TypeScript API Reference
Required Configuration
All TypeScript snippets on this page use an API key that is validated at application startup:
Imports
JoyTokenClient
Model calls, model metadata and pricing require apiKey. If it is missing, the SDK throws a clear error before sending a request. models.list() is the only unauthenticated catalog method.
One JoyTokenClient exposes Chat Completions, Responses, and Anthropic-compatible Messages methods without a global protocol switch. Chat and Responses use the Gateway’s native OpenAI endpoints. Messages are converted locally and sent through Chat Completions.
Compatible API Methods
OpenAI
Anthropic
Configure openAIBaseUrl with JOY_TOKEN_OPENAI_BASE_URL.
chat.completions.create
Calls POST /openai/v1/chat/completions and returns a non-streaming Chat Completions response.
chat.completions.stream
Calls the same endpoint and reads SSE chunks.
responses.create
Calls POST /openai/v1/responses and returns a non-streaming Responses result. input accepts a string or message input items.
responses.stream
Reads Responses SSE events including response.output_text.delta and response.completed.
images.generate
Calls POST /openai/v1/images/generations. model and prompt are required. Image generation is non-streaming: images.generate resolves once with the complete JSON response; it does not return an AsyncIterable or SSE events. Do not pass stream: true. The response contains generated images in data and JoyToken routing and billing details in metadata when available.
images.edit
Calls POST /openai/v1/images/edits. prompt and image are required; model must be "auto". image accepts a single http(s) URL or base64 data URI, or an array of them to edit multiple images. Image editing is non-streaming: images.edit resolves once with the complete JSON response; it does not return an AsyncIterable or SSE events. Do not pass stream: true. Output defaults to b64_json; set response_format: "url" only when you need a hosted URL. The response contains edited images in data and JoyToken routing and billing details in metadata when available.
Tools
Client tool options
Tool execution methods
Primitive create and stream methods never execute request-level or Client-registered tools. create() may auto-run SDK defaults only when no user tool source exists.
chat.completions
responses
Responses methods send native flat tool declarations and preserve native output items and SSE events.
Response.output_text joins all output_text content. Tool loops append function_call_output input items. Hosted tools preserve their native Responses shape.
messages
Messages methods expose Anthropic-compatible inputs, outputs, tool_use blocks, and streaming events while sending Gateway requests through Chat Completions.
Anthropic tool_choice maps as follows:
Tool types and helpers
defineTool() returns the supplied tool unchanged and preserves generic types. A Tool has a name, optional description and JSON Schema parameters, plus an optional execute(input, context) handler.
ToolCall.extra_content?: Record<string, unknown> stores opaque provider extensions. The SDK preserves this field through non-streaming and streaming Chat continuations, Responses function_call items, Messages tool_use blocks, and tool handler context. Gemini thought_signature is one example; the type and forwarding behavior are provider-neutral.
When implementing a tool loop manually, reuse the complete returned ToolCall, Responses function_call, or Messages tool_use item. Do not reconstruct it from only id, name, and arguments.
An explicit runner without a matching registered handler returns a structured tool_handler_not_found tool result. It never falls back to a same-name SDK default implementation.
Tool precedence
Hosted Responses file_search requires a non-empty vector_store_ids; the SDK never creates IDs. Local function file_search uses { type: "function", name: "file_search", ... } and is a different tool.
models.list
Calls the unauthenticated GET /api/v1/models endpoint. Use { locale: "zh" } for Chinese descriptions. Omitting locale uses the API default of English. The SDK preserves the HTTP envelope, so catalog entries are in models.data.models.
models.meta
Calls GET /api/v1/models/meta with the configured API key and returns tiers, SKUs, capability tags, industry packs, providers, and the catalog update time.
pricing.retrieve
Calls GET /api/v1/pricing with the configured API key and returns customer-facing tier exchange pricing metadata.
Orchestration
When the gateway plans and runs multiple sub-tasks for a model: "auto" turn, the SDK aggregates the result instead of exposing a raw JSON payload.
Non-streaming create() still returns the final answer text in choices[0].message.content; the breakdown lives on orchestration. Streaming chunks include intermediate sub-task text, so filter on chunk.orchestration?.task_id === ORCHESTRATION_FINAL_TASK_ID to render only the reply, or use runStream whose onTextDelta already emits only final-answer text.
JoyTokenAPIError
A failed orchestration run can arrive as an HTTP 200 response whose body or SSE stream carries an error envelope ({ "error": { ... }, "choices": [] }). The SDK detects this envelope on both non-streaming and streaming Chat paths and raises the same JoyTokenAPIError, with the gateway error object exposed on body.
