@gullabs/xai 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/adapter.ts","../src/file-store.ts","../src/model-config/grok-4-5.ts","../src/models.ts","../src/pricing.ts","../src/provider.ts"],"names":["LlmError","isPlainRecord","classifyError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Structural XaiClientLike interface + buildXaiClient factory.\n *\n * This module defines the structural interface the adapter depends on.\n * The real `openai` SDK is imported ONLY in buildXaiClient so tests can\n * inject a fake without pulling in the real SDK. This is the ONLY file in\n * `packages/xai/src` that imports `openai`.\n *\n * @module\n */\n\nimport { LlmError } from '@gullabs/core'\nimport type { AuthMaterial } from '@gullabs/core'\n\n// ---------------------------------------------------------------------------\n// Auth narrowing — xAI only accepts ApiKeyAuth\n// ---------------------------------------------------------------------------\n\n/**\n * Narrows {@link AuthMaterial} to its `apiKey` string, rejecting the\n * dev-only `CliSessionAuth` variant.\n *\n * xAI is a production API provider and only ever accepts API-key\n * credentials; `{ cliSession: true }` is reserved for the dev-only CLI\n * provider packages (`@gullabs/claude-cli`, `@gullabs/codex-cli`).\n */\nexport function requireApiKey(auth: AuthMaterial): string {\n if (\n !('apiKey' in auth) ||\n typeof auth.apiKey !== 'string' ||\n auth.apiKey.trim() === ''\n ) {\n throw new LlmError('@gullabs/xai requires auth.apiKey', {\n kind: 'invalid_auth',\n retryable: false,\n provider: 'xai',\n })\n }\n return auth.apiKey\n}\n\n// ---------------------------------------------------------------------------\n// Request shape — what the (future) adapter sends to responses.create\n// ---------------------------------------------------------------------------\n\n/** A text content item within an xAI Responses API input message. */\nexport interface XaiInputTextPart {\n type: 'input_text'\n text: string\n}\n\n/**\n * An image content item within an xAI Responses API input message.\n * `image_url` may be a data URL (`data:image/png;base64,...`) or a public URL.\n */\nexport interface XaiInputImagePart {\n type: 'input_image'\n image_url: string\n}\n\n/**\n * A file attachment content item within an xAI Responses API input message.\n * Prefer `file_id` for private uploads (via {@link XaiFileStore}); `file_url`\n * is for publicly reachable documents. Attaching either implicitly enables\n * xAI's `attachment_search` agentic tool.\n */\nexport interface XaiInputFilePart {\n type: 'input_file'\n file_id?: string\n file_url?: string\n}\n\n/** Union of content-part shapes an input message may carry. */\nexport type XaiInputContentPart = XaiInputTextPart | XaiInputImagePart | XaiInputFilePart\n\n/** A single role+content input item constructed by the (future) adapter. */\nexport interface XaiInputItem {\n role: 'user' | 'assistant' | 'system' | 'developer'\n content: XaiInputContentPart[]\n}\n\n/**\n * Structured-output text-format request shape.\n * Real xAI field: `text.format`, NOT `response_format`.\n * `name` and `strict` are included per xAI's Structured Outputs docs\n * conventions even though the live fixture's request-echo does not surface\n * them (only the schema is echoed back).\n */\nexport type XaiTextFormat =\n | { type: 'json_schema'; name: string; schema: unknown; strict: boolean }\n | { type: 'text' }\n\n/**\n * Parameters for `client.responses.create`.\n * Structurally modeled from live-captured xAI Responses API fixtures\n * (see docs/provider-plugins-and-xai-grok-4-5-plan.md §3.1), not from the\n * `openai` npm package's TS types — xAI's actual endpoint shape differs.\n */\nexport interface XaiResponseCreateParams {\n model: string\n input: XaiInputItem[]\n instructions?: string\n reasoning?: { effort: 'low' | 'high' }\n text?: { format: XaiTextFormat }\n temperature?: number\n top_p?: number\n max_output_tokens?: number\n prompt_cache_key?: string\n /** Always `false` — this library never relies on xAI-side conversation storage. */\n store: false\n}\n\n// ---------------------------------------------------------------------------\n// Response shape — mirrors the xAI Responses API surface we actually consume\n// ---------------------------------------------------------------------------\n\n/** A single summary-text segment of a `type: 'reasoning'` output item. */\nexport interface XaiReasoningSummaryPart {\n type: 'summary_text'\n text: string\n}\n\n/** A `type: 'reasoning'` item in `output`. */\nexport interface XaiReasoningOutputItem {\n type: 'reasoning'\n id?: string\n summary: XaiReasoningSummaryPart[]\n status?: string\n}\n\n/** A single text content segment of a `type: 'message'` output item. */\nexport interface XaiOutputTextPart {\n type: 'output_text'\n text: string\n logprobs?: unknown[]\n annotations?: unknown[]\n}\n\n/** A `type: 'message'` item in `output`. */\nexport interface XaiMessageOutputItem {\n type: 'message'\n id?: string\n role?: string\n status?: string\n content: XaiOutputTextPart[]\n}\n\n/** Union of output-item shapes the Responses API may return. */\nexport type XaiOutputItem = XaiReasoningOutputItem | XaiMessageOutputItem\n\n/**\n * Token usage metadata returned alongside an xAI response.\n *\n * Kept loose/open: the known fields are typed, but xAI has been observed to\n * add additional numeric fields (e.g. `num_sources_used`,\n * `cost_in_usd_ticks`, `context_details`) that must not break this type.\n */\nexport interface XaiUsageShape {\n input_tokens: number\n input_tokens_details?: { cached_tokens?: number }\n output_tokens: number\n output_tokens_details?: { reasoning_tokens?: number }\n total_tokens?: number\n /** Additional provider-specific usage fields, passed through raw. */\n [otherKeys: string]: unknown\n}\n\n/**\n * Structural equivalent of the xAI Responses API response body.\n * Only the fields the (future) adapter reads are represented here.\n */\nexport interface XaiResponseShape {\n id: string\n model: string\n /**\n * Real field: `status`. Observed values: \"completed\", \"incomplete\" — kept\n * as a plain `string` since xAI may add further status values over time.\n */\n status: string\n incomplete_details?: { reason?: string } | null\n output: XaiOutputItem[]\n usage: XaiUsageShape\n reasoning?: { effort?: string; summary?: string }\n store?: boolean\n prompt_cache_key?: string | null\n /**\n * Response-level metadata (e.g. `system_fingerprint`) — surfaced into\n * `AdapterResult.providerMetadata` by the adapter when present.\n */\n metadata?: { [key: string]: unknown } | null\n}\n\n// ---------------------------------------------------------------------------\n// XaiClientLike — structural interface (no `openai` dependency)\n// ---------------------------------------------------------------------------\n\n/**\n * Structural interface for the `openai` SDK's `client.responses` surface\n * the adapter uses.\n *\n * Satisfied by:\n * - The real `openai` `OpenAI` client (via `buildXaiClient` wrapper), pointed\n * at xAI's `https://api.x.ai/v1` base URL.\n * - `FakeXaiClient` from `@gullabs/testing`.\n */\nexport interface XaiClientLike {\n responses: {\n create(\n params: XaiResponseCreateParams,\n options?: { signal?: AbortSignal },\n ): Promise<XaiResponseShape>\n }\n}\n\n// ---------------------------------------------------------------------------\n// buildXaiClient — imports the real `openai` SDK\n// ---------------------------------------------------------------------------\n\n/**\n * Build a real `openai`-SDK-backed client from AuthMaterial, pointed at\n * xAI's Responses API endpoint.\n *\n * Only API-key authentication is supported.\n *\n * @param auth - API key credentials ({ apiKey }).\n */\nexport async function buildXaiClient(auth: AuthMaterial): Promise<XaiClientLike> {\n // Resolve and validate auth BEFORE importing the SDK so auth-rejection\n // tests never need to touch the real `openai` module (and thus never hit\n // the network).\n const apiKey = requireApiKey(auth)\n\n const { default: OpenAI } = await import('openai')\n\n const client = new OpenAI({\n apiKey,\n baseURL: 'https://api.x.ai/v1',\n maxRetries: 0,\n })\n\n return {\n responses: {\n async create(\n params: XaiResponseCreateParams,\n options?: { signal?: AbortSignal },\n ): Promise<XaiResponseShape> {\n // Cast needed: our structural types are subsets of the real SDK types,\n // and the real SDK's types do not exactly match xAI's actual response\n // shape (see module doc comment).\n return (\n client.responses.create as unknown as (\n p: unknown,\n o?: { signal?: AbortSignal },\n ) => Promise<XaiResponseShape>\n )(params, options)\n },\n },\n }\n}\n","/**\n * xaiAdapter — @gullabs/xai xAI Grok provider adapter.\n *\n * Pure request⇄response mapping over the xAI Responses API (via\n * XaiClientLike). Never persists, never computes cost, never loops.\n *\n * @module\n */\n\nimport { LlmError, classifyError, assertNever } from '@gullabs/core'\nimport type {\n ProviderAdapter,\n ResolvedRequest,\n AdapterCtx,\n AdapterResult,\n Usage,\n Warning,\n FinishReason,\n JsonValue,\n AuthMaterial,\n Part,\n} from '@gullabs/core'\nimport { buildXaiClient } from './client.js'\nimport type {\n XaiClientLike,\n XaiResponseCreateParams,\n XaiInputItem,\n XaiInputContentPart,\n XaiResponseShape,\n XaiUsageShape,\n XaiMessageOutputItem,\n} from './client.js'\n\n// ---------------------------------------------------------------------------\n// Small object-shape helpers (mirrors google adapter's local helpers)\n// ---------------------------------------------------------------------------\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction badXaiRequest(message: string): LlmError {\n return new LlmError(message, { kind: 'bad_request', retryable: false })\n}\n\n// ---------------------------------------------------------------------------\n// Vision / media mapping\n// ---------------------------------------------------------------------------\n\nconst ALLOWED_XAI_IMAGE_MIME_TYPES = new Set(['image/jpeg', 'image/jpg', 'image/png'])\n\n/** 20 MiB, xAI's documented inline-image size ceiling. */\nconst MAX_XAI_INLINE_IMAGE_BYTES = 20 * 1024 * 1024\n\n/**\n * Map a single {@link Part} to its xAI Responses API input-content-part\n * equivalent.\n *\n * - `text` → `{ type: 'input_text', text }`\n * - `inline-media` → `{ type: 'input_image', image_url: 'data:<mime>;base64,<data>' }`;\n * rejected (`bad_request`) when `mimeType` is not jpg/jpeg/png, or when the\n * decoded payload exceeds 20 MiB.\n * - `file-uri` → `{ type: 'input_image', image_url: uri }` ONLY when\n * `uri` is a public `http(s)://` URL AND `mimeType` is an allowed image\n * type — a provider-hosted URI from another provider (e.g. Gemini's Files\n * API `https://generativelanguage.googleapis.com/...` — which itself\n * happens to be `https://`, but is not dereferenceable by xAI) is not\n * portable and callers should not reuse `FileUriPart` cross-provider.\n * - `file-ref` → `{ type: 'input_file', file_id }` for xAI Files uploads.\n * Attaching files implicitly enables xAI's `attachment_search` agentic tool\n * (extra tool billing may apply). Empty `fileId` → `bad_request`.\n *\n * Note: xAI enforces an undocumented server-side minimum image size\n * (observed ~8px/side, ~512 total px). This adapter does not pre-validate\n * pixel dimensions — a too-small image surfaces as a `bad_request` from the\n * live API, classified normally by {@link classifyXaiError}.\n */\nfunction mapPart(p: Part): XaiInputContentPart {\n switch (p.kind) {\n case 'text':\n return { type: 'input_text', text: p.text }\n\n case 'inline-media': {\n if (!ALLOWED_XAI_IMAGE_MIME_TYPES.has(p.mimeType)) {\n throw badXaiRequest(\n `xAI vision only supports image/jpeg and image/png; got mimeType \"${p.mimeType}\".`,\n )\n }\n const byteLength = Buffer.from(p.data, 'base64').length\n if (byteLength > MAX_XAI_INLINE_IMAGE_BYTES) {\n throw badXaiRequest(\n `xAI inline images must be at most 20 MiB; got ${byteLength} bytes.`,\n )\n }\n return { type: 'input_image', image_url: `data:${p.mimeType};base64,${p.data}` }\n }\n\n case 'file-uri': {\n const isPublicHttpUrl = p.uri.startsWith('http://') || p.uri.startsWith('https://')\n const isAllowedImageType = ALLOWED_XAI_IMAGE_MIME_TYPES.has(p.mimeType)\n if (!isPublicHttpUrl || !isAllowedImageType) {\n throw badXaiRequest(\n `xAI only accepts public http(s) image URLs via FileUriPart; got scheme of \"${p.uri}\" / mimeType \"${p.mimeType}\".`,\n )\n }\n // Reject known foreign provider hosts even when scheme+mime look valid.\n if (\n p.uri.includes('generativelanguage.googleapis.com') ||\n p.uri.includes('googleapis.com/v1beta/files')\n ) {\n throw badXaiRequest(\n `xAI cannot dereference Gemini/Google Files URIs via FileUriPart; upload to xAI Files and use FileRefPart (file_id) instead. Got \"${p.uri}\".`,\n )\n }\n return { type: 'input_image', image_url: p.uri }\n }\n\n case 'file-ref': {\n if (typeof p.fileId !== 'string' || p.fileId.trim() === '') {\n throw badXaiRequest('FileRefPart.fileId must be a non-empty string.')\n }\n return { type: 'input_file', file_id: p.fileId }\n }\n\n default:\n return assertNever(p)\n }\n}\n\n// ---------------------------------------------------------------------------\n// providerOptions.xai → explicit allowlisted mapping\n// ---------------------------------------------------------------------------\n\nfunction mapXaiProviderOptions(\n xaiOpts: unknown,\n model: string,\n): { promptCacheKey?: string } {\n if (xaiOpts === undefined) {\n return {}\n }\n\n if (!isPlainRecord(xaiOpts)) {\n throw badXaiRequest(`providerOptions.xai must be an object for model \"${model}\".`)\n }\n\n const unknownKeys = Object.keys(xaiOpts).filter((key) => key !== 'promptCacheKey')\n if (unknownKeys.length > 0) {\n throw badXaiRequest(\n `providerOptions.xai contains unsupported keys [${unknownKeys.join(\n ', ',\n )}] for model \"${model}\". Allowed keys: promptCacheKey.`,\n )\n }\n\n const mapped: { promptCacheKey?: string } = {}\n if (xaiOpts['promptCacheKey'] !== undefined) {\n if (\n typeof xaiOpts['promptCacheKey'] !== 'string' ||\n xaiOpts['promptCacheKey'].length === 0\n ) {\n throw badXaiRequest(\n `providerOptions.xai.promptCacheKey must be a non-empty string for model \"${model}\".`,\n )\n }\n mapped.promptCacheKey = xaiOpts['promptCacheKey']\n }\n\n return mapped\n}\n\n// ---------------------------------------------------------------------------\n// FinishReason mapping (xAI status/incomplete_details → our FinishReason)\n// ---------------------------------------------------------------------------\n\nfunction mapFinishReason(response: XaiResponseShape): FinishReason {\n if (response.status === 'completed') {\n return 'stop'\n }\n if (\n response.status === 'incomplete' &&\n response.incomplete_details?.reason === 'max_output_tokens'\n ) {\n return 'length'\n }\n // Any other status/incomplete_details combination without fixture\n // evidence (or a status we don't recognize) maps to 'other' — the core\n // FinishReason union is closed to these four values.\n return 'other'\n}\n\n// ---------------------------------------------------------------------------\n// Usage mapping — #1 correctness rule\n// ---------------------------------------------------------------------------\n\n/**\n * Usage fields already mapped into canonical {@link Usage} counters — never\n * duplicated into `details` under their raw xAI names.\n */\nconst CANONICALLY_MAPPED_USAGE_KEYS = new Set([\n 'input_tokens',\n 'output_tokens',\n 'total_tokens',\n])\n\n/**\n * Map xAI's `usage` object to our {@link Usage} type.\n *\n * **GROSS convention (ADR-004):**\n * - `usage.input_tokens` is already GROSS (includes cached) → `inputTokens`.\n * - `usage.output_tokens` is already GROSS (includes reasoning) → `outputTokens`.\n * Unlike Gemini, xAI does not require us to sum sub-fields into the gross\n * total — the top-level fields are already gross.\n *\n * **xAI extras** (captured, not billed): every additional NUMERIC top-level\n * usage field (`num_sources_used`, `num_server_side_tools_used`,\n * `cost_in_usd_ticks`, and anything xAI adds later) is surfaced into\n * `details` under its raw name. Non-numeric extras (e.g. `context_details`)\n * belong to `AdapterResult.providerMetadata` (see the adapter) and the full\n * raw payload always lands in `Usage.raw` verbatim.\n */\nfunction mapUsage(usage: XaiUsageShape): Usage {\n const inputTokens = usage.input_tokens\n const outputTokens = usage.output_tokens\n const cachedInputTokens = usage.input_tokens_details?.cached_tokens\n const thinkingTokens = usage.output_tokens_details?.reasoning_tokens\n const totalTokens = usage.total_tokens\n\n // Canonical details keys: input, output, cached, thinking.\n const details: Record<string, number> = {\n input: inputTokens,\n output: outputTokens,\n ...(cachedInputTokens !== undefined ? { cached: cachedInputTokens } : {}),\n ...(thinkingTokens !== undefined ? { thinking: thinkingTokens } : {}),\n }\n\n // Numeric xAI extras — surfaced under their raw names.\n for (const [key, value] of Object.entries(usage)) {\n if (typeof value === 'number' && !CANONICALLY_MAPPED_USAGE_KEYS.has(key)) {\n details[key] = value\n }\n }\n\n const raw: JsonValue = usage as unknown as { [k: string]: JsonValue }\n\n const result: Usage = {\n inputTokens,\n outputTokens,\n details,\n raw,\n ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),\n ...(thinkingTokens !== undefined ? { thinkingTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n }\n\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Structured-body auth-failure signature, taken verbatim from the recorded\n * live error taxonomy (`__fixtures__/09-error-taxonomy.json`,\n * `invalid_api_key` case): HTTP 400 with body\n * `{ code: 'invalid-argument', error: 'Incorrect API key provided. …' }`.\n *\n * The body `code` (`'invalid-argument'`) is NOT discriminating — xAI uses it\n * for genuinely bad requests too (e.g. `Model not found: grok-99`) — and the\n * `openai` SDK's `APIError` drops it (it hoists only the body's `error`\n * field onto `.error`). The exact message PREFIX xAI emits for bad keys is\n * therefore the signature.\n */\nconst XAI_AUTH_ERROR_MESSAGE_PREFIX = 'Incorrect API key provided'\n\n/**\n * Extract the STRUCTURED error-body text from a raw thrown value.\n *\n * Consulted shapes (both are parsed-body fields, never free-form\n * `Error.message` text):\n * - `rawErr.error` as a string — the `openai` SDK's `APIError` hoists the\n * response body's `error` field onto `.error`, which for xAI's\n * `{ code, error }` bodies is the message string itself.\n * - `rawErr.error` as an object — the full parsed body (test fakes and\n * hand-rolled throws of the fixture shape `{ status, error: <body> }`);\n * its `error` (xAI) or `message` (OpenAI-style) string field is read.\n *\n * Free-form `Error.message` is deliberately ignored so arbitrary request\n * content echoed into a message (e.g. a schema-validation error quoting user\n * text that mentions \"api key\") can never influence classification.\n */\nfunction extractXaiErrorBodyText(rawErr: unknown): string | undefined {\n if (rawErr === null || typeof rawErr !== 'object') {\n return undefined\n }\n const body = (rawErr as Record<string, unknown>)['error']\n if (typeof body === 'string') {\n return body\n }\n if (isPlainRecord(body)) {\n if (typeof body['error'] === 'string') {\n return body['error']\n }\n if (typeof body['message'] === 'string') {\n return body['message']\n }\n }\n return undefined\n}\n\n/** True iff the structured body matches xAI's recorded bad-API-key signature. */\nfunction isXaiAuthFailureBody(rawErr: unknown): boolean {\n const text = extractXaiErrorBodyText(rawErr)\n return text !== undefined && text.startsWith(XAI_AUTH_ERROR_MESSAGE_PREFIX)\n}\n\n/**\n * Message/errno signatures of a transport-level failure: the request never\n * reached xAI's servers (or the connection was severed mid-flight), so there\n * is no HTTP response for {@link classifyHttpStatus} to route by status.\n * Covers the `openai` SDK's own default message (`\"Connection error.\"`,\n * thrown by `APIConnectionError`) plus the Node/undici errno codes that\n * surface when the underlying `fetch` rejects before a response arrives.\n */\nconst XAI_TRANSPORT_ERROR_PATTERN =\n /connection error|econnreset|econnrefused|etimedout|eai_again|epipe|socket hang up|fetch failed/i\n\n/** True iff `err.message` or `err.code` matches a known transport-failure signature. */\nfunction matchesXaiTransportSignature(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n if (XAI_TRANSPORT_ERROR_PATTERN.test(err.message)) return true\n const code = (err as { code?: unknown }).code\n return typeof code === 'string' && XAI_TRANSPORT_ERROR_PATTERN.test(code)\n}\n\n/**\n * True iff `rawErr` is (or wraps) a transport-level connection failure —\n * observed live killing Temporal-orchestrated audit runs when the `openai`\n * SDK's `APIConnectionError` (\"Connection error.\") fell through\n * `classifyError`'s generic HTTP-status classification to `kind: 'unknown',\n * retryable: false`.\n *\n * Detection order:\n * 1. `rawErr.constructor.name` matches the `openai` SDK's\n * `APIConnectionError` / `APIConnectionTimeoutError` classes. Matched by\n * constructor name rather than `instanceof` so this file does not need a\n * runtime import of `openai` — per `client.ts`, that package is imported\n * ONLY in `buildXaiClient`, keeping unit tests independent of the real\n * SDK.\n * 2. `rawErr.message` / `rawErr.code` matches a known transport-failure\n * signature (handles the SDK's default message text directly, without\n * relying on the class name surviving minification).\n * 3. A wrapped `rawErr.cause` matches either of the above —\n * `APIConnectionError` attaches the underlying fetch/socket error as\n * `.cause`.\n */\nfunction isXaiTransportError(rawErr: unknown): boolean {\n if (!(rawErr instanceof Error)) return false\n\n const ctorName = rawErr.constructor.name\n if (ctorName === 'APIConnectionError' || ctorName === 'APIConnectionTimeoutError') {\n return true\n }\n\n if (matchesXaiTransportSignature(rawErr)) return true\n\n const cause = (rawErr as { cause?: unknown }).cause\n if (cause instanceof Error) {\n const causeCtorName = cause.constructor.name\n if (\n causeCtorName === 'APIConnectionError' ||\n causeCtorName === 'APIConnectionTimeoutError'\n ) {\n return true\n }\n if (matchesXaiTransportSignature(cause)) return true\n }\n\n return false\n}\n\n/**\n * Classify a raw error thrown from the xAI Responses API call into a typed\n * {@link LlmError}.\n *\n * xAI's Responses API returns HTTP 400 (NOT 401) for an invalid API key, so\n * generic {@link classifyHttpStatus}-based classification (which maps 400 →\n * `bad_request`) is wrong for this one case. This function special-cases it:\n * a 400 response whose STRUCTURED parsed body matches the exact recorded\n * xAI auth-failure signature (`code: 'invalid-argument'` AND message prefix\n * `\"Incorrect API key provided\"` — see fixture 09) is reclassified as\n * `invalid_auth`. Free-form `Error.message` text is never scanned, so a 400\n * whose message merely *mentions* an API key (e.g. schema validation echoing\n * user content) stays `bad_request`. When the structured body is unavailable\n * or unparseable, classification falls through to the status-based\n * `classifyError` from `@gullabs/core`.\n *\n * A second special case widens `classifyError`'s generic fallback: when the\n * base classification lands on `kind: 'unknown'` (no HTTP status to route\n * by) AND the raw error matches a known transport-failure signature (see\n * {@link isXaiTransportError}), it is reclassified `kind: 'server',\n * retryable: true` — the same \"provider fault, not caller fault, safe to\n * retry\" bucket this adapter's `countTokens` path already uses for\n * provider-side failures with no HTTP status. A connection that never\n * reached xAI is not the caller's fault and is safe to retry; it must never\n * be surfaced as the non-retryable `unknown` kind, which Temporal treats as\n * fatal and uses to kill the run outright.\n */\nexport function classifyXaiError(rawErr: unknown): LlmError {\n if (rawErr instanceof LlmError) {\n return rawErr\n }\n\n const base = classifyError(rawErr)\n\n if (base.httpStatus === 400 && isXaiAuthFailureBody(rawErr)) {\n return new LlmError(base.message, {\n kind: 'invalid_auth',\n retryable: false,\n httpStatus: base.httpStatus,\n provider: 'xai',\n cause: base.cause ?? rawErr,\n })\n }\n\n if (base.kind === 'unknown' && isXaiTransportError(rawErr)) {\n return new LlmError(base.message, {\n kind: 'server',\n retryable: true,\n provider: 'xai',\n cause: base.cause ?? rawErr,\n })\n }\n\n return new LlmError(base.message, {\n kind: base.kind,\n retryable: base.retryable,\n ...(base.httpStatus !== undefined ? { httpStatus: base.httpStatus } : {}),\n ...(base.retryAfterMs !== undefined ? { retryAfterMs: base.retryAfterMs } : {}),\n provider: 'xai',\n cause: base.cause ?? rawErr,\n })\n}\n\n// ---------------------------------------------------------------------------\n// Adapter options\n// ---------------------------------------------------------------------------\n\nexport interface XaiAdapterOptions {\n /**\n * Inject a pre-built client (real or fake).\n * When omitted, `buildXaiClient` is called with `ctx.auth` at call time,\n * inside the classified try/catch so any construction failure is wrapped\n * as a typed `LlmError`.\n */\n client?: XaiClientLike\n /**\n * @internal Testing-only.\n *\n * Override the default `buildXaiClient` factory. Allows unit tests to\n * simulate construction failures without importing the real `openai` SDK.\n * Never set this in production code. Mirrors `GeminiAdapterOptions._clientFactory`.\n */\n _clientFactory?: (auth: AuthMaterial) => XaiClientLike | Promise<XaiClientLike>\n}\n\n// ---------------------------------------------------------------------------\n// xaiAdapter factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create an xAI Grok provider adapter (Responses API).\n *\n * @param opts.client - Optional pre-built client (e.g. for testing).\n */\nexport function xaiAdapter(opts?: XaiAdapterOptions): ProviderAdapter {\n return {\n id: 'xai',\n\n async run(req: ResolvedRequest, ctx: AdapterCtx): Promise<AdapterResult> {\n if (req.provider !== 'xai') {\n throw new LlmError(\n `xaiAdapter received a request for provider \"${req.provider}\", expected \"xai\".`,\n { kind: 'bad_request', retryable: false },\n )\n }\n\n const warnings: Warning[] = []\n const model = req.model\n const genConfig = req.config\n\n // ------------------------------------------------------------------\n // 1. Map messages → input\n // ------------------------------------------------------------------\n const input: XaiInputItem[] = req.messages.map((msg) => ({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.parts.map(mapPart),\n }))\n\n // ------------------------------------------------------------------\n // 2. Build request params\n // ------------------------------------------------------------------\n const params: XaiResponseCreateParams = {\n model,\n input,\n store: false,\n }\n\n if (req.system !== undefined) {\n params.instructions = req.system\n }\n\n // Sampling — forwarded verbatim, no clamping (schema enforces bounds\n // upstream of the adapter).\n if (genConfig.temperature !== undefined) {\n params.temperature = genConfig.temperature\n }\n if (genConfig.topP !== undefined) {\n params.top_p = genConfig.topP\n }\n\n // max_output_tokens — no artificial ceiling; truncation surfaces as\n // finishReason:'length', not an error (see mapFinishReason).\n if (genConfig.maxOutputTokens !== undefined) {\n params.max_output_tokens = genConfig.maxOutputTokens\n }\n\n // serviceTier — xAI has no service-tier concept for grok-4.5.\n if (genConfig.serviceTier !== undefined) {\n throw badXaiRequest(\n `serviceTier is not supported for xai models (got \"${genConfig.serviceTier}\").`,\n )\n }\n\n // ------------------------------------------------------------------\n // 3. Reasoning → { effort: 'low' | 'high' }\n //\n // grok-4.5 admits ONLY 'low' | 'high' (default 'high'); 'none' and\n // 'medium' are rejected by the live API. budgetTokens is not\n // supported (level-style reasoning, no token budget). includeThoughts\n // is a no-op for xAI — reasoning summaries come back unconditionally\n // whenever reasoning ran, so reasoningText is always surfaced below\n // regardless of this flag; we do not throw on it since it is a\n // legitimate ReasoningIntent field this provider simply doesn't need.\n // ------------------------------------------------------------------\n const reasoning = genConfig.reasoning\n if (reasoning !== undefined) {\n if (reasoning.budgetTokens !== undefined) {\n throw badXaiRequest(\n `reasoning.budgetTokens is not supported for model \"${model}\" (xAI uses effort-level reasoning, not token budgets); use reasoning.effort instead.`,\n )\n }\n\n if (reasoning.effort !== undefined) {\n const effort = reasoning.effort\n if (effort !== 'low' && effort !== 'high') {\n throw badXaiRequest(\n `reasoning.effort \"${effort}\" is not supported for xai model \"${model}\" (only \"low\" and \"high\" are admitted).`,\n )\n }\n const admitted = req.modelDescriptor?.capabilities?.admittedReasoningEfforts\n if (admitted !== undefined && !admitted.includes(effort)) {\n throw badXaiRequest(\n `reasoning.effort \"${effort}\" is not supported for xai model \"${model}\".`,\n )\n }\n params.reasoning = { effort }\n }\n }\n\n // ------------------------------------------------------------------\n // 4. Structured output → text.format (NOT response_format)\n // ------------------------------------------------------------------\n const structuredOutputRequested = req.outputJsonSchema !== undefined\n if (structuredOutputRequested) {\n const schema = req.outputJsonSchema\n const name =\n isPlainRecord(schema) &&\n typeof schema['title'] === 'string' &&\n schema['title'].length > 0\n ? schema['title']\n : 'structured_output'\n params.text = {\n format: { type: 'json_schema', name, schema, strict: true },\n }\n }\n\n // ------------------------------------------------------------------\n // 5. providerOptions.xai → prompt_cache_key\n // ------------------------------------------------------------------\n const xaiProviderConfig = mapXaiProviderOptions(\n genConfig.providerOptions?.['xai'],\n model,\n )\n if (xaiProviderConfig.promptCacheKey !== undefined) {\n params.prompt_cache_key = xaiProviderConfig.promptCacheKey\n }\n\n // ------------------------------------------------------------------\n // 6. Client construction + SDK call — inside the classifier so ANY\n // failure (including bad auth construction) is rethrown as a typed\n // LlmError(provider:'xai').\n // ------------------------------------------------------------------\n let response: XaiResponseShape\n try {\n const buildClient = opts?._clientFactory ?? buildXaiClient\n const client: XaiClientLike =\n opts?.client !== undefined ? opts.client : await buildClient(ctx.auth)\n ctx.logger.debug(\n { model, configKeys: Object.keys(params) },\n 'llm.adapter.dispatch',\n )\n response = await client.responses.create(\n params,\n ctx.signal !== undefined ? { signal: ctx.signal } : undefined,\n )\n } catch (rawErr) {\n throw classifyXaiError(rawErr)\n }\n\n // ------------------------------------------------------------------\n // 7. Map response\n // ------------------------------------------------------------------\n let text = ''\n let reasoningText: string | undefined\n const messageItems: XaiMessageOutputItem[] = []\n\n for (const item of response.output) {\n if (item.type === 'message') {\n messageItems.push(item)\n } else {\n const joined = item.summary.map((s) => s.text).join('')\n if (joined.length > 0) {\n reasoningText = (reasoningText ?? '') + joined\n }\n }\n }\n\n // xAI's Responses API convention: when multiple `type: 'message'`\n // output items are present, the LAST one is the response — earlier\n // ones are superseded (observed live in strict json_schema mode,\n // grok-4.5, reasoning effort high: two complete-JSON message items in\n // one response). Concatenating across items corrupts the payload\n // (e.g. two JSON documents back-to-back); joining `output_text` parts\n // WITHIN a single message item is still correct (segmentation, not\n // duplication).\n if (messageItems.length > 0) {\n const lastMessage = messageItems[messageItems.length - 1] as XaiMessageOutputItem\n text = lastMessage.content.map((part) => part.text).join('')\n\n if (messageItems.length > 1) {\n warnings.push({\n type: 'other',\n message: `xai: response contained ${messageItems.length} message output items; using the last one and discarding ${\n messageItems.length - 1\n } earlier message item(s).`,\n })\n }\n }\n\n // Parse structured output (JSON text → rawStructured).\n let rawStructured: unknown\n if (structuredOutputRequested && text.length > 0) {\n try {\n rawStructured = JSON.parse(text)\n } catch {\n // Core reports unparsed via absence of rawStructured; callers own\n // validation/retry policy (ADR-009).\n }\n }\n\n const usage = mapUsage(response.usage)\n const finishReason = mapFinishReason(response)\n\n // Response-level metadata → providerMetadata: usage.context_details\n // (non-numeric usage extra) and response.metadata (e.g.\n // system_fingerprint). Numeric usage extras live in usage.details; the\n // full raw usage payload is already in usage.raw.\n const providerMeta: { [k: string]: JsonValue } = {}\n const contextDetails = response.usage['context_details']\n if (isPlainRecord(contextDetails)) {\n providerMeta['context_details'] = contextDetails as unknown as JsonValue\n }\n if (isPlainRecord(response.metadata)) {\n providerMeta['metadata'] = response.metadata as unknown as JsonValue\n }\n\n const result: AdapterResult = {\n model: response.model,\n usage,\n warnings,\n finishReason,\n responseId: response.id,\n ...(text.length > 0 ? { text } : {}),\n ...(reasoningText !== undefined ? { reasoningText } : {}),\n ...(rawStructured !== undefined ? { rawStructured } : {}),\n ...(Object.keys(providerMeta).length > 0\n ? { providerMetadata: providerMeta }\n : {}),\n }\n\n return result\n },\n }\n}\n","/**\n * XaiFileStore — thin wrapper over the xAI Files REST API.\n *\n * Upload / get / list / delete / content over injectable `fetch`.\n * No READY-state polling (upload returns metadata immediately).\n * No ambient credential reads — auth is injected at construction.\n *\n * @module\n */\n\nimport type { AuthMaterial, JsonValue, Logger } from '@gullabs/core'\nimport { LlmError, classifyError, redactSecrets } from '@gullabs/core'\n\nimport { requireApiKey } from './client.js'\nimport { classifyXaiError } from './adapter.js'\n\n// ---------------------------------------------------------------------------\n// Public constants\n// ---------------------------------------------------------------------------\n\n/** xAI minimum `expires_after` (1 hour), inclusive. */\nexport const XAI_FILE_TTL_MIN_SECONDS = 3_600\n\n/** xAI maximum `expires_after` (30 days), inclusive. */\nexport const XAI_FILE_TTL_MAX_SECONDS = 2_592_000\n\n/**\n * Conservative max upload size (48 MiB). Managing-files docs say ~48 MB;\n * upload REST says 50 MB — we take the lower bound.\n */\nexport const XAI_FILE_MAX_BYTES = 48 * 1024 * 1024\n\n/** Default Files API base (includes `/v1`). */\nexport const XAI_FILES_DEFAULT_BASE_URL = 'https://api.x.ai/v1'\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** A handle to a file stored in the xAI Files API. */\nexport interface XaiFileHandle {\n /** File id, e.g. `\"file_a128090d-…\"`. Use as `FileRefPart.fileId`. */\n id: string\n filename?: string\n bytes?: number\n purpose?: string\n createdAt?: Date\n /** Present when the file has a TTL; key omitted when permanent / unknown. */\n expiresAt?: Date\n /** Full vendor JSON object for forward-compat (P2 raw lane). */\n raw?: { [k: string]: JsonValue }\n}\n\nexport interface XaiFileUploadInput {\n data: Uint8Array | Blob\n filename: string\n mimeType?: string\n /**\n * TTL in seconds. Must be an integer in\n * `[XAI_FILE_TTL_MIN_SECONDS, XAI_FILE_TTL_MAX_SECONDS]` when set.\n * Omit only for permanent storage (discouraged for ephemeral corpus).\n */\n expiresAfterSeconds?: number\n /** Default `\"assistants\"` (OpenAI SDK convention; xAI does not enforce). */\n purpose?: string\n}\n\nexport interface XaiFileListOptions {\n /** 1..100. Server default is 100 when omitted. */\n limit?: number\n order?: 'asc' | 'desc'\n sortBy?: 'created_at' | 'filename' | 'size'\n paginationToken?: string\n}\n\nexport interface XaiFileListResult {\n files: XaiFileHandle[]\n paginationToken?: string\n}\n\nexport interface XaiFileStoreOptions {\n auth: AuthMaterial\n /** Default {@link XAI_FILES_DEFAULT_BASE_URL}. */\n baseUrl?: string\n /** Injectable fetch for tests. Default: global `fetch`. */\n fetch?: typeof fetch\n /**\n * Delete failures that are NOT already-gone (404).\n * Default: `logger.error` or `console.error` with a redacted message.\n */\n onDeleteError?: (fileId: string, err: unknown) => void\n logger?: Logger\n /** Injectable clock for tests. Default: `Date.now`. */\n now?: () => number\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype VendorFileObject = {\n id?: unknown\n filename?: unknown\n bytes?: unknown\n purpose?: unknown\n created_at?: unknown\n expires_at?: unknown\n object?: unknown\n [k: string]: unknown\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction badRequest(message: string): LlmError {\n return new LlmError(message, {\n kind: 'bad_request',\n retryable: false,\n provider: 'xai',\n })\n}\n\nfunction resolveFileId(fileIdOrHandle: string | Pick<XaiFileHandle, 'id'>): string {\n if (typeof fileIdOrHandle === 'string') {\n return fileIdOrHandle\n }\n return fileIdOrHandle.id\n}\n\nfunction unixSecondsToDate(value: unknown): Date | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return undefined\n }\n return new Date(value * 1000)\n}\n\nfunction makeHandle(raw: VendorFileObject): XaiFileHandle {\n if (typeof raw.id !== 'string' || raw.id.length === 0) {\n throw new LlmError('File response missing required field (id)', {\n kind: 'server',\n retryable: false,\n provider: 'xai',\n })\n }\n\n const handle: XaiFileHandle = {\n id: raw.id,\n raw: raw as { [k: string]: JsonValue },\n }\n\n if (typeof raw.filename === 'string' && raw.filename.length > 0) {\n handle.filename = raw.filename\n }\n if (typeof raw.bytes === 'number' && Number.isFinite(raw.bytes)) {\n handle.bytes = raw.bytes\n }\n if (typeof raw.purpose === 'string') {\n handle.purpose = raw.purpose\n }\n\n const createdAt = unixSecondsToDate(raw.created_at)\n if (createdAt !== undefined) {\n handle.createdAt = createdAt\n }\n\n // expires_at is null for permanent files — omit the key entirely (Google parity).\n if (raw.expires_at !== null && raw.expires_at !== undefined) {\n const expiresAt = unixSecondsToDate(raw.expires_at)\n if (expiresAt !== undefined) {\n handle.expiresAt = expiresAt\n }\n }\n\n return handle\n}\n\nfunction byteLengthOf(data: Uint8Array | Blob): number {\n return data instanceof Uint8Array ? data.byteLength : data.size\n}\n\nfunction toBlob(data: Uint8Array | Blob, mimeType: string | undefined): Blob {\n if (data instanceof Blob) {\n return data\n }\n // Copy into a plain ArrayBuffer-backed view for BlobPart typing.\n const copy = Uint8Array.from(data)\n return mimeType !== undefined && mimeType.length > 0\n ? new Blob([copy], { type: mimeType })\n : new Blob([copy])\n}\n\n/**\n * Shape a non-2xx fetch response into a throw value that\n * {@link classifyXaiError} / {@link classifyError} understand:\n * - `.status` for HTTP routing\n * - `.error` for structured body (auth-body detection)\n */\n/**\n * Error shaped for {@link classifyError} / {@link classifyXaiError}:\n * numeric `.status` for HTTP routing, `.error` for structured body text.\n */\nclass XaiFilesHttpError extends Error {\n readonly status: number\n readonly error: unknown\n\n constructor(status: number, message: string, errorBody: unknown) {\n super(message)\n this.name = 'XaiFilesHttpError'\n this.status = status\n this.error = errorBody\n }\n}\n\nasync function throwHttpFailure(res: Response): Promise<never> {\n const status = res.status\n let bodyText = ''\n try {\n bodyText = await res.text()\n } catch {\n bodyText = ''\n }\n\n let parsed: unknown = bodyText\n if (bodyText.length > 0) {\n try {\n parsed = JSON.parse(bodyText) as unknown\n } catch {\n parsed = bodyText\n }\n }\n\n let message = `xAI Files API HTTP ${status}`\n if (typeof parsed === 'string' && parsed.length > 0) {\n message = parsed\n } else if (isPlainRecord(parsed) && typeof parsed['error'] === 'string') {\n message = parsed['error']\n }\n\n throw new XaiFilesHttpError(status, message, parsed)\n}\n\nfunction isNotFoundError(err: unknown): boolean {\n if (err instanceof LlmError && err.httpStatus === 404) {\n return true\n }\n if (typeof err === 'object' && err !== null) {\n const status = (err as { status?: unknown }).status\n if (status === 404) return true\n const httpStatus = (err as { httpStatus?: unknown }).httpStatus\n if (httpStatus === 404) return true\n }\n return false\n}\n\nfunction notFoundError(fileId: string, operation: string): LlmError {\n return new LlmError(`xAI file not found during ${operation}: \"${fileId}\"`, {\n kind: 'bad_request',\n retryable: false,\n httpStatus: 404,\n provider: 'xai',\n })\n}\n\nfunction maybeZdrHint(message: string): string {\n if (\n /zero\\s*data\\s*retention|\\bzdr\\b|files?\\s+(api\\s+)?(disabled|unavailable|not supported)/i.test(\n message,\n )\n ) {\n return `${message} (xAI Zero Data Retention blocks new file uploads and file_id attachments for this team.)`\n }\n return message\n}\n\n/** Prefer structured body text / explicit message over generic `HTTP NNN`. */\nfunction extractThrownMessage(raw: unknown): string | undefined {\n if (raw === null || typeof raw !== 'object') return undefined\n const obj = raw as Record<string, unknown>\n if (typeof obj['message'] === 'string' && obj['message'].length > 0) {\n return obj['message']\n }\n const err = obj['error']\n if (typeof err === 'string' && err.length > 0) return err\n if (typeof err === 'object' && err !== null) {\n const nested = err as Record<string, unknown>\n if (typeof nested['error'] === 'string' && nested['error'].length > 0) {\n return nested['error']\n }\n if (typeof nested['message'] === 'string' && nested['message'].length > 0) {\n return nested['message']\n }\n }\n return undefined\n}\n\nfunction classifyStoreError(raw: unknown): LlmError {\n if (raw instanceof LlmError) {\n return raw\n }\n const classified = classifyXaiError(raw)\n const bodyMessage = extractThrownMessage(raw)\n // classifyError maps plain `{ status }` throws to generic \"HTTP NNN\" — prefer\n // the structured body text we attached in throwHttpFailure when present.\n const baseMessage =\n bodyMessage !== undefined &&\n (classified.message.startsWith('HTTP ') || classified.message.length === 0)\n ? bodyMessage\n : classified.message\n const hinted = maybeZdrHint(baseMessage)\n if (\n hinted === classified.message &&\n classified.provider === 'xai' &&\n bodyMessage === undefined\n ) {\n return classified\n }\n return new LlmError(hinted, {\n kind: classified.kind,\n retryable: classified.retryable,\n ...(classified.httpStatus !== undefined ? { httpStatus: classified.httpStatus } : {}),\n ...(classified.retryAfterMs !== undefined\n ? { retryAfterMs: classified.retryAfterMs }\n : {}),\n provider: 'xai',\n cause: classified.cause ?? raw,\n })\n}\n\n// ---------------------------------------------------------------------------\n// XaiFileStore\n// ---------------------------------------------------------------------------\n\n/**\n * **Auth snapshot note:** captures `AuthMaterial` at construction and holds\n * the resolved API key for the store lifetime. Correct for static API keys.\n * Refreshable credentials would need a resolver callback (see GoogleFileStore\n * / ADR-020).\n */\nexport class XaiFileStore {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n private readonly onDeleteError: (fileId: string, err: unknown) => void\n private readonly logger: Logger | undefined\n\n constructor(opts: XaiFileStoreOptions) {\n this.apiKey = requireApiKey(opts.auth)\n this.baseUrl = (opts.baseUrl ?? XAI_FILES_DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.fetchImpl = opts.fetch ?? fetch\n this.logger = opts.logger\n this.onDeleteError =\n opts.onDeleteError ??\n ((fileId, err) => {\n const message = redactSecrets(classifyError(err).message)\n if (this.logger !== undefined) {\n this.logger.error({ fileId, error: message }, 'xai.file.delete.failed')\n } else {\n console.error(`[XaiFileStore] delete failed for \"${fileId}\":`, message)\n }\n })\n }\n\n private authHeaders(): Headers {\n const headers = new Headers()\n headers.set('Authorization', `Bearer ${this.apiKey}`)\n return headers\n }\n\n private filesUrl(path = ''): string {\n if (path.length === 0) return `${this.baseUrl}/files`\n return `${this.baseUrl}/files/${path.replace(/^\\//, '')}`\n }\n\n /** Build RequestInit without writing `signal: undefined` (exactOptionalPropertyTypes). */\n private requestInit(\n method: string,\n opts?: { body?: FormData; signal?: AbortSignal },\n ): RequestInit {\n const init: RequestInit = {\n method,\n headers: this.authHeaders(),\n }\n if (opts?.body !== undefined) {\n init.body = opts.body\n }\n if (opts?.signal !== undefined) {\n init.signal = opts.signal\n }\n return init\n }\n\n /**\n * Upload bytes to xAI Files. Returns immediately with metadata (no poll).\n *\n * Multipart field order is load-bearing: `expires_after` then `purpose`\n * then `file` — reversing order yields HTTP 400 from xAI.\n */\n async upload(input: XaiFileUploadInput, signal?: AbortSignal): Promise<XaiFileHandle> {\n if (typeof input.filename !== 'string' || input.filename.trim() === '') {\n throw badRequest('XaiFileUploadInput.filename must be a non-empty string.')\n }\n\n const size = byteLengthOf(input.data)\n if (size > XAI_FILE_MAX_BYTES) {\n throw badRequest(\n `xAI file uploads must be at most ${XAI_FILE_MAX_BYTES} bytes (48 MiB); got ${size}.`,\n )\n }\n\n if (input.expiresAfterSeconds !== undefined) {\n const ttl = input.expiresAfterSeconds\n if (\n typeof ttl !== 'number' ||\n !Number.isInteger(ttl) ||\n ttl < XAI_FILE_TTL_MIN_SECONDS ||\n ttl > XAI_FILE_TTL_MAX_SECONDS\n ) {\n throw badRequest(\n `expiresAfterSeconds must be an integer in [${XAI_FILE_TTL_MIN_SECONDS}, ${XAI_FILE_TTL_MAX_SECONDS}]; got ${String(ttl)}.`,\n )\n }\n }\n\n const purpose = input.purpose ?? 'assistants'\n const form = new FormData()\n\n // Order: expires_after → purpose → file (xAI multipart requirement).\n if (input.expiresAfterSeconds !== undefined) {\n form.append('expires_after', String(input.expiresAfterSeconds))\n }\n form.append('purpose', purpose)\n form.append('file', toBlob(input.data, input.mimeType), input.filename)\n\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(),\n this.requestInit('POST', {\n body: form,\n ...(signal !== undefined ? { signal } : {}),\n }),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file upload aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n let json: unknown\n try {\n json = await res.json()\n } catch (e) {\n throw new LlmError('xAI file upload returned non-JSON body', {\n kind: 'server',\n retryable: false,\n provider: 'xai',\n cause: e,\n })\n }\n\n return makeHandle(json as VendorFileObject)\n }\n\n async get(fileId: string, signal?: AbortSignal): Promise<XaiFileHandle> {\n if (typeof fileId !== 'string' || fileId.trim() === '') {\n throw badRequest('fileId must be a non-empty string.')\n }\n\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(fileId),\n this.requestInit('GET', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file get aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (res.status === 404) {\n throw notFoundError(fileId, 'get')\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n const json = (await res.json()) as VendorFileObject\n return makeHandle(json)\n }\n\n async list(\n opts: XaiFileListOptions = {},\n signal?: AbortSignal,\n ): Promise<XaiFileListResult> {\n if (opts.limit !== undefined) {\n if (\n typeof opts.limit !== 'number' ||\n !Number.isInteger(opts.limit) ||\n opts.limit < 1 ||\n opts.limit > 100\n ) {\n throw badRequest('list.limit must be an integer in [1, 100].')\n }\n }\n\n const params = new URLSearchParams()\n if (opts.limit !== undefined) params.set('limit', String(opts.limit))\n if (opts.order !== undefined) params.set('order', opts.order)\n if (opts.sortBy !== undefined) params.set('sort_by', opts.sortBy)\n if (opts.paginationToken !== undefined) {\n params.set('pagination_token', opts.paginationToken)\n }\n\n const qs = params.toString()\n const url = qs.length > 0 ? `${this.filesUrl()}?${qs}` : this.filesUrl()\n\n let res: Response\n try {\n res = await this.fetchImpl(\n url,\n this.requestInit('GET', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file list aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n const json = (await res.json()) as {\n data?: VendorFileObject[]\n pagination_token?: string\n }\n const files = Array.isArray(json.data) ? json.data.map((f) => makeHandle(f)) : []\n const result: XaiFileListResult = { files }\n if (typeof json.pagination_token === 'string' && json.pagination_token.length > 0) {\n result.paginationToken = json.pagination_token\n }\n return result\n }\n\n /**\n * Delete a file. Idempotent: HTTP 404 → success.\n * Other errors are forwarded to `onDeleteError` and **not** rethrown (P5).\n */\n async delete(\n fileIdOrHandle: string | Pick<XaiFileHandle, 'id'>,\n signal?: AbortSignal,\n ): Promise<void> {\n const fileId = resolveFileId(fileIdOrHandle)\n if (typeof fileId !== 'string' || fileId.trim() === '') {\n // Fail-open still applies — surface via callback rather than throw.\n this.onDeleteError(String(fileId), badRequest('fileId must be a non-empty string.'))\n return\n }\n\n try {\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(fileId),\n this.requestInit('DELETE', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n // Aborts are caller intent; still fail-open on delete side-effects.\n this.onDeleteError(\n fileId,\n new LlmError('xAI file delete aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n }),\n )\n return\n }\n throw e\n }\n\n if (res.status === 404) {\n return\n }\n\n if (!res.ok) {\n await throwHttpFailure(res)\n }\n } catch (err) {\n if (isNotFoundError(err)) {\n return\n }\n this.onDeleteError(fileId, classifyStoreError(err))\n }\n }\n\n /**\n * Delete many files. Each failure is individually fail-open; none are thrown.\n */\n async deleteAll(\n ids: ReadonlyArray<string | Pick<XaiFileHandle, 'id'>>,\n signal?: AbortSignal,\n ): Promise<void> {\n await Promise.allSettled(ids.map((id) => this.delete(id, signal)))\n }\n\n /** Download raw file bytes. */\n async getContent(fileId: string, signal?: AbortSignal): Promise<Uint8Array> {\n if (typeof fileId !== 'string' || fileId.trim() === '') {\n throw badRequest('fileId must be a non-empty string.')\n }\n\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(`${fileId}/content`),\n this.requestInit('GET', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file content download aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (res.status === 404) {\n throw notFoundError(fileId, 'getContent')\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n const buf = await res.arrayBuffer()\n return new Uint8Array(buf)\n }\n}\n","/**\n * Strict Zod config schema for xAI's `grok-4.5` model.\n *\n * Mirrors `@gullabs/core`'s `packages/core/src/model-config/*.ts` doc-density\n * style, but is a single self-contained `z.strictObject` — unlike Gemini's\n * schemas, xai has no service-tier branching (no `z.union` of tier variants\n * needed), no `topK`, and only a single reasoning-effort union (`'low'|'high'`).\n *\n * @module\n */\n\nimport { z } from 'zod'\n\nexport const Grok45ConfigSchema = z\n .strictObject({\n temperature: z.number().optional().meta({\n title: 'Temperature',\n description: 'Sampling temperature forwarded verbatim to grok-4.5.',\n }),\n topP: z.number().optional().meta({\n title: 'Top P',\n description: 'Nucleus sampling parameter forwarded verbatim to grok-4.5.',\n }),\n maxOutputTokens: z\n .number()\n .int()\n .positive()\n .optional()\n .meta({\n title: 'Max Output Tokens',\n description:\n 'Maximum output token cap for grok-4.5. No artificial ceiling — xAI ' +\n 'accepts arbitrarily large values (live-verified); truncation surfaces ' +\n \"as finishReason:'length', not an error.\",\n }),\n reasoning: z\n .strictObject({\n effort: z.enum(['low', 'high']).meta({\n title: 'Reasoning Effort',\n description:\n 'Reasoning effort for grok-4.5. Only \"low\" and \"high\" are admitted ' +\n '(live-verified); \"none\"/\"medium\"/\"xhigh\" are rejected by the live API.',\n }),\n })\n .optional()\n .meta({\n title: 'Reasoning',\n description:\n 'grok-4.5 effort-level reasoning configuration. No budgetTokens field — ' +\n 'xAI uses level-style reasoning, not token budgets.',\n }),\n timeoutMs: z.number().int().positive().optional().meta({\n title: 'Timeout',\n description: 'Logical request timeout in milliseconds.',\n }),\n providerOptions: z\n .strictObject({\n xai: z\n .strictObject({\n promptCacheKey: z\n .string()\n .min(1)\n .optional()\n .meta({\n title: 'Prompt Cache Key',\n description:\n 'xAI conversation-routing cache key — maps to Responses API ' +\n '`prompt_cache_key`.',\n }),\n })\n .optional()\n .meta({\n title: 'xAI Provider Options',\n description: 'Allowlisted xAI provider options for grok-4.5.',\n }),\n })\n .optional()\n .meta({\n title: 'Provider Options',\n description: 'Provider-specific options accepted for grok-4.5.',\n }),\n })\n .meta({\n title: 'Grok45Config',\n description:\n 'Strict Responses API config for model grok-4.5. Level reasoning ' +\n '(low/high only), tunable sampling, no service tiers, structured output, ' +\n 'vision, priced.',\n examples: [{ reasoning: { effort: 'high' } }],\n })\n","/**\n * Model descriptor + registry for @gullabs/xai.\n *\n * v1 ships exactly one model: `grok-4.5` (canonical id only — the\n * `grok-4.5-latest` / `grok-build-latest` aliases visible in xAI's\n * `/v1/models` listing are intentionally NOT registered as separate\n * descriptors; reject-don't-map, callers must use `grok-4.5` verbatim).\n *\n * @module\n */\n\nimport type { ModelDescriptor, ModelRegistry } from '@gullabs/core'\nimport {\n createModelRegistry,\n toConfigJsonSchema,\n zodToStandardSchema,\n} from '@gullabs/core'\n\nimport { Grok45ConfigSchema } from './model-config/grok-4-5.js'\n\nexport { Grok45ConfigSchema } from './model-config/grok-4-5.js'\n\nexport const grok45ModelDescriptor: ModelDescriptor = {\n model: 'grok-4.5',\n provider: 'xai',\n pricingFamily: 'grok-4.5',\n capabilities: {\n reasoning: true,\n reasoningApi: 'level',\n admittedReasoningEfforts: ['low', 'high'],\n structuredOutput: true,\n nativeStructuredOutput: true,\n vision: true,\n audioInput: false,\n sampling: 'tunable',\n caching: { explicit: false, minTokens: 0 },\n grounding: false,\n // No serviceTiers key — xai has no service-tier concept.\n },\n configSchema: Grok45ConfigSchema,\n configJsonSchema: toConfigJsonSchema(Grok45ConfigSchema),\n validateConfig: zodToStandardSchema(Grok45ConfigSchema),\n}\n\n/** Every model descriptor `@gullabs/xai` contributes. v1 ships only grok-4.5. */\nexport const xaiModelDescriptors: ModelDescriptor[] = [grok45ModelDescriptor]\n\nexport const xaiRegistry: ModelRegistry = createModelRegistry(xaiModelDescriptors)\n","/**\n * xAI pricing snapshot + cost computation for @gullabs/xai.\n *\n * All rates are in **micro-USD per million tokens** (µUSD/M), matching\n * `@gullabs/core`'s `ModelRates` convention exactly: `cost_µUSD = N *\n * ratePerM / 1_000_000`.\n *\n * This is a SELF-CONTAINED, xai-owned reimplementation — it does NOT import\n * core's Gemini-specific `computeCost`/`GEMINI_PRICING`/`geminiPricingSource`\n * (those are Gemini-only). `PricingSource` is provider-scoped by contract\n * (see `packages/core/src/ports.ts`); this module is xai's own.\n *\n * **Long-context tier.** grok-4.5 charges a premium when the GROSS input\n * token count exceeds 200,000 (`long_context_threshold` in xAI's\n * `/v1/models` listing). Selected by `inputTokens` (incl. cached), not by\n * billable input — mirrors core's `selectRates` convention exactly (strictly\n * greater than 200,000).\n *\n * **Service tiers.** xAI has no service-tier concept for grok-4.5 — there is\n * no `TIER_FACTOR`-equivalent here. `price()`'s `tier` param is accepted for\n * `PricingSource` structural conformance but any *defined* tier is treated\n * as unrecognized → unpriced (reject-don't-map), mirroring core's own\n * defensive stance for an unrecognized tier. `undefined` (no tier requested,\n * the only value xAI adapters ever pass — `xaiAdapter` rejects `serviceTier`\n * upstream) prices normally.\n *\n * **Conversion factor.** xAI's `/v1/models` raw `*_token_price` fields are\n * in hundred-thousandths of a dollar per token (i.e. divide the raw integer\n * by 10,000 to get USD per million tokens): e.g. `grok-4.5`'s raw\n * `prompt_text_token_price: 20000` ÷ 10,000 = $2.00/M, which matches the\n * confirmed live-verified figure.\n *\n * Verified against `/v1/models` fixture captured 2026-07-09 (see\n * `docs/provider-plugins-and-xai-grok-4-5-plan.md` and the live-verification\n * fixture directory referenced in the commit-3 task brief).\n *\n * @module\n */\n\nimport type { Cost, PricingSource, Usage } from '@gullabs/core'\n\n/** Identifies this pricing snapshot — bump the date when rates change. */\nexport const xaiPricingVersion = 'xai-2026-07-09' as const\n\n/**\n * Per-model rate entry (all values in µUSD per million tokens).\n *\n * `gt200k` (when present) applies when GROSS input tokens > 200,000.\n */\nexport interface XaiModelRates {\n /** µUSD per million input tokens (billable = gross − cached). */\n inputPerM: number\n /** µUSD per million cache-read tokens. */\n cachedPerM: number\n /** µUSD per million output tokens (reasoning tokens are folded in). */\n outputPerM: number\n /** Optional high-tier rates for long-context (GROSS input > 200k). */\n gt200k?: {\n inputPerM: number\n cachedPerM: number\n outputPerM: number\n }\n}\n\n/**\n * Frozen xAI pricing snapshot (per-1M in µUSD).\n *\n * Keys are EXACT canonical model identifiers — no prefix or alias matching.\n * xAI aliases (e.g. `grok-4.5-latest`, `grok-build-latest`) are deliberately\n * NOT registered/priced (reject-don't-map): callers must use the canonical\n * id; anything else resolves to the unpriced path.\n */\nexport const XAI_PRICING: Readonly<Record<string, XaiModelRates>> = Object.freeze({\n // ── grok-4.5 ── $2.00/$6.00 (≤200k), $4.00/$12.00 (>200k); cached $0.50/$1.00\n 'grok-4.5': {\n inputPerM: 2_000_000,\n cachedPerM: 500_000,\n outputPerM: 6_000_000,\n gt200k: {\n inputPerM: 4_000_000,\n cachedPerM: 1_000_000,\n outputPerM: 12_000_000,\n },\n },\n})\n\nconst LONG_CONTEXT_THRESHOLD = 200_000\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Look up rates for a model — EXACT match only.\n *\n * Deliberately no prefix matching (unlike core's Gemini lookup): xAI aliases\n * such as `grok-4.5-latest` would otherwise prefix-match `grok-4.5` and\n * silently reintroduce the alias behavior the model registry rejects. An id\n * that is not an exact `XAI_PRICING` key is unpriced.\n */\nfunction lookupRates(model: string): XaiModelRates | undefined {\n return XAI_PRICING[model]\n}\n\n/**\n * Select the applicable rate set for a model given the GROSS input token\n * count. When a model has a `gt200k` tier, that tier's rates apply when\n * `grossInputTokens` is **strictly greater than** 200,000.\n */\nfunction selectRates(\n rates: XaiModelRates,\n grossInputTokens: number,\n): { inputPerM: number; cachedPerM: number; outputPerM: number } {\n if (rates.gt200k !== undefined && grossInputTokens > LONG_CONTEXT_THRESHOLD) {\n return rates.gt200k\n }\n return {\n inputPerM: rates.inputPerM,\n cachedPerM: rates.cachedPerM,\n outputPerM: rates.outputPerM,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the cost of an xAI LLM call given a model name and usage data.\n *\n * Pure function — no side effects, always returns a well-formed {@link Cost}.\n *\n * **Algorithm** (mirrors `@gullabs/core`'s `computeCost` exactly, xai-owned):\n * 1. Look up rates for `model`; if not found, return an unpriced `Cost`\n * (`microUsd: null`) naming the model.\n * 2. A defined `tier` is always unpriced (xai has no tiers; reject-don't-map).\n * `undefined` prices normally.\n * 3. Select base vs. `>200k` long-context rates from GROSS `inputTokens`.\n * 4. Billable input = `inputTokens − (cachedInputTokens ?? 0)`, clamped to 0.\n * 5. Round each component (input, cached, output) independently to the\n * nearest integer micro-USD.\n * 6. `microUsd` is the sum of the three components — guarantees\n * `details.input + details.cached + details.output === microUsd` exactly.\n */\nexport function computeXaiCost(model: string, usage: Usage, tier?: string): Cost {\n const rates = lookupRates(model)\n\n if (rates === undefined) {\n return {\n microUsd: null,\n usd: null,\n pricingVersion: xaiPricingVersion,\n confidence: 'estimated',\n details: { input: 0, cached: 0, output: 0 },\n unpricedReason: `Unknown model \"${model}\"; no pricing entry found.`,\n }\n }\n\n if (tier !== undefined) {\n return {\n microUsd: null,\n usd: null,\n pricingVersion: xaiPricingVersion,\n confidence: 'estimated',\n details: { input: 0, cached: 0, output: 0 },\n unpricedReason: `Unknown service tier \"${tier}\"; xai has no service tiers, refusing to guess a pricing multiplier.`,\n }\n }\n\n const base = selectRates(rates, usage.inputTokens)\n\n const cached = usage.cachedInputTokens ?? 0\n const billableInput = Math.max(0, usage.inputTokens - cached)\n\n const inputCost = Math.round((billableInput * base.inputPerM) / 1_000_000)\n const cachedCost = Math.round((cached * base.cachedPerM) / 1_000_000)\n const outputCost = Math.round((usage.outputTokens * base.outputPerM) / 1_000_000)\n\n const microUsd = inputCost + cachedCost + outputCost\n\n return {\n microUsd,\n usd: microUsd / 1_000_000,\n pricingVersion: xaiPricingVersion,\n confidence: 'exact',\n details: {\n input: inputCost,\n cached: cachedCost,\n output: outputCost,\n },\n }\n}\n\n/**\n * Factory that returns the **xai-scoped** {@link PricingSource} port\n * implementation backed by {@link XAI_PRICING}.\n *\n * @example\n * ```ts\n * import { xaiPricingSource } from '@gullabs/xai'\n *\n * const pricing = xaiPricingSource()\n * const cost = pricing.price('grok-4.5', usage)\n * ```\n */\nexport function xaiPricingSource(): PricingSource {\n return {\n version: xaiPricingVersion,\n price(model: string, usage: Usage, tier?: string): Cost {\n return computeXaiCost(model, usage, tier)\n },\n hasModel(model: string): boolean {\n return lookupRates(model) !== undefined\n },\n listModels(): readonly string[] {\n return Object.keys(XAI_PRICING)\n },\n }\n}\n","/**\n * `xaiProvider` — {@link ProviderPlugin} factory for @gullabs/xai.\n *\n * Bundles the xAI Grok adapter, the `grok-4.5` model descriptor, and the\n * xai pricing source into a single plugin for {@link composeProviders}.\n *\n * @module\n */\n\nimport type { ProviderPlugin } from '@gullabs/core'\n\nimport { xaiAdapter } from './adapter.js'\nimport type { XaiAdapterOptions } from './adapter.js'\nimport { xaiModelDescriptors } from './models.js'\nimport { xaiPricingSource } from './pricing.js'\n\n/**\n * Create a {@link ProviderPlugin} for the xAI Grok provider.\n *\n * @param opts - Forwarded to {@link xaiAdapter}.\n * @returns A plugin bundling the xAI adapter, the `grok-4.5` model\n * descriptor, and the built-in xai pricing source.\n *\n * @example\n * ```ts\n * import { createClient, composeProviders } from '@gullabs/core'\n * import { xaiProvider } from '@gullabs/xai'\n *\n * const client = createClient({\n * ...composeProviders([xaiProvider()]),\n * })\n * ```\n */\nexport function xaiProvider(opts?: XaiAdapterOptions): ProviderPlugin {\n return {\n adapter: xaiAdapter(opts),\n modelDescriptors: xaiModelDescriptors,\n pricingSource: xaiPricingSource(),\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/adapter.ts","../src/file-store.ts","../src/model-config/grok-4-5.ts","../src/models.ts","../src/pricing.ts","../src/provider.ts"],"names":["LlmError","isPlainRecord","classifyError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Structural XaiClientLike interface + buildXaiClient factory.\n *\n * This module defines the structural interface the adapter depends on.\n * The real `openai` SDK is imported ONLY in buildXaiClient so tests can\n * inject a fake without pulling in the real SDK. This is the ONLY file in\n * `packages/xai/src` that imports `openai`.\n *\n * @module\n */\n\nimport { LlmError } from '@gullabs/core'\nimport type { AuthMaterial } from '@gullabs/core'\n\n// ---------------------------------------------------------------------------\n// Auth narrowing — xAI only accepts ApiKeyAuth\n// ---------------------------------------------------------------------------\n\n/**\n * Narrows {@link AuthMaterial} to its `apiKey` string, rejecting the\n * dev-only `CliSessionAuth` variant.\n *\n * xAI is a production API provider and only ever accepts API-key\n * credentials; `{ cliSession: true }` is reserved for the dev-only CLI\n * provider packages (`@gullabs/claude-cli`, `@gullabs/codex-cli`).\n */\nexport function requireApiKey(auth: AuthMaterial): string {\n if (\n !('apiKey' in auth) ||\n typeof auth.apiKey !== 'string' ||\n auth.apiKey.trim() === ''\n ) {\n throw new LlmError('@gullabs/xai requires auth.apiKey', {\n kind: 'invalid_auth',\n retryable: false,\n provider: 'xai',\n })\n }\n return auth.apiKey\n}\n\n// ---------------------------------------------------------------------------\n// Request shape — what the (future) adapter sends to responses.create\n// ---------------------------------------------------------------------------\n\n/** A text content item within an xAI Responses API input message. */\nexport interface XaiInputTextPart {\n type: 'input_text'\n text: string\n}\n\n/**\n * An image content item within an xAI Responses API input message.\n * `image_url` may be a data URL (`data:image/png;base64,...`) or a public URL.\n */\nexport interface XaiInputImagePart {\n type: 'input_image'\n image_url: string\n}\n\n/**\n * A file attachment content item within an xAI Responses API input message.\n * Prefer `file_id` for private uploads (via {@link XaiFileStore}); `file_url`\n * is for publicly reachable documents. Attaching either implicitly enables\n * xAI's `attachment_search` agentic tool.\n */\nexport interface XaiInputFilePart {\n type: 'input_file'\n file_id?: string\n file_url?: string\n}\n\n/** Union of content-part shapes an input message may carry. */\nexport type XaiInputContentPart = XaiInputTextPart | XaiInputImagePart | XaiInputFilePart\n\n/** A single role+content input item constructed by the (future) adapter. */\nexport interface XaiInputItem {\n role: 'user' | 'assistant' | 'system' | 'developer'\n content: XaiInputContentPart[]\n}\n\n/**\n * Structured-output text-format request shape.\n * Real xAI field: `text.format`, NOT `response_format`.\n * `name` and `strict` are included per xAI's Structured Outputs docs\n * conventions even though the live fixture's request-echo does not surface\n * them (only the schema is echoed back).\n */\nexport type XaiTextFormat =\n | { type: 'json_schema'; name: string; schema: unknown; strict: boolean }\n | { type: 'text' }\n\n/**\n * Parameters for `client.responses.create`.\n * Structurally modeled from live-captured xAI Responses API fixtures\n * (see docs/provider-plugins-and-xai-grok-4-5-plan.md §3.1), not from the\n * `openai` npm package's TS types — xAI's actual endpoint shape differs.\n */\nexport interface XaiResponseCreateParams {\n model: string\n input: XaiInputItem[]\n instructions?: string\n reasoning?: { effort: 'low' | 'high' }\n text?: { format: XaiTextFormat }\n temperature?: number\n top_p?: number\n max_output_tokens?: number\n prompt_cache_key?: string\n /** Always `false` — this library never relies on xAI-side conversation storage. */\n store: false\n}\n\n// ---------------------------------------------------------------------------\n// Response shape — mirrors the xAI Responses API surface we actually consume\n// ---------------------------------------------------------------------------\n\n/** A single summary-text segment of a `type: 'reasoning'` output item. */\nexport interface XaiReasoningSummaryPart {\n type: 'summary_text'\n text: string\n}\n\n/** A `type: 'reasoning'` item in `output`. */\nexport interface XaiReasoningOutputItem {\n type: 'reasoning'\n id?: string\n summary: XaiReasoningSummaryPart[]\n status?: string\n}\n\n/** A single text content segment of a `type: 'message'` output item. */\nexport interface XaiOutputTextPart {\n type: 'output_text'\n text: string\n logprobs?: unknown[]\n annotations?: unknown[]\n}\n\n/** A `type: 'message'` item in `output`. */\nexport interface XaiMessageOutputItem {\n type: 'message'\n id?: string\n role?: string\n status?: string\n content: XaiOutputTextPart[]\n}\n\n/** Union of output-item shapes the Responses API may return. */\nexport type XaiOutputItem = XaiReasoningOutputItem | XaiMessageOutputItem\n\n/**\n * Token usage metadata returned alongside an xAI response.\n *\n * Kept loose/open: the known fields are typed, but xAI has been observed to\n * add additional numeric fields (e.g. `num_sources_used`,\n * `cost_in_usd_ticks`, `context_details`) that must not break this type.\n */\nexport interface XaiUsageShape {\n input_tokens: number\n input_tokens_details?: { cached_tokens?: number }\n output_tokens: number\n output_tokens_details?: { reasoning_tokens?: number }\n total_tokens?: number\n /** Additional provider-specific usage fields, passed through raw. */\n [otherKeys: string]: unknown\n}\n\n/**\n * Structural equivalent of the xAI Responses API response body.\n * Only the fields the (future) adapter reads are represented here.\n */\nexport interface XaiResponseShape {\n id: string\n model: string\n /**\n * Real field: `status`. Observed values: \"completed\", \"incomplete\" — kept\n * as a plain `string` since xAI may add further status values over time.\n */\n status: string\n incomplete_details?: { reason?: string } | null\n output: XaiOutputItem[]\n usage: XaiUsageShape\n reasoning?: { effort?: string; summary?: string }\n store?: boolean\n prompt_cache_key?: string | null\n /**\n * Response-level metadata (e.g. `system_fingerprint`) — surfaced into\n * `AdapterResult.providerMetadata` by the adapter when present.\n */\n metadata?: { [key: string]: unknown } | null\n}\n\n// ---------------------------------------------------------------------------\n// XaiClientLike — structural interface (no `openai` dependency)\n// ---------------------------------------------------------------------------\n\n/**\n * Structural interface for the `openai` SDK's `client.responses` surface\n * the adapter uses.\n *\n * Satisfied by:\n * - The real `openai` `OpenAI` client (via `buildXaiClient` wrapper), pointed\n * at xAI's `https://api.x.ai/v1` base URL.\n * - `FakeXaiClient` from `@gullabs/testing`.\n */\nexport interface XaiClientLike {\n responses: {\n create(\n params: XaiResponseCreateParams,\n options?: { signal?: AbortSignal },\n ): Promise<XaiResponseShape>\n }\n}\n\n// ---------------------------------------------------------------------------\n// buildXaiClient — imports the real `openai` SDK\n// ---------------------------------------------------------------------------\n\n/**\n * Build a real `openai`-SDK-backed client from AuthMaterial, pointed at\n * xAI's Responses API endpoint.\n *\n * Only API-key authentication is supported.\n *\n * @param auth - API key credentials ({ apiKey }).\n */\nexport async function buildXaiClient(auth: AuthMaterial): Promise<XaiClientLike> {\n // Resolve and validate auth BEFORE importing the SDK so auth-rejection\n // tests never need to touch the real `openai` module (and thus never hit\n // the network).\n const apiKey = requireApiKey(auth)\n\n const { default: OpenAI } = await import('openai')\n\n const client = new OpenAI({\n apiKey,\n baseURL: 'https://api.x.ai/v1',\n maxRetries: 0,\n })\n\n return {\n responses: {\n async create(\n params: XaiResponseCreateParams,\n options?: { signal?: AbortSignal },\n ): Promise<XaiResponseShape> {\n // Cast needed: our structural types are subsets of the real SDK types,\n // and the real SDK's types do not exactly match xAI's actual response\n // shape (see module doc comment).\n return (\n client.responses.create as unknown as (\n p: unknown,\n o?: { signal?: AbortSignal },\n ) => Promise<XaiResponseShape>\n )(params, options)\n },\n },\n }\n}\n","/**\n * xaiAdapter — @gullabs/xai xAI Grok provider adapter.\n *\n * Pure request⇄response mapping over the xAI Responses API (via\n * XaiClientLike). Never persists, never computes cost, never loops.\n *\n * @module\n */\n\nimport { LlmError, classifyError, assertNever } from '@gullabs/core'\nimport type {\n ProviderAdapter,\n ResolvedRequest,\n AdapterCtx,\n AdapterResult,\n Usage,\n Warning,\n FinishReason,\n JsonValue,\n AuthMaterial,\n Part,\n} from '@gullabs/core'\nimport { buildXaiClient } from './client.js'\nimport type {\n XaiClientLike,\n XaiResponseCreateParams,\n XaiInputItem,\n XaiInputContentPart,\n XaiResponseShape,\n XaiUsageShape,\n XaiMessageOutputItem,\n} from './client.js'\n\n// ---------------------------------------------------------------------------\n// Small object-shape helpers (mirrors google adapter's local helpers)\n// ---------------------------------------------------------------------------\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction badXaiRequest(message: string): LlmError {\n return new LlmError(message, { kind: 'bad_request', retryable: false })\n}\n\n// ---------------------------------------------------------------------------\n// Vision / media mapping\n// ---------------------------------------------------------------------------\n\nconst ALLOWED_XAI_IMAGE_MIME_TYPES = new Set(['image/jpeg', 'image/jpg', 'image/png'])\n\n/** 20 MiB, xAI's documented inline-image size ceiling. */\nconst MAX_XAI_INLINE_IMAGE_BYTES = 20 * 1024 * 1024\n\n/**\n * Map a single {@link Part} to its xAI Responses API input-content-part\n * equivalent.\n *\n * - `text` → `{ type: 'input_text', text }`\n * - `inline-media` → `{ type: 'input_image', image_url: 'data:<mime>;base64,<data>' }`;\n * rejected (`bad_request`) when `mimeType` is not jpg/jpeg/png, or when the\n * decoded payload exceeds 20 MiB.\n * - `file-uri` → `{ type: 'input_image', image_url: uri }` ONLY when\n * `uri` is a public `http(s)://` URL AND `mimeType` is an allowed image\n * type — a provider-hosted URI from another provider (e.g. Gemini's Files\n * API `https://generativelanguage.googleapis.com/...` — which itself\n * happens to be `https://`, but is not dereferenceable by xAI) is not\n * portable and callers should not reuse `FileUriPart` cross-provider.\n * - `file-ref` → `{ type: 'input_file', file_id }` for xAI Files uploads.\n * Attaching files implicitly enables xAI's `attachment_search` agentic tool\n * (extra tool billing may apply). Empty `fileId` → `bad_request`.\n *\n * Note: xAI enforces an undocumented server-side minimum image size\n * (observed ~8px/side, ~512 total px). This adapter does not pre-validate\n * pixel dimensions — a too-small image surfaces as a `bad_request` from the\n * live API, classified normally by {@link classifyXaiError}.\n */\nfunction mapPart(p: Part): XaiInputContentPart {\n switch (p.kind) {\n case 'text':\n return { type: 'input_text', text: p.text }\n\n case 'inline-media': {\n if (!ALLOWED_XAI_IMAGE_MIME_TYPES.has(p.mimeType)) {\n throw badXaiRequest(\n `xAI vision only supports image/jpeg and image/png; got mimeType \"${p.mimeType}\".`,\n )\n }\n const byteLength = Buffer.from(p.data, 'base64').length\n if (byteLength > MAX_XAI_INLINE_IMAGE_BYTES) {\n throw badXaiRequest(\n `xAI inline images must be at most 20 MiB; got ${byteLength} bytes.`,\n )\n }\n return { type: 'input_image', image_url: `data:${p.mimeType};base64,${p.data}` }\n }\n\n case 'file-uri': {\n const isPublicHttpUrl = p.uri.startsWith('http://') || p.uri.startsWith('https://')\n const isAllowedImageType = ALLOWED_XAI_IMAGE_MIME_TYPES.has(p.mimeType)\n if (!isPublicHttpUrl || !isAllowedImageType) {\n throw badXaiRequest(\n `xAI only accepts public http(s) image URLs via FileUriPart; got scheme of \"${p.uri}\" / mimeType \"${p.mimeType}\".`,\n )\n }\n // Reject known foreign provider hosts even when scheme+mime look valid.\n if (\n p.uri.includes('generativelanguage.googleapis.com') ||\n p.uri.includes('googleapis.com/v1beta/files')\n ) {\n throw badXaiRequest(\n `xAI cannot dereference Gemini/Google Files URIs via FileUriPart; upload to xAI Files and use FileRefPart (file_id) instead. Got \"${p.uri}\".`,\n )\n }\n return { type: 'input_image', image_url: p.uri }\n }\n\n case 'file-ref': {\n if (typeof p.fileId !== 'string' || p.fileId.trim() === '') {\n throw badXaiRequest('FileRefPart.fileId must be a non-empty string.')\n }\n return { type: 'input_file', file_id: p.fileId }\n }\n\n default:\n return assertNever(p)\n }\n}\n\n// ---------------------------------------------------------------------------\n// providerOptions.xai → explicit allowlisted mapping\n// ---------------------------------------------------------------------------\n\nfunction mapXaiProviderOptions(\n xaiOpts: unknown,\n model: string,\n): { promptCacheKey?: string } {\n if (xaiOpts === undefined) {\n return {}\n }\n\n if (!isPlainRecord(xaiOpts)) {\n throw badXaiRequest(`providerOptions.xai must be an object for model \"${model}\".`)\n }\n\n const unknownKeys = Object.keys(xaiOpts).filter((key) => key !== 'promptCacheKey')\n if (unknownKeys.length > 0) {\n throw badXaiRequest(\n `providerOptions.xai contains unsupported keys [${unknownKeys.join(\n ', ',\n )}] for model \"${model}\". Allowed keys: promptCacheKey.`,\n )\n }\n\n const mapped: { promptCacheKey?: string } = {}\n if (xaiOpts['promptCacheKey'] !== undefined) {\n if (\n typeof xaiOpts['promptCacheKey'] !== 'string' ||\n xaiOpts['promptCacheKey'].length === 0\n ) {\n throw badXaiRequest(\n `providerOptions.xai.promptCacheKey must be a non-empty string for model \"${model}\".`,\n )\n }\n mapped.promptCacheKey = xaiOpts['promptCacheKey']\n }\n\n return mapped\n}\n\n// ---------------------------------------------------------------------------\n// FinishReason mapping (xAI status/incomplete_details → our FinishReason)\n// ---------------------------------------------------------------------------\n\nfunction mapFinishReason(response: XaiResponseShape): FinishReason {\n if (response.status === 'completed') {\n return 'stop'\n }\n if (\n response.status === 'incomplete' &&\n response.incomplete_details?.reason === 'max_output_tokens'\n ) {\n return 'length'\n }\n // Any other status/incomplete_details combination without fixture\n // evidence (or a status we don't recognize) maps to 'other' — the core\n // FinishReason union is closed to these four values.\n return 'other'\n}\n\n// ---------------------------------------------------------------------------\n// Usage mapping — #1 correctness rule\n// ---------------------------------------------------------------------------\n\n/**\n * Usage fields already mapped into canonical {@link Usage} counters — never\n * duplicated into `details` under their raw xAI names.\n */\nconst CANONICALLY_MAPPED_USAGE_KEYS = new Set([\n 'input_tokens',\n 'output_tokens',\n 'total_tokens',\n])\n\n/**\n * Map xAI's `usage` object to our {@link Usage} type.\n *\n * **GROSS convention (ADR-004):**\n * - `usage.input_tokens` is already GROSS (includes cached) → `inputTokens`.\n * - `usage.output_tokens` is already GROSS (includes reasoning) → `outputTokens`.\n * Unlike Gemini, xAI does not require us to sum sub-fields into the gross\n * total — the top-level fields are already gross.\n *\n * **xAI extras** (captured, not billed in `computeXaiCost`): every additional\n * NUMERIC top-level usage field (`num_sources_used`,\n * `num_server_side_tools_used` — e.g. after implicit `attachment_search` when\n * files are attached — `cost_in_usd_ticks`, and anything xAI adds later) is\n * surfaced into `details` under its raw name for host visibility. Non-numeric\n * extras (e.g. `context_details`) belong to `AdapterResult.providerMetadata`\n * (see the adapter) and the full raw payload always lands in `Usage.raw`\n * verbatim. Tool invocation fees are not yet a separate Cost lane.\n */\nfunction mapUsage(usage: XaiUsageShape): Usage {\n const inputTokens = usage.input_tokens\n const outputTokens = usage.output_tokens\n const cachedInputTokens = usage.input_tokens_details?.cached_tokens\n const thinkingTokens = usage.output_tokens_details?.reasoning_tokens\n const totalTokens = usage.total_tokens\n\n // Canonical details keys: input, output, cached, thinking.\n const details: Record<string, number> = {\n input: inputTokens,\n output: outputTokens,\n ...(cachedInputTokens !== undefined ? { cached: cachedInputTokens } : {}),\n ...(thinkingTokens !== undefined ? { thinking: thinkingTokens } : {}),\n }\n\n // Numeric xAI extras — surfaced under their raw names.\n for (const [key, value] of Object.entries(usage)) {\n if (typeof value === 'number' && !CANONICALLY_MAPPED_USAGE_KEYS.has(key)) {\n details[key] = value\n }\n }\n\n const raw: JsonValue = usage as unknown as { [k: string]: JsonValue }\n\n const result: Usage = {\n inputTokens,\n outputTokens,\n details,\n raw,\n ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),\n ...(thinkingTokens !== undefined ? { thinkingTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n }\n\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Structured-body auth-failure signature, taken verbatim from the recorded\n * live error taxonomy (`__fixtures__/09-error-taxonomy.json`,\n * `invalid_api_key` case): HTTP 400 with body\n * `{ code: 'invalid-argument', error: 'Incorrect API key provided. …' }`.\n *\n * The body `code` (`'invalid-argument'`) is NOT discriminating — xAI uses it\n * for genuinely bad requests too (e.g. `Model not found: grok-99`) — and the\n * `openai` SDK's `APIError` drops it (it hoists only the body's `error`\n * field onto `.error`). The exact message PREFIX xAI emits for bad keys is\n * therefore the signature.\n */\nconst XAI_AUTH_ERROR_MESSAGE_PREFIX = 'Incorrect API key provided'\n\n/**\n * Extract the STRUCTURED error-body text from a raw thrown value.\n *\n * Consulted shapes (both are parsed-body fields, never free-form\n * `Error.message` text):\n * - `rawErr.error` as a string — the `openai` SDK's `APIError` hoists the\n * response body's `error` field onto `.error`, which for xAI's\n * `{ code, error }` bodies is the message string itself.\n * - `rawErr.error` as an object — the full parsed body (test fakes and\n * hand-rolled throws of the fixture shape `{ status, error: <body> }`);\n * its `error` (xAI) or `message` (OpenAI-style) string field is read.\n *\n * Free-form `Error.message` is deliberately ignored so arbitrary request\n * content echoed into a message (e.g. a schema-validation error quoting user\n * text that mentions \"api key\") can never influence classification.\n */\nfunction extractXaiErrorBodyText(rawErr: unknown): string | undefined {\n if (rawErr === null || typeof rawErr !== 'object') {\n return undefined\n }\n const body = (rawErr as Record<string, unknown>)['error']\n if (typeof body === 'string') {\n return body\n }\n if (isPlainRecord(body)) {\n if (typeof body['error'] === 'string') {\n return body['error']\n }\n if (typeof body['message'] === 'string') {\n return body['message']\n }\n }\n return undefined\n}\n\n/** True iff the structured body matches xAI's recorded bad-API-key signature. */\nfunction isXaiAuthFailureBody(rawErr: unknown): boolean {\n const text = extractXaiErrorBodyText(rawErr)\n return text !== undefined && text.startsWith(XAI_AUTH_ERROR_MESSAGE_PREFIX)\n}\n\n/**\n * Message/errno signatures of a transport-level failure: the request never\n * reached xAI's servers (or the connection was severed mid-flight), so there\n * is no HTTP response for {@link classifyHttpStatus} to route by status.\n * Covers the `openai` SDK's own default message (`\"Connection error.\"`,\n * thrown by `APIConnectionError`) plus the Node/undici errno codes that\n * surface when the underlying `fetch` rejects before a response arrives.\n */\nconst XAI_TRANSPORT_ERROR_PATTERN =\n /connection error|econnreset|econnrefused|etimedout|eai_again|epipe|socket hang up|fetch failed/i\n\n/** True iff `err.message` or `err.code` matches a known transport-failure signature. */\nfunction matchesXaiTransportSignature(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n if (XAI_TRANSPORT_ERROR_PATTERN.test(err.message)) return true\n const code = (err as { code?: unknown }).code\n return typeof code === 'string' && XAI_TRANSPORT_ERROR_PATTERN.test(code)\n}\n\n/**\n * True iff `rawErr` is (or wraps) a transport-level connection failure —\n * observed live killing Temporal-orchestrated audit runs when the `openai`\n * SDK's `APIConnectionError` (\"Connection error.\") fell through\n * `classifyError`'s generic HTTP-status classification to `kind: 'unknown',\n * retryable: false`.\n *\n * Detection order:\n * 1. `rawErr.constructor.name` matches the `openai` SDK's\n * `APIConnectionError` / `APIConnectionTimeoutError` classes. Matched by\n * constructor name rather than `instanceof` so this file does not need a\n * runtime import of `openai` — per `client.ts`, that package is imported\n * ONLY in `buildXaiClient`, keeping unit tests independent of the real\n * SDK.\n * 2. `rawErr.message` / `rawErr.code` matches a known transport-failure\n * signature (handles the SDK's default message text directly, without\n * relying on the class name surviving minification).\n * 3. A wrapped `rawErr.cause` matches either of the above —\n * `APIConnectionError` attaches the underlying fetch/socket error as\n * `.cause`.\n */\nfunction isXaiTransportError(rawErr: unknown): boolean {\n if (!(rawErr instanceof Error)) return false\n\n const ctorName = rawErr.constructor.name\n if (ctorName === 'APIConnectionError' || ctorName === 'APIConnectionTimeoutError') {\n return true\n }\n\n if (matchesXaiTransportSignature(rawErr)) return true\n\n const cause = (rawErr as { cause?: unknown }).cause\n if (cause instanceof Error) {\n const causeCtorName = cause.constructor.name\n if (\n causeCtorName === 'APIConnectionError' ||\n causeCtorName === 'APIConnectionTimeoutError'\n ) {\n return true\n }\n if (matchesXaiTransportSignature(cause)) return true\n }\n\n return false\n}\n\n/**\n * Classify a raw error thrown from the xAI Responses API call into a typed\n * {@link LlmError}.\n *\n * xAI's Responses API returns HTTP 400 (NOT 401) for an invalid API key, so\n * generic {@link classifyHttpStatus}-based classification (which maps 400 →\n * `bad_request`) is wrong for this one case. This function special-cases it:\n * a 400 response whose STRUCTURED parsed body matches the exact recorded\n * xAI auth-failure signature (`code: 'invalid-argument'` AND message prefix\n * `\"Incorrect API key provided\"` — see fixture 09) is reclassified as\n * `invalid_auth`. Free-form `Error.message` text is never scanned, so a 400\n * whose message merely *mentions* an API key (e.g. schema validation echoing\n * user content) stays `bad_request`. When the structured body is unavailable\n * or unparseable, classification falls through to the status-based\n * `classifyError` from `@gullabs/core`.\n *\n * A second special case widens `classifyError`'s generic fallback: when the\n * base classification lands on `kind: 'unknown'` (no HTTP status to route\n * by) AND the raw error matches a known transport-failure signature (see\n * {@link isXaiTransportError}), it is reclassified `kind: 'server',\n * retryable: true` — the same \"provider fault, not caller fault, safe to\n * retry\" bucket this adapter's `countTokens` path already uses for\n * provider-side failures with no HTTP status. A connection that never\n * reached xAI is not the caller's fault and is safe to retry; it must never\n * be surfaced as the non-retryable `unknown` kind, which Temporal treats as\n * fatal and uses to kill the run outright.\n */\nexport function classifyXaiError(rawErr: unknown): LlmError {\n if (rawErr instanceof LlmError) {\n return rawErr\n }\n\n const base = classifyError(rawErr)\n\n if (base.httpStatus === 400 && isXaiAuthFailureBody(rawErr)) {\n return new LlmError(base.message, {\n kind: 'invalid_auth',\n retryable: false,\n httpStatus: base.httpStatus,\n provider: 'xai',\n cause: base.cause ?? rawErr,\n })\n }\n\n if (base.kind === 'unknown' && isXaiTransportError(rawErr)) {\n return new LlmError(base.message, {\n kind: 'server',\n retryable: true,\n provider: 'xai',\n cause: base.cause ?? rawErr,\n })\n }\n\n return new LlmError(base.message, {\n kind: base.kind,\n retryable: base.retryable,\n ...(base.httpStatus !== undefined ? { httpStatus: base.httpStatus } : {}),\n ...(base.retryAfterMs !== undefined ? { retryAfterMs: base.retryAfterMs } : {}),\n provider: 'xai',\n cause: base.cause ?? rawErr,\n })\n}\n\n// ---------------------------------------------------------------------------\n// Adapter options\n// ---------------------------------------------------------------------------\n\nexport interface XaiAdapterOptions {\n /**\n * Inject a pre-built client (real or fake).\n * When omitted, `buildXaiClient` is called with `ctx.auth` at call time,\n * inside the classified try/catch so any construction failure is wrapped\n * as a typed `LlmError`.\n */\n client?: XaiClientLike\n /**\n * @internal Testing-only.\n *\n * Override the default `buildXaiClient` factory. Allows unit tests to\n * simulate construction failures without importing the real `openai` SDK.\n * Never set this in production code. Mirrors `GeminiAdapterOptions._clientFactory`.\n */\n _clientFactory?: (auth: AuthMaterial) => XaiClientLike | Promise<XaiClientLike>\n}\n\n// ---------------------------------------------------------------------------\n// xaiAdapter factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create an xAI Grok provider adapter (Responses API).\n *\n * @param opts.client - Optional pre-built client (e.g. for testing).\n */\nexport function xaiAdapter(opts?: XaiAdapterOptions): ProviderAdapter {\n return {\n id: 'xai',\n\n async run(req: ResolvedRequest, ctx: AdapterCtx): Promise<AdapterResult> {\n if (req.provider !== 'xai') {\n throw new LlmError(\n `xaiAdapter received a request for provider \"${req.provider}\", expected \"xai\".`,\n { kind: 'bad_request', retryable: false },\n )\n }\n\n const warnings: Warning[] = []\n const model = req.model\n const genConfig = req.config\n\n // ------------------------------------------------------------------\n // 1. Map messages → input\n // ------------------------------------------------------------------\n const input: XaiInputItem[] = req.messages.map((msg) => ({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.parts.map(mapPart),\n }))\n\n // ------------------------------------------------------------------\n // 2. Build request params\n // ------------------------------------------------------------------\n const params: XaiResponseCreateParams = {\n model,\n input,\n store: false,\n }\n\n if (req.system !== undefined) {\n params.instructions = req.system\n }\n\n // Sampling — forwarded verbatim, no clamping (schema enforces bounds\n // upstream of the adapter).\n if (genConfig.temperature !== undefined) {\n params.temperature = genConfig.temperature\n }\n if (genConfig.topP !== undefined) {\n params.top_p = genConfig.topP\n }\n\n // max_output_tokens — no artificial ceiling; truncation surfaces as\n // finishReason:'length', not an error (see mapFinishReason).\n if (genConfig.maxOutputTokens !== undefined) {\n params.max_output_tokens = genConfig.maxOutputTokens\n }\n\n // serviceTier — xAI has no service-tier concept for grok-4.5.\n if (genConfig.serviceTier !== undefined) {\n throw badXaiRequest(\n `serviceTier is not supported for xai models (got \"${genConfig.serviceTier}\").`,\n )\n }\n\n // ------------------------------------------------------------------\n // 3. Reasoning → { effort: 'low' | 'high' }\n //\n // grok-4.5 admits ONLY 'low' | 'high' (default 'high'); 'none' and\n // 'medium' are rejected by the live API. budgetTokens is not\n // supported (level-style reasoning, no token budget). includeThoughts\n // is a no-op for xAI — reasoning summaries come back unconditionally\n // whenever reasoning ran, so reasoningText is always surfaced below\n // regardless of this flag; we do not throw on it since it is a\n // legitimate ReasoningIntent field this provider simply doesn't need.\n // ------------------------------------------------------------------\n const reasoning = genConfig.reasoning\n if (reasoning !== undefined) {\n if (reasoning.budgetTokens !== undefined) {\n throw badXaiRequest(\n `reasoning.budgetTokens is not supported for model \"${model}\" (xAI uses effort-level reasoning, not token budgets); use reasoning.effort instead.`,\n )\n }\n\n if (reasoning.effort !== undefined) {\n const effort = reasoning.effort\n if (effort !== 'low' && effort !== 'high') {\n throw badXaiRequest(\n `reasoning.effort \"${effort}\" is not supported for xai model \"${model}\" (only \"low\" and \"high\" are admitted).`,\n )\n }\n const admitted = req.modelDescriptor?.capabilities?.admittedReasoningEfforts\n if (admitted !== undefined && !admitted.includes(effort)) {\n throw badXaiRequest(\n `reasoning.effort \"${effort}\" is not supported for xai model \"${model}\".`,\n )\n }\n params.reasoning = { effort }\n }\n }\n\n // ------------------------------------------------------------------\n // 4. Structured output → text.format (NOT response_format)\n // ------------------------------------------------------------------\n const structuredOutputRequested = req.outputJsonSchema !== undefined\n if (structuredOutputRequested) {\n const schema = req.outputJsonSchema\n const name =\n isPlainRecord(schema) &&\n typeof schema['title'] === 'string' &&\n schema['title'].length > 0\n ? schema['title']\n : 'structured_output'\n params.text = {\n format: { type: 'json_schema', name, schema, strict: true },\n }\n }\n\n // ------------------------------------------------------------------\n // 5. providerOptions.xai → prompt_cache_key\n // ------------------------------------------------------------------\n const xaiProviderConfig = mapXaiProviderOptions(\n genConfig.providerOptions?.['xai'],\n model,\n )\n if (xaiProviderConfig.promptCacheKey !== undefined) {\n params.prompt_cache_key = xaiProviderConfig.promptCacheKey\n }\n\n // ------------------------------------------------------------------\n // 6. Client construction + SDK call — inside the classifier so ANY\n // failure (including bad auth construction) is rethrown as a typed\n // LlmError(provider:'xai').\n // ------------------------------------------------------------------\n let response: XaiResponseShape\n try {\n const buildClient = opts?._clientFactory ?? buildXaiClient\n const client: XaiClientLike =\n opts?.client !== undefined ? opts.client : await buildClient(ctx.auth)\n ctx.logger.debug(\n { model, configKeys: Object.keys(params) },\n 'llm.adapter.dispatch',\n )\n response = await client.responses.create(\n params,\n ctx.signal !== undefined ? { signal: ctx.signal } : undefined,\n )\n } catch (rawErr) {\n throw classifyXaiError(rawErr)\n }\n\n // ------------------------------------------------------------------\n // 7. Map response\n // ------------------------------------------------------------------\n let text = ''\n let reasoningText: string | undefined\n const messageItems: XaiMessageOutputItem[] = []\n\n for (const item of response.output) {\n if (item.type === 'message') {\n messageItems.push(item)\n } else {\n const joined = item.summary.map((s) => s.text).join('')\n if (joined.length > 0) {\n reasoningText = (reasoningText ?? '') + joined\n }\n }\n }\n\n // xAI's Responses API convention: when multiple `type: 'message'`\n // output items are present, the LAST one is the response — earlier\n // ones are superseded (observed live in strict json_schema mode,\n // grok-4.5, reasoning effort high: two complete-JSON message items in\n // one response). Concatenating across items corrupts the payload\n // (e.g. two JSON documents back-to-back); joining `output_text` parts\n // WITHIN a single message item is still correct (segmentation, not\n // duplication).\n if (messageItems.length > 0) {\n const lastMessage = messageItems[messageItems.length - 1] as XaiMessageOutputItem\n text = lastMessage.content.map((part) => part.text).join('')\n\n if (messageItems.length > 1) {\n warnings.push({\n type: 'other',\n message: `xai: response contained ${messageItems.length} message output items; using the last one and discarding ${\n messageItems.length - 1\n } earlier message item(s).`,\n })\n }\n }\n\n // Parse structured output (JSON text → rawStructured).\n let rawStructured: unknown\n if (structuredOutputRequested && text.length > 0) {\n try {\n rawStructured = JSON.parse(text)\n } catch {\n // Core reports unparsed via absence of rawStructured; callers own\n // validation/retry policy (ADR-009).\n }\n }\n\n const usage = mapUsage(response.usage)\n const finishReason = mapFinishReason(response)\n\n // Response-level metadata → providerMetadata: usage.context_details\n // (non-numeric usage extra) and response.metadata (e.g.\n // system_fingerprint). Numeric usage extras live in usage.details; the\n // full raw usage payload is already in usage.raw.\n const providerMeta: { [k: string]: JsonValue } = {}\n const contextDetails = response.usage['context_details']\n if (isPlainRecord(contextDetails)) {\n providerMeta['context_details'] = contextDetails as unknown as JsonValue\n }\n if (isPlainRecord(response.metadata)) {\n providerMeta['metadata'] = response.metadata as unknown as JsonValue\n }\n\n const result: AdapterResult = {\n model: response.model,\n usage,\n warnings,\n finishReason,\n responseId: response.id,\n ...(text.length > 0 ? { text } : {}),\n ...(reasoningText !== undefined ? { reasoningText } : {}),\n ...(rawStructured !== undefined ? { rawStructured } : {}),\n ...(Object.keys(providerMeta).length > 0\n ? { providerMetadata: providerMeta }\n : {}),\n }\n\n return result\n },\n }\n}\n","/**\n * XaiFileStore — thin wrapper over the xAI Files REST API.\n *\n * Upload / get / list / delete / content over injectable `fetch`.\n * No READY-state polling (upload returns metadata immediately).\n * No ambient credential reads — auth is injected at construction.\n *\n * @module\n */\n\nimport type { AuthMaterial, JsonValue, Logger } from '@gullabs/core'\nimport { LlmError, classifyError, redactSecrets } from '@gullabs/core'\n\nimport { requireApiKey } from './client.js'\nimport { classifyXaiError } from './adapter.js'\n\n// ---------------------------------------------------------------------------\n// Public constants\n// ---------------------------------------------------------------------------\n\n/** xAI minimum `expires_after` (1 hour), inclusive. */\nexport const XAI_FILE_TTL_MIN_SECONDS = 3_600\n\n/** xAI maximum `expires_after` (30 days), inclusive. */\nexport const XAI_FILE_TTL_MAX_SECONDS = 2_592_000\n\n/**\n * Conservative max upload size (48 MiB). Managing-files docs say ~48 MB;\n * upload REST says 50 MB — we take the lower bound.\n */\nexport const XAI_FILE_MAX_BYTES = 48 * 1024 * 1024\n\n/** Default Files API base (includes `/v1`). */\nexport const XAI_FILES_DEFAULT_BASE_URL = 'https://api.x.ai/v1'\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** A handle to a file stored in the xAI Files API. */\nexport interface XaiFileHandle {\n /** File id, e.g. `\"file_a128090d-…\"`. Use as `FileRefPart.fileId`. */\n id: string\n filename?: string\n bytes?: number\n purpose?: string\n createdAt?: Date\n /** Present when the file has a TTL; key omitted when permanent / unknown. */\n expiresAt?: Date\n /** Full vendor JSON object for forward-compat (P2 raw lane). */\n raw?: { [k: string]: JsonValue }\n}\n\nexport interface XaiFileUploadInput {\n data: Uint8Array | Blob\n filename: string\n mimeType?: string\n /**\n * TTL in seconds. Must be an integer in\n * `[XAI_FILE_TTL_MIN_SECONDS, XAI_FILE_TTL_MAX_SECONDS]` when set.\n * Omit only for permanent storage (discouraged for ephemeral corpus).\n */\n expiresAfterSeconds?: number\n /** Default `\"assistants\"` (OpenAI SDK convention; xAI does not enforce). */\n purpose?: string\n}\n\nexport interface XaiFileListOptions {\n /** 1..100. Server default is 100 when omitted. */\n limit?: number\n order?: 'asc' | 'desc'\n sortBy?: 'created_at' | 'filename' | 'size'\n paginationToken?: string\n}\n\nexport interface XaiFileListResult {\n files: XaiFileHandle[]\n paginationToken?: string\n}\n\n/**\n * Options for {@link XaiFileStore.delete} / {@link XaiFileStore.deleteAll}.\n *\n * Default is fail-open (P5 side-effect style). Pass `failClosed: true` when\n * the host gates durable state (e.g. `released_at`) on known delete success.\n */\nexport interface FileDeleteOptions {\n signal?: AbortSignal\n /**\n * When true, non-404 failures throw typed `LlmError`.\n * When false/omitted, non-404 failures invoke `onDeleteError` and resolve.\n * HTTP 404 is success in both modes (idempotent).\n */\n failClosed?: boolean\n}\n\nexport interface XaiFileStoreOptions {\n auth: AuthMaterial\n /** Default {@link XAI_FILES_DEFAULT_BASE_URL}. */\n baseUrl?: string\n /** Injectable fetch for tests. Default: global `fetch`. */\n fetch?: typeof fetch\n /**\n * Delete failures that are NOT already-gone (404).\n * Default: `logger.error` or `console.error` with a redacted message.\n */\n onDeleteError?: (fileId: string, err: unknown) => void\n logger?: Logger\n /** Injectable clock for tests. Default: `Date.now`. */\n now?: () => number\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype VendorFileObject = {\n id?: unknown\n filename?: unknown\n bytes?: unknown\n purpose?: unknown\n created_at?: unknown\n expires_at?: unknown\n object?: unknown\n [k: string]: unknown\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction badRequest(message: string): LlmError {\n return new LlmError(message, {\n kind: 'bad_request',\n retryable: false,\n provider: 'xai',\n })\n}\n\nfunction resolveFileId(fileIdOrHandle: string | Pick<XaiFileHandle, 'id'>): string {\n if (typeof fileIdOrHandle === 'string') {\n return fileIdOrHandle\n }\n return fileIdOrHandle.id\n}\n\nfunction unixSecondsToDate(value: unknown): Date | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return undefined\n }\n return new Date(value * 1000)\n}\n\nfunction makeHandle(raw: VendorFileObject): XaiFileHandle {\n if (typeof raw.id !== 'string' || raw.id.length === 0) {\n throw new LlmError('File response missing required field (id)', {\n kind: 'server',\n retryable: false,\n provider: 'xai',\n })\n }\n\n const handle: XaiFileHandle = {\n id: raw.id,\n raw: raw as { [k: string]: JsonValue },\n }\n\n if (typeof raw.filename === 'string' && raw.filename.length > 0) {\n handle.filename = raw.filename\n }\n if (typeof raw.bytes === 'number' && Number.isFinite(raw.bytes)) {\n handle.bytes = raw.bytes\n }\n if (typeof raw.purpose === 'string') {\n handle.purpose = raw.purpose\n }\n\n const createdAt = unixSecondsToDate(raw.created_at)\n if (createdAt !== undefined) {\n handle.createdAt = createdAt\n }\n\n // expires_at is null for permanent files — omit the key entirely (Google parity).\n if (raw.expires_at !== null && raw.expires_at !== undefined) {\n const expiresAt = unixSecondsToDate(raw.expires_at)\n if (expiresAt !== undefined) {\n handle.expiresAt = expiresAt\n }\n }\n\n return handle\n}\n\nfunction byteLengthOf(data: Uint8Array | Blob): number {\n return data instanceof Uint8Array ? data.byteLength : data.size\n}\n\nfunction toBlob(data: Uint8Array | Blob, mimeType: string | undefined): Blob {\n if (data instanceof Blob) {\n return data\n }\n // Copy into a plain ArrayBuffer-backed view for BlobPart typing.\n const copy = Uint8Array.from(data)\n return mimeType !== undefined && mimeType.length > 0\n ? new Blob([copy], { type: mimeType })\n : new Blob([copy])\n}\n\n/**\n * Shape a non-2xx fetch response into a throw value that\n * {@link classifyXaiError} / {@link classifyError} understand:\n * - `.status` for HTTP routing\n * - `.error` for structured body (auth-body detection)\n */\n/**\n * Error shaped for {@link classifyError} / {@link classifyXaiError}:\n * numeric `.status` for HTTP routing, `.error` for structured body text.\n */\nclass XaiFilesHttpError extends Error {\n readonly status: number\n readonly error: unknown\n\n constructor(status: number, message: string, errorBody: unknown) {\n super(message)\n this.name = 'XaiFilesHttpError'\n this.status = status\n this.error = errorBody\n }\n}\n\nasync function throwHttpFailure(res: Response): Promise<never> {\n const status = res.status\n let bodyText = ''\n try {\n bodyText = await res.text()\n } catch {\n bodyText = ''\n }\n\n let parsed: unknown = bodyText\n if (bodyText.length > 0) {\n try {\n parsed = JSON.parse(bodyText) as unknown\n } catch {\n parsed = bodyText\n }\n }\n\n let message = `xAI Files API HTTP ${status}`\n if (typeof parsed === 'string' && parsed.length > 0) {\n message = parsed\n } else if (isPlainRecord(parsed) && typeof parsed['error'] === 'string') {\n message = parsed['error']\n }\n\n throw new XaiFilesHttpError(status, message, parsed)\n}\n\nfunction isNotFoundError(err: unknown): boolean {\n if (err instanceof LlmError && err.httpStatus === 404) {\n return true\n }\n if (typeof err === 'object' && err !== null) {\n const status = (err as { status?: unknown }).status\n if (status === 404) return true\n const httpStatus = (err as { httpStatus?: unknown }).httpStatus\n if (httpStatus === 404) return true\n }\n return false\n}\n\nfunction notFoundError(fileId: string, operation: string): LlmError {\n return new LlmError(`xAI file not found during ${operation}: \"${fileId}\"`, {\n kind: 'bad_request',\n retryable: false,\n httpStatus: 404,\n provider: 'xai',\n })\n}\n\nfunction maybeZdrHint(message: string): string {\n if (\n /zero\\s*data\\s*retention|\\bzdr\\b|files?\\s+(api\\s+)?(disabled|unavailable|not supported)/i.test(\n message,\n )\n ) {\n return `${message} (xAI Zero Data Retention blocks new file uploads and file_id attachments for this team.)`\n }\n return message\n}\n\n/** Prefer structured body text / explicit message over generic `HTTP NNN`. */\nfunction extractThrownMessage(raw: unknown): string | undefined {\n if (raw === null || typeof raw !== 'object') return undefined\n const obj = raw as Record<string, unknown>\n if (typeof obj['message'] === 'string' && obj['message'].length > 0) {\n return obj['message']\n }\n const err = obj['error']\n if (typeof err === 'string' && err.length > 0) return err\n if (typeof err === 'object' && err !== null) {\n const nested = err as Record<string, unknown>\n if (typeof nested['error'] === 'string' && nested['error'].length > 0) {\n return nested['error']\n }\n if (typeof nested['message'] === 'string' && nested['message'].length > 0) {\n return nested['message']\n }\n }\n return undefined\n}\n\nfunction classifyStoreError(raw: unknown): LlmError {\n if (raw instanceof LlmError) {\n return raw\n }\n const classified = classifyXaiError(raw)\n const bodyMessage = extractThrownMessage(raw)\n // classifyError maps plain `{ status }` throws to generic \"HTTP NNN\" — prefer\n // the structured body text we attached in throwHttpFailure when present.\n const baseMessage =\n bodyMessage !== undefined &&\n (classified.message.startsWith('HTTP ') || classified.message.length === 0)\n ? bodyMessage\n : classified.message\n const hinted = maybeZdrHint(baseMessage)\n if (\n hinted === classified.message &&\n classified.provider === 'xai' &&\n bodyMessage === undefined\n ) {\n return classified\n }\n return new LlmError(hinted, {\n kind: classified.kind,\n retryable: classified.retryable,\n ...(classified.httpStatus !== undefined ? { httpStatus: classified.httpStatus } : {}),\n ...(classified.retryAfterMs !== undefined\n ? { retryAfterMs: classified.retryAfterMs }\n : {}),\n provider: 'xai',\n cause: classified.cause ?? raw,\n })\n}\n\n// ---------------------------------------------------------------------------\n// XaiFileStore\n// ---------------------------------------------------------------------------\n\n/**\n * **Auth snapshot note:** captures `AuthMaterial` at construction and holds\n * the resolved API key for the store lifetime. Correct for static API keys.\n * Refreshable credentials would need a resolver callback (see GoogleFileStore\n * / ADR-020).\n */\nexport class XaiFileStore {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n private readonly onDeleteError: (fileId: string, err: unknown) => void\n private readonly logger: Logger | undefined\n\n constructor(opts: XaiFileStoreOptions) {\n this.apiKey = requireApiKey(opts.auth)\n this.baseUrl = (opts.baseUrl ?? XAI_FILES_DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.fetchImpl = opts.fetch ?? fetch\n this.logger = opts.logger\n this.onDeleteError =\n opts.onDeleteError ??\n ((fileId, err) => {\n const message = redactSecrets(classifyError(err).message)\n if (this.logger !== undefined) {\n this.logger.error({ fileId, error: message }, 'xai.file.delete.failed')\n } else {\n console.error(`[XaiFileStore] delete failed for \"${fileId}\":`, message)\n }\n })\n }\n\n private authHeaders(): Headers {\n const headers = new Headers()\n headers.set('Authorization', `Bearer ${this.apiKey}`)\n return headers\n }\n\n private filesUrl(path = ''): string {\n if (path.length === 0) return `${this.baseUrl}/files`\n return `${this.baseUrl}/files/${path.replace(/^\\//, '')}`\n }\n\n /** Build RequestInit without writing `signal: undefined` (exactOptionalPropertyTypes). */\n private requestInit(\n method: string,\n opts?: { body?: FormData; signal?: AbortSignal },\n ): RequestInit {\n const init: RequestInit = {\n method,\n headers: this.authHeaders(),\n }\n if (opts?.body !== undefined) {\n init.body = opts.body\n }\n if (opts?.signal !== undefined) {\n init.signal = opts.signal\n }\n return init\n }\n\n /**\n * Upload bytes to xAI Files. Returns immediately with metadata (no poll).\n *\n * Multipart field order is load-bearing: `expires_after` then `purpose`\n * then `file` — reversing order yields HTTP 400 from xAI.\n */\n async upload(input: XaiFileUploadInput, signal?: AbortSignal): Promise<XaiFileHandle> {\n if (typeof input.filename !== 'string' || input.filename.trim() === '') {\n throw badRequest('XaiFileUploadInput.filename must be a non-empty string.')\n }\n\n const size = byteLengthOf(input.data)\n if (size > XAI_FILE_MAX_BYTES) {\n throw badRequest(\n `xAI file uploads must be at most ${XAI_FILE_MAX_BYTES} bytes (48 MiB); got ${size}.`,\n )\n }\n\n if (input.expiresAfterSeconds !== undefined) {\n const ttl = input.expiresAfterSeconds\n if (\n typeof ttl !== 'number' ||\n !Number.isInteger(ttl) ||\n ttl < XAI_FILE_TTL_MIN_SECONDS ||\n ttl > XAI_FILE_TTL_MAX_SECONDS\n ) {\n throw badRequest(\n `expiresAfterSeconds must be an integer in [${XAI_FILE_TTL_MIN_SECONDS}, ${XAI_FILE_TTL_MAX_SECONDS}]; got ${String(ttl)}.`,\n )\n }\n }\n\n const purpose = input.purpose ?? 'assistants'\n const form = new FormData()\n\n // Order: expires_after → purpose → file (xAI multipart requirement).\n if (input.expiresAfterSeconds !== undefined) {\n form.append('expires_after', String(input.expiresAfterSeconds))\n }\n form.append('purpose', purpose)\n form.append('file', toBlob(input.data, input.mimeType), input.filename)\n\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(),\n this.requestInit('POST', {\n body: form,\n ...(signal !== undefined ? { signal } : {}),\n }),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file upload aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n let json: unknown\n try {\n json = await res.json()\n } catch (e) {\n throw new LlmError('xAI file upload returned non-JSON body', {\n kind: 'server',\n retryable: false,\n provider: 'xai',\n cause: e,\n })\n }\n\n return makeHandle(json as VendorFileObject)\n }\n\n async get(fileId: string, signal?: AbortSignal): Promise<XaiFileHandle> {\n if (typeof fileId !== 'string' || fileId.trim() === '') {\n throw badRequest('fileId must be a non-empty string.')\n }\n\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(fileId),\n this.requestInit('GET', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file get aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (res.status === 404) {\n throw notFoundError(fileId, 'get')\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n const json = (await res.json()) as VendorFileObject\n return makeHandle(json)\n }\n\n async list(\n opts: XaiFileListOptions = {},\n signal?: AbortSignal,\n ): Promise<XaiFileListResult> {\n if (opts.limit !== undefined) {\n if (\n typeof opts.limit !== 'number' ||\n !Number.isInteger(opts.limit) ||\n opts.limit < 1 ||\n opts.limit > 100\n ) {\n throw badRequest('list.limit must be an integer in [1, 100].')\n }\n }\n\n const params = new URLSearchParams()\n if (opts.limit !== undefined) params.set('limit', String(opts.limit))\n if (opts.order !== undefined) params.set('order', opts.order)\n if (opts.sortBy !== undefined) params.set('sort_by', opts.sortBy)\n if (opts.paginationToken !== undefined) {\n params.set('pagination_token', opts.paginationToken)\n }\n\n const qs = params.toString()\n const url = qs.length > 0 ? `${this.filesUrl()}?${qs}` : this.filesUrl()\n\n let res: Response\n try {\n res = await this.fetchImpl(\n url,\n this.requestInit('GET', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file list aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n const json = (await res.json()) as {\n data?: VendorFileObject[]\n pagination_token?: string\n }\n const files = Array.isArray(json.data) ? json.data.map((f) => makeHandle(f)) : []\n const result: XaiFileListResult = { files }\n if (typeof json.pagination_token === 'string' && json.pagination_token.length > 0) {\n result.paginationToken = json.pagination_token\n }\n return result\n }\n\n /**\n * Delete a file. Idempotent: HTTP 404 → success.\n *\n * Default (`failClosed` omitted/false): non-404 errors go to `onDeleteError`\n * and resolve (P5 fail-open). With `failClosed: true`, non-404 errors throw\n * typed `LlmError` and `onDeleteError` is not called.\n *\n * Empty/blank ids always throw `bad_request` (caller fault).\n */\n async delete(\n fileIdOrHandle: string | Pick<XaiFileHandle, 'id'>,\n opts?: FileDeleteOptions,\n ): Promise<void> {\n const fileId = resolveFileId(fileIdOrHandle)\n if (typeof fileId !== 'string' || fileId.trim() === '') {\n throw badRequest('fileId must be a non-empty string.')\n }\n\n const failClosed = opts?.failClosed === true\n const signal = opts?.signal\n\n try {\n const res = await this.fetchImpl(\n this.filesUrl(fileId),\n this.requestInit('DELETE', signal !== undefined ? { signal } : {}),\n )\n\n if (res.status === 404) {\n return\n }\n\n if (!res.ok) {\n await throwHttpFailure(res)\n }\n } catch (err) {\n if (isNotFoundError(err)) {\n return\n }\n\n // Abort during fetch: surface as aborted LlmError through the same path.\n const classified =\n signal?.aborted === true && !(err instanceof LlmError)\n ? new LlmError('xAI file delete aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n cause: err,\n })\n : classifyStoreError(err)\n\n if (failClosed) {\n throw classified\n }\n this.onDeleteError(fileId, classified)\n }\n }\n\n /**\n * Delete many files.\n *\n * Fail-open (default): `Promise.allSettled` — each failure → `onDeleteError`.\n * Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are\n * not cancelled (partial deletes may already have succeeded at the provider).\n * Prefer per-id delete + host DB mark when gating durable release state.\n */\n async deleteAll(\n ids: ReadonlyArray<string | Pick<XaiFileHandle, 'id'>>,\n opts?: FileDeleteOptions,\n ): Promise<void> {\n if (opts?.failClosed === true) {\n await Promise.all(ids.map((id) => this.delete(id, opts)))\n return\n }\n await Promise.allSettled(ids.map((id) => this.delete(id, opts)))\n }\n\n /** Download raw file bytes. */\n async getContent(fileId: string, signal?: AbortSignal): Promise<Uint8Array> {\n if (typeof fileId !== 'string' || fileId.trim() === '') {\n throw badRequest('fileId must be a non-empty string.')\n }\n\n let res: Response\n try {\n res = await this.fetchImpl(\n this.filesUrl(`${fileId}/content`),\n this.requestInit('GET', signal !== undefined ? { signal } : {}),\n )\n } catch (e) {\n if (signal?.aborted === true) {\n throw new LlmError('xAI file content download aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'xai',\n })\n }\n throw classifyStoreError(e)\n }\n\n if (res.status === 404) {\n throw notFoundError(fileId, 'getContent')\n }\n\n if (!res.ok) {\n try {\n await throwHttpFailure(res)\n } catch (e) {\n throw classifyStoreError(e)\n }\n }\n\n const buf = await res.arrayBuffer()\n return new Uint8Array(buf)\n }\n}\n","/**\n * Strict Zod config schema for xAI's `grok-4.5` model.\n *\n * Mirrors `@gullabs/core`'s `packages/core/src/model-config/*.ts` doc-density\n * style, but is a single self-contained `z.strictObject` — unlike Gemini's\n * schemas, xai has no service-tier branching (no `z.union` of tier variants\n * needed), no `topK`, and only a single reasoning-effort union (`'low'|'high'`).\n *\n * @module\n */\n\nimport { z } from 'zod'\n\nexport const Grok45ConfigSchema = z\n .strictObject({\n temperature: z.number().optional().meta({\n title: 'Temperature',\n description: 'Sampling temperature forwarded verbatim to grok-4.5.',\n }),\n topP: z.number().optional().meta({\n title: 'Top P',\n description: 'Nucleus sampling parameter forwarded verbatim to grok-4.5.',\n }),\n maxOutputTokens: z\n .number()\n .int()\n .positive()\n .optional()\n .meta({\n title: 'Max Output Tokens',\n description:\n 'Maximum output token cap for grok-4.5. No artificial ceiling — xAI ' +\n 'accepts arbitrarily large values (live-verified); truncation surfaces ' +\n \"as finishReason:'length', not an error.\",\n }),\n reasoning: z\n .strictObject({\n effort: z.enum(['low', 'high']).meta({\n title: 'Reasoning Effort',\n description:\n 'Reasoning effort for grok-4.5. Only \"low\" and \"high\" are admitted ' +\n '(live-verified); \"none\"/\"medium\"/\"xhigh\" are rejected by the live API.',\n }),\n })\n .optional()\n .meta({\n title: 'Reasoning',\n description:\n 'grok-4.5 effort-level reasoning configuration. No budgetTokens field — ' +\n 'xAI uses level-style reasoning, not token budgets.',\n }),\n timeoutMs: z.number().int().positive().optional().meta({\n title: 'Timeout',\n description: 'Logical request timeout in milliseconds.',\n }),\n providerOptions: z\n .strictObject({\n xai: z\n .strictObject({\n promptCacheKey: z\n .string()\n .min(1)\n .optional()\n .meta({\n title: 'Prompt Cache Key',\n description:\n 'xAI conversation-routing cache key — maps to Responses API ' +\n '`prompt_cache_key`.',\n }),\n })\n .optional()\n .meta({\n title: 'xAI Provider Options',\n description: 'Allowlisted xAI provider options for grok-4.5.',\n }),\n })\n .optional()\n .meta({\n title: 'Provider Options',\n description: 'Provider-specific options accepted for grok-4.5.',\n }),\n })\n .meta({\n title: 'Grok45Config',\n description:\n 'Strict Responses API config for model grok-4.5. Level reasoning ' +\n '(low/high only), tunable sampling, no service tiers, structured output, ' +\n 'vision, priced.',\n examples: [{ reasoning: { effort: 'high' } }],\n })\n","/**\n * Model descriptor + registry for @gullabs/xai.\n *\n * v1 ships exactly one model: `grok-4.5` (canonical id only — the\n * `grok-4.5-latest` / `grok-build-latest` aliases visible in xAI's\n * `/v1/models` listing are intentionally NOT registered as separate\n * descriptors; reject-don't-map, callers must use `grok-4.5` verbatim).\n *\n * @module\n */\n\nimport type { ModelDescriptor, ModelRegistry } from '@gullabs/core'\nimport {\n createModelRegistry,\n toConfigJsonSchema,\n zodToStandardSchema,\n} from '@gullabs/core'\n\nimport { Grok45ConfigSchema } from './model-config/grok-4-5.js'\n\nexport { Grok45ConfigSchema } from './model-config/grok-4-5.js'\n\nexport const grok45ModelDescriptor: ModelDescriptor = {\n model: 'grok-4.5',\n provider: 'xai',\n pricingFamily: 'grok-4.5',\n capabilities: {\n reasoning: true,\n reasoningApi: 'level',\n admittedReasoningEfforts: ['low', 'high'],\n structuredOutput: true,\n nativeStructuredOutput: true,\n vision: true,\n audioInput: false,\n sampling: 'tunable',\n caching: { explicit: false, minTokens: 0 },\n grounding: false,\n // No serviceTiers key — xai has no service-tier concept.\n },\n configSchema: Grok45ConfigSchema,\n configJsonSchema: toConfigJsonSchema(Grok45ConfigSchema),\n validateConfig: zodToStandardSchema(Grok45ConfigSchema),\n}\n\n/** Every model descriptor `@gullabs/xai` contributes. v1 ships only grok-4.5. */\nexport const xaiModelDescriptors: ModelDescriptor[] = [grok45ModelDescriptor]\n\nexport const xaiRegistry: ModelRegistry = createModelRegistry(xaiModelDescriptors)\n","/**\n * xAI pricing snapshot + cost computation for @gullabs/xai.\n *\n * All rates are in **micro-USD per million tokens** (µUSD/M), matching\n * `@gullabs/core`'s `ModelRates` convention exactly: `cost_µUSD = N *\n * ratePerM / 1_000_000`.\n *\n * This is a SELF-CONTAINED, xai-owned reimplementation — it does NOT import\n * core's Gemini-specific `computeCost`/`GEMINI_PRICING`/`geminiPricingSource`\n * (those are Gemini-only). `PricingSource` is provider-scoped by contract\n * (see `packages/core/src/ports.ts`); this module is xai's own.\n *\n * **Long-context tier.** grok-4.5 charges a premium when the GROSS input\n * token count exceeds 200,000 (`long_context_threshold` in xAI's\n * `/v1/models` listing). Selected by `inputTokens` (incl. cached), not by\n * billable input — mirrors core's `selectRates` convention exactly (strictly\n * greater than 200,000).\n *\n * **Service tiers.** xAI has no service-tier concept for grok-4.5 — there is\n * no `TIER_FACTOR`-equivalent here. `price()`'s `tier` param is accepted for\n * `PricingSource` structural conformance but any *defined* tier is treated\n * as unrecognized → unpriced (reject-don't-map), mirroring core's own\n * defensive stance for an unrecognized tier. `undefined` (no tier requested,\n * the only value xAI adapters ever pass — `xaiAdapter` rejects `serviceTier`\n * upstream) prices normally.\n *\n * **Conversion factor.** xAI's `/v1/models` raw `*_token_price` fields are\n * in hundred-thousandths of a dollar per token (i.e. divide the raw integer\n * by 10,000 to get USD per million tokens): e.g. `grok-4.5`'s raw\n * `prompt_text_token_price: 20000` ÷ 10,000 = $2.00/M, which matches the\n * confirmed live-verified figure.\n *\n * Verified against `/v1/models` fixture captured 2026-07-09 (see\n * `docs/provider-plugins-and-xai-grok-4-5-plan.md` and the live-verification\n * fixture directory referenced in the commit-3 task brief).\n *\n * @module\n */\n\nimport type { Cost, PricingSource, Usage } from '@gullabs/core'\n\n/** Identifies this pricing snapshot — bump the date when rates change. */\nexport const xaiPricingVersion = 'xai-2026-07-09' as const\n\n/**\n * Per-model rate entry (all values in µUSD per million tokens).\n *\n * `gt200k` (when present) applies when GROSS input tokens > 200,000.\n */\nexport interface XaiModelRates {\n /** µUSD per million input tokens (billable = gross − cached). */\n inputPerM: number\n /** µUSD per million cache-read tokens. */\n cachedPerM: number\n /** µUSD per million output tokens (reasoning tokens are folded in). */\n outputPerM: number\n /** Optional high-tier rates for long-context (GROSS input > 200k). */\n gt200k?: {\n inputPerM: number\n cachedPerM: number\n outputPerM: number\n }\n}\n\n/**\n * Frozen xAI pricing snapshot (per-1M in µUSD).\n *\n * Keys are EXACT canonical model identifiers — no prefix or alias matching.\n * xAI aliases (e.g. `grok-4.5-latest`, `grok-build-latest`) are deliberately\n * NOT registered/priced (reject-don't-map): callers must use the canonical\n * id; anything else resolves to the unpriced path.\n */\nexport const XAI_PRICING: Readonly<Record<string, XaiModelRates>> = Object.freeze({\n // ── grok-4.5 ── $2.00/$6.00 (≤200k), $4.00/$12.00 (>200k); cached $0.50/$1.00\n 'grok-4.5': {\n inputPerM: 2_000_000,\n cachedPerM: 500_000,\n outputPerM: 6_000_000,\n gt200k: {\n inputPerM: 4_000_000,\n cachedPerM: 1_000_000,\n outputPerM: 12_000_000,\n },\n },\n})\n\nconst LONG_CONTEXT_THRESHOLD = 200_000\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Look up rates for a model — EXACT match only.\n *\n * Deliberately no prefix matching (unlike core's Gemini lookup): xAI aliases\n * such as `grok-4.5-latest` would otherwise prefix-match `grok-4.5` and\n * silently reintroduce the alias behavior the model registry rejects. An id\n * that is not an exact `XAI_PRICING` key is unpriced.\n */\nfunction lookupRates(model: string): XaiModelRates | undefined {\n return XAI_PRICING[model]\n}\n\n/**\n * Select the applicable rate set for a model given the GROSS input token\n * count. When a model has a `gt200k` tier, that tier's rates apply when\n * `grossInputTokens` is **strictly greater than** 200,000.\n */\nfunction selectRates(\n rates: XaiModelRates,\n grossInputTokens: number,\n): { inputPerM: number; cachedPerM: number; outputPerM: number } {\n if (rates.gt200k !== undefined && grossInputTokens > LONG_CONTEXT_THRESHOLD) {\n return rates.gt200k\n }\n return {\n inputPerM: rates.inputPerM,\n cachedPerM: rates.cachedPerM,\n outputPerM: rates.outputPerM,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the cost of an xAI LLM call given a model name and usage data.\n *\n * Pure function — no side effects, always returns a well-formed {@link Cost}.\n *\n * **Algorithm** (mirrors `@gullabs/core`'s `computeCost` exactly, xai-owned):\n * 1. Look up rates for `model`; if not found, return an unpriced `Cost`\n * (`microUsd: null`) naming the model.\n * 2. A defined `tier` is always unpriced (xai has no tiers; reject-don't-map).\n * `undefined` prices normally.\n * 3. Select base vs. `>200k` long-context rates from GROSS `inputTokens`.\n * 4. Billable input = `inputTokens − (cachedInputTokens ?? 0)`, clamped to 0.\n * 5. Round each component (input, cached, output) independently to the\n * nearest integer micro-USD.\n * 6. `microUsd` is the sum of the three components — guarantees\n * `details.input + details.cached + details.output === microUsd` exactly.\n */\nexport function computeXaiCost(model: string, usage: Usage, tier?: string): Cost {\n const rates = lookupRates(model)\n\n if (rates === undefined) {\n return {\n microUsd: null,\n usd: null,\n pricingVersion: xaiPricingVersion,\n confidence: 'estimated',\n details: { input: 0, cached: 0, output: 0 },\n unpricedReason: `Unknown model \"${model}\"; no pricing entry found.`,\n }\n }\n\n if (tier !== undefined) {\n return {\n microUsd: null,\n usd: null,\n pricingVersion: xaiPricingVersion,\n confidence: 'estimated',\n details: { input: 0, cached: 0, output: 0 },\n unpricedReason: `Unknown service tier \"${tier}\"; xai has no service tiers, refusing to guess a pricing multiplier.`,\n }\n }\n\n const base = selectRates(rates, usage.inputTokens)\n\n const cached = usage.cachedInputTokens ?? 0\n const billableInput = Math.max(0, usage.inputTokens - cached)\n\n const inputCost = Math.round((billableInput * base.inputPerM) / 1_000_000)\n const cachedCost = Math.round((cached * base.cachedPerM) / 1_000_000)\n const outputCost = Math.round((usage.outputTokens * base.outputPerM) / 1_000_000)\n\n const microUsd = inputCost + cachedCost + outputCost\n\n return {\n microUsd,\n usd: microUsd / 1_000_000,\n pricingVersion: xaiPricingVersion,\n confidence: 'exact',\n details: {\n input: inputCost,\n cached: cachedCost,\n output: outputCost,\n },\n }\n}\n\n/**\n * Factory that returns the **xai-scoped** {@link PricingSource} port\n * implementation backed by {@link XAI_PRICING}.\n *\n * @example\n * ```ts\n * import { xaiPricingSource } from '@gullabs/xai'\n *\n * const pricing = xaiPricingSource()\n * const cost = pricing.price('grok-4.5', usage)\n * ```\n */\nexport function xaiPricingSource(): PricingSource {\n return {\n version: xaiPricingVersion,\n price(model: string, usage: Usage, tier?: string): Cost {\n return computeXaiCost(model, usage, tier)\n },\n hasModel(model: string): boolean {\n return lookupRates(model) !== undefined\n },\n listModels(): readonly string[] {\n return Object.keys(XAI_PRICING)\n },\n }\n}\n","/**\n * `xaiProvider` — {@link ProviderPlugin} factory for @gullabs/xai.\n *\n * Bundles the xAI Grok adapter, the `grok-4.5` model descriptor, and the\n * xai pricing source into a single plugin for {@link composeProviders}.\n *\n * @module\n */\n\nimport type { ProviderPlugin } from '@gullabs/core'\n\nimport { xaiAdapter } from './adapter.js'\nimport type { XaiAdapterOptions } from './adapter.js'\nimport { xaiModelDescriptors } from './models.js'\nimport { xaiPricingSource } from './pricing.js'\n\n/**\n * Create a {@link ProviderPlugin} for the xAI Grok provider.\n *\n * @param opts - Forwarded to {@link xaiAdapter}.\n * @returns A plugin bundling the xAI adapter, the `grok-4.5` model\n * descriptor, and the built-in xai pricing source.\n *\n * @example\n * ```ts\n * import { createClient, composeProviders } from '@gullabs/core'\n * import { xaiProvider } from '@gullabs/xai'\n *\n * const client = createClient({\n * ...composeProviders([xaiProvider()]),\n * })\n * ```\n */\nexport function xaiProvider(opts?: XaiAdapterOptions): ProviderPlugin {\n return {\n adapter: xaiAdapter(opts),\n modelDescriptors: xaiModelDescriptors,\n pricingSource: xaiPricingSource(),\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gullabs/xai",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "xAI Grok provider adapter for any-llm — Responses API, reasoning, structured output, vision.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -27,11 +27,11 @@
27
27
  "@gullabs/core": "0.11.0"
28
28
  },
29
29
  "peerDependencies": {
30
- "openai": "^6"
30
+ "openai": "^6 || ^7"
31
31
  },
32
32
  "devDependencies": {
33
- "openai": "^6",
34
- "@gullabs/testing": "0.4.3"
33
+ "openai": "^7.4.0",
34
+ "@gullabs/testing": "0.5.0"
35
35
  },
36
36
  "engines": {
37
37
  "node": ">=20.9.0"