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

@volter/twin-fireworks

v0.1.37

Published

Local Fireworks AI twin — OpenAI-compatible inference + Anthropic-compatible messages + the stateful Gateway control plane, envelope-faithful with labeled deterministic stubs. Built on @volter/twin.

Readme

@volter/twin-fireworks

A local, faithful Fireworks AI twin your real fireworks Python client or @ai-sdk/fireworks provider talks to unmodified — point the client at the twin's host and chat completions (OpenAI-compatible + streaming), the legacy completions endpoint, the Responses API, the Anthropic-compatible /v1/messages, embeddings, rerank, and the stateful Gateway control plane (deployments, datasets, batch-inference and supervised-fine-tuning jobs, users/apiKeys, secrets, models) all work. Built on the shared @volter/world-core kernel; see the model for storage and branching; no parallel side store.

import { createFireworks } from '@ai-sdk/fireworks';
import { createFireworksTwinServer } from '@volter/twin-fireworks';

const { port } = createFireworksTwinServer({});
// The provider's default baseURL is https://api.fireworks.ai/inference/v1 and it appends
// /chat/completions to it — the twin serves that same prefix, so "swap the host" is the
// whole configuration.
const fireworks = createFireworks({ apiKey: 'fw_twin', baseURL: `http://127.0.0.1:${port}/inference/v1` });
const result = await generateText({ model: fireworks('accounts/fireworks/models/kimi-k2-instruct'), prompt: 'hello' });
// result.text starts with "[twin-stub:…]" — a deterministic stub, clearly labeled.

Fireworks serves two API planes on one host (api.fireworks.ai), and the twin serves both at their real wire prefixes:

| plane | prefix | surface | |---|---|---| | inference | /inference/v1/… | chat/completions, completions, responses, embeddings, rerank, and the Anthropic-compatible messages | | control | /v1/accounts/{account_id}/… | deployments, datasets, batch-inference jobs, supervised fine-tuning jobs, users, apiKeys, secrets, models |

The merged spec some clients are generated from publishes the inference operations at /v1/… with servers: https://api.fireworks.ai/inference — same operations, different spelling. The twin serves the real wire prefix; a request to the bare /v1/chat/completions 404s, because the real vendor does not serve it either — a twin that answered there would let a mis-configured client "work" locally and then fail against the real vendor.

Fireworks is not OpenAI — the differences this twin models

The inference plane is OpenAI-compatible, and treating "compatible" as "identical" is how a Fireworks twin gets built wrong. The load-bearing differences, grounded in Fireworks' own published specs (see specSource in src/index.ts) and docs, read 2026-09-16:

| | Fireworks | OpenAI | |---|---|---| | base path | https://api.fireworks.ai/inference/v1/… | https://api.openai.com/v1/… | | validation errors | the FastAPI envelope: 422 with { detail: [{ loc, msg, type }] } | { error: { message, type, param, code } } with 400 | | streaming usage | in the final chunk's usage, by default (opt out with stream_options.include_usage: false) | opt-IN via stream_options.include_usage | | service_tier | priority-only (plus auto); flex/performance are not Fireworks tiers | a different set | | context overflow | modeled as a request field: context_length_exceeded_behavior (truncate_left / middle_truncate / error) | not a request field | | reasoning models | expose reasoning_content on the message | reasoning content blocks | | max_tokens / max_completion_tokens | cannot both be set — 400 naming the alias | both accepted | | error envelope (inference) | { error: { message, … } } (OpenAI shape) / Anthropic shape on /v1/messages | { error: { message, type, param, code } } | | error envelope (control) | google.rpc style: { code: <gatewayCode>, message } | OpenAI shape | | control-plane writes | ids passed via query params (POST …/deployments?deploymentId=x), custom methods as verb suffixes (:cancel, :scale, :undelete, apiKeys:delete) | ids in the body; verbs as separate resources | | list envelopes | { items, nextPageToken, totalSize } + pageToken pagination | { data, has_more } | | deletes | answer {} (empty object), not a deleted: true echo | { id, deleted } |

The generative-stub design (be honest)

