TypeScript SDK
The zero-dependency TypeScript instrumentation SDK — install, the exported API, callback scopes, the drop-in fetch, the async ledger pull, and runnable examples.
On this page
The TypeScript SDK is the idiomatic-TS binding of the same contract as
Python: zero runtime dependencies, dual ESM+CJS, edge-safe core. It
emits x-tt-* headers and reads back typed receipts — it forwards and reads; it never
computes.
Install
npm install tokentriage
import * as tt from "tokentriage";
// or named:
import { init, trace, step, headers, receipt, fetch, wrapFetch, lastReceipt, ledger, check } from "tokentriage";
Subpaths: tokentriage (the frozen root), tokentriage/adapters/otel, and
tokentriage/management (the generated admin-API client).
Configure
tt.init({
baseUrl: "https://tt.example.com", // env: TOKENTRIAGE_BASE_URL
adminUrl: "http://127.0.0.1:9090", // env: TOKENTRIAGE_ADMIN_URL
log: "warn", // "debug" | "warn" | "off"
agent: "my-service",
});
init(options?) is the one entry that throws (TokenTriageConfigError). The env vars match
Python’s (TOKENTRIAGE_BASE_URL, TOKENTRIAGE_ADMIN_URL, TOKENTRIAGE_DISABLED,
TOKENTRIAGE_LOG, TOKENTRIAGE_ADMIN_TOKEN).
The exported API
- Context (callback-scoped):
trace<T>(options, fn)/trace<T>(fn)andstep<T>(...)run their callback inside oneAsyncLocalStorageframe.currentStep()returnsStep | null. (There is no decorator form and noobserve— that’s a Python-only convenience.) - Wire:
headers(overrides?)returns thex-tt-*record;receipt(source, status?)parses aResponse,Headers, or header record into aReceipt;lastReceipt()returns the most recent. - Transport:
fetchis a drop-in forglobalThis.fetchthat injectsheaders(), opens an implicit per-request step, and pairs the receipt;wrapFetch(base?, options?)builds an origin-scoped wrapper. - Ledger & doctor (all async):
ledger.fetch(receiptOrReqId, { adminUrl?, waitS? }),ledger.fetchTrace(...),ledger.feedback(receiptOrReqId, { ok, note?, adminUrl? });check({ adminUrl?, probe? }). - Also exported:
registerExporter,DebugExporter,renderCost,version,TokenTriageConfigError, and the full type set (Mode,StepClass,Cost,Receipt,InitOptions,TraceOptions,StepOptions, …).
Examples
Drop-in fetch behind the OpenAI SDK, honest cost from the ledger:
import * as tt from "tokentriage";
import OpenAI from "openai";
tt.init({ baseUrl: "https://tt.example.com", adminUrl: "http://127.0.0.1:9090" });
const client = new OpenAI({ baseURL: "https://tt.example.com/v1", fetch: tt.fetch });
await tt.trace({ agent: "planner" }, async () => {
await tt.step({ agent: "coder", stepClass: "tool_loop" }, async () => {
await client.chat.completions.create({ model: "gpt-4o", messages: [] });
const rcpt = tt.lastReceipt();
if (rcpt) {
const row = await tt.ledger.fetch(rcpt); // async in TS
if (row.cost?.state === "priced") console.log(row.cost.usd); // string
}
});
});
Library-agnostic headers() path (any client, no adapter):
import { init, trace, headers, receipt } from "tokentriage";
init({ baseUrl: "https://tt.example.com" });
await trace({ agent: "planner", tags: { env: "prod" } }, async () => {
const r = await fetch("https://tt.example.com/v1/messages", { headers: headers() });
const rcpt = receipt(r);
console.log(rcpt.requestId, rcpt.mode, rcpt.costDisplay);
});
Doctor + feedback + the OTel bridge:
import { check, ledger, lastReceipt } from "tokentriage";
import { bridge } from "tokentriage/adapters/otel"; // importing the subpath is the opt-in
const report = await check({ adminUrl: "http://127.0.0.1:9090" });
const dispose = bridge(); // x-tt-* now adopt the active OTel span ids
try {
const ack = await ledger.feedback(lastReceipt()!, { ok: false, note: "bad" }); // rejects on failure
console.log(ack.accepted, ack.verdict, ack.source);
} finally {
dispose();
}
Parity with Python
| Aspect | Python | TypeScript |
|---|---|---|
| install / import | pip install tokentriage / import tokentriage as tt |
npm install tokentriage / import * as tt from "tokentriage" |
| scope form | context manager and decorator (with, @observe) |
callback only (trace(opts, fn)) |
ledger / check |
synchronous | async (Promise) |
| built-in transport adapters | httpx, requests, LangChain, CrewAI, OTel | fetch/wrapFetch + OTel |
Cost.usd |
Decimal | None |
decimal string, after narrowing to priced |
| naming | snake_case (fetch_trace, last_receipt) |
camelCase (fetchTrace, lastReceipt) |
feedback on failure |
raises | rejects |
Both bindings are verified against the same byte-equality conformance corpus.