npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

panofy

v0.6.0

Published

TypeScript SDK for Panofy Agent Platform

Readme

Panofy TypeScript SDK

TypeScript SDK for Panofy Agent Platform.

Installation

npm install panofy

Quick Start

import { Panofy } from 'panofy';

const panofy = new Panofy({
  agentId: 'your-agent-id',
  apiKey: 'da_your_api_key',
});

// One-line function call. Synchronous; awaits the full agent run.
const result = await panofy.predict({ input: 'data' });
console.log(result);

// Inspect token usage and point cost from the last predict run.
console.log(panofy.lastUsage());      // cache_read, cache_write, output_token
console.log(panofy.lastPointUsage()); // points_consumed

// String values that point to existing local files are uploaded
// automatically and rewritten to task-visible filenames in FUNC_INPUT.json.
const report = await panofy.predict({
  claim_application_file: './Claims_application-C2104.json',
});

// If FUNC_OUTPUT.json references files, they are downloaded to
// `panofy_outputs/<taskId>/` by default. Override or disable via options:
const rawReport = await panofy.predict(
  { claim_application_file: './Claims_application-C2104.json' },
  { outputDir: null },
);

// Bound the wait time and abort the task server-side on timeout:
const bounded = await panofy.predict(
  { input: 'data' },
  { timeout: 600_000 },  // milliseconds
);

API Reference

new Panofy({ agentId, apiKey, baseUrl?, timeout? })

Main SDK client. baseUrl defaults to https://panofy.ai; override it only for local development or a custom/private deployment.

Predict

  • predict(inputData, options?: PredictOptions) — Function-call replacement. Serialises input, creates a task, uploads FUNC_INPUT.json plus any string parameters that point to existing local files, then drives the BFF's plan→execute pipeline via /api/sdk/predict-async and short-polls /api/sdk/runs/{runId} until the SDK run reaches a terminal status. Long agent runs are supported (no Fastly 15-minute edge cap). On COMPLETED, fetches and returns the parsed FUNC_OUTPUT.json; on any failure terminal raises a PanofyError whose taskId is set so you can recover via panofy.tasks.get(taskId) / panofy.download(taskId). After a terminal run, panofy.lastUsage() returns the latest token usage as cache_read, cache_write, and output_token when returned by the API; panofy.lastPointUsage() returns points_consumed. Use predictWithMetadata(input, options?) when you want the parsed output and run metadata (run_id, task_id, points, and usage) in one return value.

    const { output, run } = await panofy.predictWithMetadata({ input: 'data' });
    console.log(output);
    console.log(run.run_id, run.points_consumed, run.usage);
    interface PredictOptions {
      /**
       * Output file directory. Files referenced by FUNC_OUTPUT.json paths land
       * under `<outputDir>/<taskId>/<basename>`. Default: "panofy_outputs".
       * Pass null to disable the output-side download.
       */
      outputDir?: string | null;
      /**
       * Default true. Set false to skip both input-side heuristic file
       * uploading and output-side path rewriting (strings stay strings).
       */
      resolveFiles?: boolean;
      /**
       * Maximum wall-clock milliseconds. On timeout the SDK calls
       * DELETE /api/sdk/tasks/{taskId} to abort the run server-side before
       * throwing PanofyError.
       */
      timeout?: number;
    }

Tasks & files

  • tasks.list(filters?) — List tasks (with optional filters).
  • tasks.get(taskId) — Get a single task with messages.
  • tasks.delete(taskId) — Soft-delete a task.
  • uploadFile(taskId, filePath) — Upload one file via signed URL + GCS PUT.
  • uploadFiles(taskId, filePaths) — Batch sign + parallel PUTs.
  • download(taskId, outputDir?) — Download all output files of a task.

One-shot train & agents

Panofy is scoped to an existing agent and does not expose train(). To create a new agent, upload training materials, start /api/sdk/train, and wait for completion, use the module-level helper:

import { train } from 'panofy';

const { agentId, taskId } = await train({
  apiKey: 'da_your_api_key',
  name: 'rewrite title agent',
  modelId: 'PANOFY_AIR',
  instruction: 'train a rewrite_title(input) function',
  trainingData: [
    './function_definition.md',
    './FUNC_INPUT.json',
    './FUNC_OUTPUT.json',
  ],
});
  • agents.list({ type?: 'CHAT' | 'WORKFLOW' }) / agents.get(id) / agents.create(input) / agents.update(id, patch) / agents.delete(id). Agent names are display labels and may repeat; use id, type, model_id, and timestamps to disambiguate same-name agents.

Authentication

All SDK routes are under /api/sdk/* and use the X-Api-Key header (the SDK sends this automatically once you construct a Panofy instance with an apiKey).

Error Handling

import { PanofyError, AuthenticationError, NotFoundError } from 'panofy';

try {
  const result = await panofy.predict({ n: 3 });
} catch (e) {
  if (e instanceof AuthenticationError) {
    console.log('Invalid API key');
  } else if (e instanceof NotFoundError) {
    console.log('Agent not found');
  } else if (e instanceof PanofyError) {
    console.log(`Error: ${e.message} (task=${e.taskId})`);
  }
}

Migrating from 0.1.x

The single predict() entry point replaces the previous predictRaw / predictAsync / createTask trio. Plans are auto-confirmed by the BFF — no onPlan callback, no PlanRejectedError. See the root CHANGELOG.md for the full breaking-change list and migration table.