The twin cannot run the model — there are no weights here. So POST /inference/v1/chat/completions returns a deterministic STUB completion that is unmistakably a twin stub (it carries a [twin-stub:<model>] marker and echoes your prompt), POST /inference/v1/embeddings returns deterministic pseudo-vectors (L2-normalized, seeded from the input hash), and rerank returns deterministic overlap-biased scores. They never pretend to be real model output.

What is faithful is the entire protocol envelope:

  • chat response shape — { id:'chatcmpl-…', object:'chat.completion', created, model, choices:[{index, message:{role:'assistant', content, reasoning_content?}, logprobs, finish_reason}], usage }
  • streaming via SSE — real data: {…chat.completion.chunk with choices[].delta…} chunks ending with data: [DONE] (role chunk → reasoning/content deltas → the finish chunk carrying usage by default; driven through an injected sink — no real sockets in the handler). The legacy completions stream uses the legacy chunk shape throughout (object: 'text_completion', delta in choices[].text, same final-chunk usage default). The Anthropic-compatible /v1/messages streams its OWN event sequence (message_start → content_block_delta → message_delta with the real token counts → message_stop) and no [DONE] sentinel
  • the Responses API — create (with store: false → id: null), retrieve, list ({ data, has_more }), delete
  • the Anthropic-compatible messages — the Anthropic envelope, max_tokens optional (Fireworks' difference from Anthropic), stop_reason, system as blocks, the Anthropic error shape on both planes' 401
  • max_tokens / max_completion_tokens (mutually exclusive), stop (earliest hit), response_format json_object, reasoning_effort → reasoning_content, context_length_exceeded_behavior, service_tier (auto/priority only); deterministic usage
  • Embeddings — { object:'list', data:[{object:'embedding', index, embedding}], model, usage }, dimensions parameter, encoding_format float/base64
  • Rerank — query-responsive ordering (shared-token overlap), top_n, return_documents

The genuinely stateful + static surface is real, not a stub:

  • Deployments — create (id via query param), get, list (paginated), delete ({}), undelete (:undelete), scale (both the :scale POST spelling and the spec's PATCH spelling), read-only-field PATCH tolerated, duplicate-create 409, baseModel required
  • Datasets — create (body-carried id), lifecycle
  • Batch-inference jobs — create (dataset reference validated — the dataset must really exist, 400 otherwise), cancel (:cancel), cancel-in-wrong-state refused
  • Supervised fine-tuning jobs — create over a dataset that must really exist (400 otherwise)
  • Users & apiKeys — role validation, key returned exactly once (create response only — the LIST answers it never), delete via the collection-level apiKeys:delete body spelling, cross-user key access refused through both the id-segment and collection-level spellings
  • Secrets — value never on read, name/keyName required
  • Models — create + list

Vendor-shaped errors throughout: 400 / 401 / 404 / 405 (read-only guard) / 409 / 422 (FastAPI) / 429 (scripted) — the inference plane in its OpenAI/Anthropic envelopes, the control plane in google.rpc { code, message } with the vendor's own gatewayCode enum (NOT_FOUND, ALREADY_EXISTS, …). Mixing the planes' envelopes is a wire lie the twin never commits.

Scenario scripting (twin-only)

Chat completions can be scripted by MSW-shaped handlers in a world dir's handlers/fireworks.json, run by the ONE kernel scenario engine with this pack's adapter:

{ "handlers": [
  { "on": { "userTextIncludes": "refund" },
    "respond": { "text": "Refund queued." }, "once": true },
  { "on": { "modelEndsWith": "kimi-k2-instruct" }, "respond": { "error": { "type": "rate_limit_exceeded" } } }
] }

Load it with --scenario FILE / createFireworksTwinServer({ scenarioPath }) / TWIN_FIREWORKS_SCENARIO. The read doors GET /twin and GET /twin/scenario explain and inspect it. A malformed file throws at load, never a silent fall-back. Scenario support is twin-only scaffolding for eval worlds, not vendor surface, so it is deliberately not in the capability manifest.

CLI

world-fireworks serve       [--port N] [--root DIR] [--read-only] [--scenario FILE]
world-fireworks conformance [--root DIR]

Connector (pull / push)

pullFireworksState folds the real control plane (deployments, datasets, both job families, users, apiKeys, secrets, models) into the twin — each collection paginated to exhaustion, so the kernel's tombstone sweep marks subjects that vanished remotely as deleted: true locally; pushFireworksAction / pushPendingFireworksActions push pending local writes (create / delete / scale / undelete) to the real API and confirm them by the vendor's _external_id; fullSyncFireworks and syncFireworksFromRemote are the protocol-2 refresh entry points. All vendor I/O is over an injected executor (liveFireworksExecute(apiKey) live; a fake in tests) — the pack holds no key and imports no SDK at runtime. Every live call is charged against the shared kernel RateBudget before it goes out, and the executor refuses any path outside /inference/v1/ and /v1/accounts/. Fireworks publishes no scalar request limit and no header a cooldown could arm on, so the declaration is pinned at the kernel fallback and buys resolution downward (inference endpoints cost 6 → at most 10 per window); see fireworks-budget.ts for the full reasoning.

Coverage

The capability manifest (fireworks-capabilities.ts) enumerates the real Fireworks API surface as the honest denominator, enumerated top-down from the five first-party OpenAPI specs (see specSource) plus docs.fireworks.ai (read 2026-09-16); verify() proves each done against the local twin, offline + deterministically. Run bun scripts/twin-capabilities.ts fireworks for the live numbers.

Coverage is partial and honest: the served protocol envelopes are enumerated and proven, but whole product areas are modeled only as gaps — the serverless model catalog and its rate limits, account quotas, the dataset-upload extra, the fine-tuning lifecycle (create→READY with training progression), per-request response ids, per-request chat completions inside batch outputs (the batch OUTPUT surface is unmodeled entirely — jobs stay in their early state), and the image generation surface the @ai-sdk/fireworks provider reaches (/image_generation/{model} legacy and the async workflows pair) are all todo.

Done (proven, verifiable)

  • Chat Completions — create + faithful envelope, the labeled stub, FastAPI 422 validation, the max_tokens/max_completion_tokens mutual exclusion, service_tier priority-only, context_length_exceeded_behavior, stop, max_tokens length finish, reasoning_content, json_object response format
  • Streaming — the chunk sequence, usage on the final chunk by default (the Fireworks difference) with include_usage: false opting out, the pre-stream refusal answering a real status (never a 200 event stream)
  • Legacy completions — create, prompt arrays, streaming in the legacy chunk shape (usage on the final chunk by default, include_usage: false opting out)
  • Responses API — create + retrieve, store: false → id: null, delete, the list envelope
  • Anthropic-compatible messages — the Anthropic envelope, max_tokens optional, stop_reason, the Anthropic error envelope, streaming, system as blocks (priced into input_tokens, echoed when the user content is whitespace)
  • Embeddings — create, L2-normalized vectors, dimensions, array input
  • Rerank — create, query-responsive ordering, top_n + return_documents
  • Auth — missing key, invalid key, any non-empty key accepted, the Anthropic plane gated with its OWN error envelope
  • Errors — unknown-path 404, the scripted 429
  • Deployments — create (query-param id), get, list, pagination, delete ({}), delete-then-404, read-only-field PATCH, undelete, scale (both spellings), duplicate 409, baseModel required
  • Datasets / Batch jobs / SFT / Users / apiKeys / Secrets / Models — as listed above
  • Connector — control-plane pull, refusal-is-not-emptiness, pull idempotency, push create with query params, push delete by the vendor's _external_id, inference ops never pushed, request shapes, full sync, the live client's unmodeled-path refusal
  • Conformance — one real probe per claimed endpoint plus the hand-authored router census

No UI mirror

The API is the product. When someone does Fireworks' core job they write code against the inference API or the Gateway control plane; the Fireworks console is incidental tooling for API keys, usage dashboards and deployments — not where the work happens. Per the contributor recipe's "Does this vendor get a mirror?" rule (and ../../../docs/contributing/architecture.md C1b), this pack therefore ships no mirror and no UI capabilities; coverage is API + connector. This matches the sibling generative packs (openai, anthropic, gemini, groq).