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

@polimorfapp/sdk

v0.1.1

Published

Official TypeScript SDK for the Polimorf AI application platform — run and stream assistants over the public runtime API.

Readme

@polimorfapp/sdk

The official TypeScript client for the Polimorf AI Application Platform — the "integrate once" seam. This package currently provides the base client: an authenticated, JSON HTTP transport with timeouts, cancellation, and typed error handling, plus the runtime surface (runtime.execute, runtime.stream).

Quick start

npm install @polimorfapp/sdk
import { createClient } from '@polimorfapp/sdk';

// The client talks to the managed Polimorf API (https://api.polimorf.app);
// all you provide is your API key.
const client = createClient({ apiKey: process.env.POLIMORF_API_KEY });

const result = await client.assistant('support').run({
  input: 'How do I cancel my subscription?',
});
console.log(result.message.content);

Get an API key (csk_live_…) from your Polimorf dashboard. It can be passed as apiKey or read from the POLIMORF_API_KEY environment variable.

Usage

import { createClient } from '@polimorfapp/sdk';

// apiKey passed explicitly…
const client = createClient({ apiKey: 'csk_live_…' });

// …or read from POLIMORF_API_KEY in the environment:
const client2 = createClient();

// Every request is sent with `Authorization: Bearer <apiKey>` and
// `Accept: application/json`.
const assistant = await client.request<{ id: string; name: string }>({
  method: 'GET',
  path: '/assistants/asst_123',
});

Options

createClient({
  apiKey, // required — `csk_live_…` key; falls back to POLIMORF_API_KEY
  baseUrl, // optional — override the API host (defaults to https://api.polimorf.app)
  timeoutMs, // optional — per-request timeout (default 30000)
  fetch, // optional — inject a `fetch` implementation (tests/proxies)
  defaultHeaders, // optional — headers sent on every request
});

apiKey is required (passed explicitly or read from POLIMORF_API_KEY); createClient throws a clear error when it is missing. baseUrl defaults to the managed host https://api.polimorf.app and rarely needs changing — override it (or set POLIMORF_BASE_URL) only to target a different environment; an explicit option always wins over the env var.

fetch defaults to globalThis.fetch (Node ≥20). Inject your own for tests, proxies, or custom transport wrappers.

Making requests

client.request<T>({
  method, // 'GET' | 'POST' | ...
  path, // resolved against baseUrl; leading slash optional
  body, // optional — JSON-serialized, sent as application/json
  query, // optional — object → query string (undefined values omitted)
  headers, // optional — per-request headers (override defaultHeaders; the
  //          SDK-owned Authorization/Accept/Content-Type always win)
  signal, // optional — AbortSignal, composed with the client timeout
});
  • A 2xx response resolves to the parsed JSON body typed as T.
  • A 204/empty response resolves to undefined.

Running an assistant (non-streaming)

client.runtime.execute runs one generation and resolves with the full result:

const result = await client.runtime.execute({
  providerName: 'openai',
  model: 'gpt-4o',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'How do I cancel my subscription?' },
  ],
  config: { temperature: 0.2, maxOutputTokens: 512 }, // optional
});

result.message; // { role: 'assistant', content: '…' }
result.finishReason; // 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'error'
result.usage; // { inputTokens, outputTokens, totalTokens }

Pass an AbortSignal to cancel in flight:

await client.runtime.execute(request, { signal: controller.signal });

This maps to POST /runtime/execute and sends the raw model-execution contract (provider, model, messages, config).

Running a deployed assistant by slug

client.assistant(slug).run runs a published, deployed assistant by its slug — the provider/model/prompt come from the deployed version's frozen snapshot, so your application sends only the input and needs no redeploy when a product team publishes a new version (PRD §5.10):

const result = await client.assistant('support').run({
  input: 'How do I cancel my subscription?',
  variables: { plan: 'pro' }, // optional — the version's declared variables
  environment: 'production', // optional — defaults to 'production'
});

result.message; // { role: 'assistant', content: '…' }
result.usage; // { inputTokens, outputTokens, totalTokens }

This maps to POST /runtime/assistants/:slug. An unknown slug, unknown environment, or an assistant never deployed there all throw a NotFoundError (404 DEPLOYMENT_NOT_FOUND). Pass an AbortSignal to cancel in flight, exactly as with runtime.execute.

client.assistant(slug).stream is the streaming counterpart — it yields events as the deployed model produces them (over POST /runtime/assistants/:slug/stream):

for await (const event of client.assistant('support').stream({ input: 'hi' })) {
  if (event.type === 'delta') process.stdout.write(event.content);
  else if (event.type === 'done') console.log('\n', event.finishReason);
}

A pre-stream failure (e.g. 404 for an undeployed slug) throws before the loop starts; the terminal provider error is delivered as an event, not a throw.

Running an assistant (streaming)

client.runtime.stream runs one generation and yields events as the model produces them. It returns an AsyncIterable — consume it with for await:

for await (const event of client.runtime.stream({
  providerName: 'openai',
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Write a haiku about the sea.' }],
})) {
  switch (event.type) {
    case 'delta':
      process.stdout.write(event.content); // incremental text
      break;
    case 'usage':
      event.usage; // { inputTokens, outputTokens, totalTokens }
      break;
    case 'done':
      event.finishReason; // 'stop' | 'length' | ...
      break;
    case 'error':
      // Terminal provider error — delivered as an event, not thrown.
      event.error; // { code, message, retryable, providerName? }
      break;
  }
}

This maps to POST /runtime/stream (Server-Sent Events). A terminal provider error arrives as an error event (mirroring the wire contract), not a thrown exception; only a transport failure (network, connect timeout, aborted request) or a non-2xx response opening the stream throws (PolimorfError / PolimorfApiError). The client timeoutMs bounds only the wait to open the stream — it never truncates a live stream. Pass an AbortSignal to cancel in flight:

const controller = new AbortController();
const stream = client.runtime.stream(request, { signal: controller.signal });
// …later: controller.abort();

Errors

Every error the SDK throws extends PolimorfError. A non-2xx response throws a PolimorfApiError — thrown as the status-mapped subclass so you can branch on the error type with narrowing:

| HTTP status | Class | | ----------- | ----------------------- | | 400 | BadRequestError | | 401 | AuthenticationError | | 403 | PermissionDeniedError | | 404 | NotFoundError | | 409 | ConflictError | | 429 | RateLimitError | | ≥ 500 | ServerError | | other | PolimorfApiError |

import {
  PolimorfApiError,
  PolimorfError,
  NotFoundError,
  RateLimitError,
} from '@polimorfapp/sdk';

try {
  await client.request({ method: 'GET', path: '/assistants/missing' });
} catch (error) {
  if (error instanceof RateLimitError) {
    // 429 — back off and retry later
  } else if (error instanceof NotFoundError) {
    // 404 — the resource does not exist
  } else if (error instanceof PolimorfApiError) {
    // any other non-2xx response
    error.status; // e.g. 409
    error.code; // stable machine code, e.g. 'ASSISTANT_SLUG_CONFLICT' — autocompleted
    error.message; // human-readable, may change across versions
    error.fields; // [{ field, issue }] — only on VALIDATION_ERROR
  } else if (error instanceof PolimorfError) {
    // transport failure: network error, timeout, or aborted request
    error.cause;
  }
}

Every subclass is still instanceof PolimorfApiError (and PolimorfError), so a catch on a base class keeps matching. error.code is typed against the platform's public error catalog (ErrorCode, exported) with a string fallback, so known codes autocomplete while a newly published code still type-checks.