zidane 5.12.2 → 5.12.4
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/README.md +6 -5
- package/dist/{agent-Dt3mALPV.d.ts → agent-CVTAoYS0.d.ts} +33 -2
- package/dist/agent-CVTAoYS0.d.ts.map +1 -0
- package/dist/chat/pure.d.ts +3 -3
- package/dist/chat.d.ts +6 -6
- package/dist/chat.js +2 -2
- package/dist/contexts/e2b.d.ts +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/eval.js +1 -1
- package/dist/{headless-BBwdL006.js → headless-DM5JeUiE.js} +3 -3
- package/dist/{headless-BBwdL006.js.map → headless-DM5JeUiE.js.map} +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/{index-Do7IZGW5.d.ts → index-BuIaw3r3.d.ts} +2 -2
- package/dist/{index-Do7IZGW5.d.ts.map → index-BuIaw3r3.d.ts.map} +1 -1
- package/dist/{index-BDRh3kup.d.ts → index-Gin_mFQJ.d.ts} +2 -2
- package/dist/{index-BDRh3kup.d.ts.map → index-Gin_mFQJ.d.ts.map} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7 -7
- package/dist/{logger-C2E41UWq.d.ts → logger-CYtWKlBF.d.ts} +2 -2
- package/dist/{logger-C2E41UWq.d.ts.map → logger-CYtWKlBF.d.ts.map} +1 -1
- package/dist/{login-LF-inV4T.js → login-94imBv_3.js} +2 -2
- package/dist/{login-LF-inV4T.js.map → login-94imBv_3.js.map} +1 -1
- package/dist/{mcp-DeJ9280K.js → mcp-Bnnrt_Ps.js} +5 -2
- package/dist/{mcp-DeJ9280K.js.map → mcp-Bnnrt_Ps.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +1 -1
- package/dist/output/stream-json.d.ts +2 -2
- package/dist/output/stream-json.js +1 -1
- package/dist/output/terminal.d.ts +2 -2
- package/dist/{presets-sIs25Per.js → presets-BorC0fVx.js} +2 -2
- package/dist/{presets-sIs25Per.js.map → presets-BorC0fVx.js.map} +1 -1
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +1 -1
- package/dist/{providers-psx2_0LB.js → providers-C_zClj1S.js} +338 -8
- package/dist/providers-C_zClj1S.js.map +1 -0
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +2 -2
- package/dist/restate.d.ts +1 -1
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/skills.d.ts +2 -2
- package/dist/{tool-formatters-COmtAwgF.d.ts → tool-formatters-Chwpa2Ix.d.ts} +2 -2
- package/dist/tool-formatters-Chwpa2Ix.d.ts.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/{tools-Dfvr9bBs.js → tools-BlMV33N1.js} +46 -3
- package/dist/tools-BlMV33N1.js.map +1 -0
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-BtOrrlmN.js → transcript-anchors-D2zBge6D.js} +5 -5
- package/dist/{transcript-anchors-BtOrrlmN.js.map → transcript-anchors-D2zBge6D.js.map} +1 -1
- package/dist/{transcript-anchors-DLa8m9_E.d.ts → transcript-anchors-LMTpzn6r.d.ts} +5 -5
- package/dist/{transcript-anchors-DLa8m9_E.d.ts.map → transcript-anchors-LMTpzn6r.d.ts.map} +1 -1
- package/dist/tui.d.ts +3 -3
- package/dist/tui.js +5 -5
- package/dist/{turn-operations-ifKg5muR.d.ts → turn-operations-DyOAiVE3.d.ts} +3 -3
- package/dist/{turn-operations-ifKg5muR.d.ts.map → turn-operations-DyOAiVE3.d.ts.map} +1 -1
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/agent-Dt3mALPV.d.ts.map +0 -1
- package/dist/providers-psx2_0LB.js.map +0 -1
- package/dist/tool-formatters-COmtAwgF.d.ts.map +0 -1
- package/dist/tools-Dfvr9bBs.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers-C_zClj1S.js","names":["BASE_URL","getApiKey","BASE_URL","getApiKey","BASE_URL","getApiKey","DEFAULT_MODEL","getApiKey","DEFAULT_MODEL"],"sources":["../src/chat/anthropic-models.ts","../src/atomic-write.ts","../src/providers/oauth.ts","../src/providers/anthropic.ts","../src/providers/arcee.ts","../src/providers/baseten.ts","../src/providers/cerebras.ts","../src/chat/oauth-page/pkce.ts","../src/chat/oauth-page/cursor.ts","../src/providers/cursor.ts","../src/providers/local.ts","../src/providers/openai.ts","../src/providers/openrouter.ts","../src/chat/oauth-page/xai.ts","../src/providers/xai.ts"],"sourcesContent":["/**\n * Anthropic models not (yet) bundled in `@earendil-works/pi-ai`'s registry.\n *\n * pi-ai ships a static price/metadata registry that lags new Anthropic\n * releases by a dep bump. Until the bump lands, list freshly-shipped models\n * here so they show in the picker, expose the reasoning knob, and get an\n * accurate cost estimate. Entries are merged ahead of pi-ai's list in\n * {@link modelsForDescriptor} and de-duped by id, so once pi-ai catches up\n * the bundled entry simply wins.\n */\n\nimport type { ModelInfo, ModelOption } from './providers'\n\n/**\n * Anthropic \"fast mode\" — `speed: \"fast\"` on the Messages API. ~2.5× output\n * tokens/sec at a per-model price multiplier. Supported on Opus 4.6 / 4.7 / 4.8\n * only; the API errors if sent on any other model, so it's attached just to\n * those entries (see {@link FAST_MODE_OPTIONS}).\n *\n * The multiplier scales ALL rate components (input, output, and both cache\n * rates) uniformly: per Anthropic, \"prompt caching multipliers apply on top of\n * fast mode pricing\" across the full context window. Opus 4.8 is 2× ($5/$25 →\n * $10/$50); Opus 4.6 / 4.7 are a steeper 6× ($5/$25 → $30/$150).\n * See https://platform.claude.com/docs/en/build-with-claude/fast-mode.\n */\nexport const FAST_MODE_OPTION: ModelOption = {\n id: 'fast',\n label: 'Fast mode',\n description: '~2.5× faster output at premium pricing',\n costMultiplier: { input: 2, output: 2, cacheRead: 2, cacheWrite: 2 },\n}\n\nconst FAST_MODE_OPTION_LEGACY: ModelOption = {\n ...FAST_MODE_OPTION,\n description: '~2.5× faster output at 6× pricing',\n costMultiplier: { input: 6, output: 6, cacheRead: 6, cacheWrite: 6 },\n}\n\n/** Model ids that accept `speed: \"fast\"`, mapped to their fast-mode option. */\nexport const FAST_MODE_OPTIONS: Readonly<Record<string, ModelOption>> = {\n 'claude-opus-4-8': FAST_MODE_OPTION,\n 'claude-opus-4-7': FAST_MODE_OPTION_LEGACY,\n 'claude-opus-4-6': FAST_MODE_OPTION_LEGACY,\n}\n\n/**\n * The price multiplier to apply to a model's base rates when fast mode is\n * active, or `undefined` when the model has no fast-mode pricing (i.e. doesn't\n * support it). Mirrors {@link FAST_MODE_OPTIONS} — kept as a separate accessor\n * so the cost layer can stay decoupled from the picker-facing option objects.\n */\nexport function fastModeCostMultiplier(modelId: string): ModelOption['costMultiplier'] {\n return FAST_MODE_OPTIONS[modelId]?.costMultiplier\n}\n\n/**\n * Claude Fable 5 — GA 2026-06-09. Anthropic's most capable widely released\n * model: $10/$50 per MTok, 1M context, 128k output, adaptive thinking\n * (always on), vision. No fast-mode support (Opus 4.6/4.7/4.8 only).\n *\n * Claude Opus 4.8 — shipped 2026-05-28. Same price/context/output as Opus 4.7\n * ($5/$25 per MTok, 1M context, 128k output), adaptive thinking, vision.\n * See https://www.anthropic.com/news/claude-opus-4-8.\n *\n * Claude Mythos 5 is deliberately absent: it's invitation-only (Project\n * Glasswing), so it would be a dead picker entry for virtually all users.\n *\n * See https://platform.claude.com/docs/en/about-claude/models/overview.\n */\nexport const ANTHROPIC_EXTRA_MODELS: readonly ModelInfo[] = [\n {\n id: 'claude-fable-5',\n name: 'Claude Fable 5',\n reasoning: true,\n input: ['text', 'image'],\n cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 },\n contextWindow: 1_000_000,\n maxTokens: 128_000,\n provider: 'anthropic',\n },\n {\n id: 'claude-opus-4-8',\n name: 'Claude Opus 4.8',\n reasoning: true,\n input: ['text', 'image'],\n cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },\n contextWindow: 1_000_000,\n maxTokens: 128_000,\n provider: 'anthropic',\n options: [FAST_MODE_OPTION],\n },\n]\n","/**\n * Synchronous atomic file write helper.\n *\n * Used by the chat-layer state / safelist / credentials / keybindings writers\n * and the OAuth credentials store. The pattern is always the same: write to a\n * sibling temp file, fsync it, then `renameSync` over the target. `rename(2)`\n * is atomic on the same filesystem, so concurrent readers either see the\n * previous file or the new one — never a half-written intermediate. The fsync\n * before the rename ensures the temp file's bytes are on disk before it takes\n * the target's place (without it, a power loss shortly after rename can leave\n * a zero-length or partial target on some filesystems). The temp suffix folds\n * `process.pid` + a per-process monotonic counter so two writers — same\n * process or same-millisecond siblings — can't pick the same tmp path.\n *\n * `ensureDir` runs `mkdirSync(dirname(path), { recursive: true })` before\n * the write so callers don't have to repeat the boilerplate. `mode` is\n * forwarded to the file open (e.g. `0o600` for credentials files).\n */\n\nimport { Buffer } from 'node:buffer'\nimport { closeSync, fsyncSync, mkdirSync, openSync, renameSync, unlinkSync, writeSync } from 'node:fs'\nimport { mkdir, open, rename, rm } from 'node:fs/promises'\nimport { dirname } from 'node:path'\n\nexport interface AtomicWriteOptions {\n /** When set, create the parent directory recursively before writing. */\n ensureDir?: boolean\n /** Forwarded to the file open — typically `0o600` for credentials files. */\n mode?: number\n}\n\nlet tmpCounter = 0\n\nfunction nextTmpPath(path: string): string {\n tmpCounter = (tmpCounter + 1) % Number.MAX_SAFE_INTEGER\n return `${path}.${process.pid}.${tmpCounter.toString(36)}.tmp`\n}\n\n/**\n * Best-effort fsync of the directory containing `path`, so the rename\n * itself (the directory entry) is durable. Wrapped in try/catch: opening\n * a directory for fsync fails on some platforms (notably Windows) and\n * durability of the entry is a nice-to-have on top of the data fsync.\n */\nfunction fsyncDirSync(path: string): void {\n try {\n const fd = openSync(dirname(path), 'r')\n try {\n fsyncSync(fd)\n }\n finally {\n closeSync(fd)\n }\n }\n catch { /* platform doesn't support directory fsync */ }\n}\n\nexport function writeFileAtomic(\n path: string,\n contents: string,\n options: AtomicWriteOptions = {},\n): void {\n if (options.ensureDir)\n mkdirSync(dirname(path), { recursive: true })\n const tmp = nextTmpPath(path)\n try {\n const fd = openSync(tmp, 'w', options.mode)\n try {\n const buf = Buffer.from(contents, 'utf8')\n let offset = 0\n while (offset < buf.length)\n offset += writeSync(fd, buf, offset)\n // Flush data to disk BEFORE the rename — otherwise a crash after\n // rename could leave the target pointing at not-yet-persisted bytes.\n fsyncSync(fd)\n }\n finally {\n closeSync(fd)\n }\n renameSync(tmp, path)\n fsyncDirSync(path)\n }\n catch (err) {\n // Don't leak the temp file when the write or rename throws (disk full,\n // permission flip, target dir removed).\n try {\n unlinkSync(tmp)\n }\n catch { /* never created or already gone */ }\n throw err\n }\n}\n\n/**\n * Async variant of {@link writeFileAtomic} — same tmp-suffix, fsync and\n * cleanup-on-failure semantics over `node:fs/promises`. Used by writers\n * that already live on the async path (e.g. loop persistence blobs).\n */\nexport async function writeFileAtomicAsync(\n path: string,\n contents: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n if (options.ensureDir)\n await mkdir(dirname(path), { recursive: true })\n const tmp = nextTmpPath(path)\n try {\n const fh = await open(tmp, 'w', options.mode)\n try {\n await fh.writeFile(contents, 'utf8')\n await fh.sync()\n }\n finally {\n await fh.close()\n }\n await rename(tmp, path)\n try {\n const dh = await open(dirname(path), 'r')\n try {\n await dh.sync()\n }\n finally {\n await dh.close()\n }\n }\n catch { /* platform doesn't support directory fsync */ }\n }\n catch (err) {\n await rm(tmp, { force: true }).catch(() => {})\n throw err\n }\n}\n","import type { OAuthCredentials } from '@earendil-works/pi-ai/oauth'\nimport type { StreamCallbacks } from '.'\nimport type { OAuthRefreshHookContext } from '../types'\nimport { Buffer } from 'node:buffer'\nimport { existsSync, readFileSync, statSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { resolve } from 'node:path'\nimport { getOAuthApiKey } from '@earendil-works/pi-ai/oauth'\nimport { writeFileAtomic } from '../atomic-write'\nimport { errorMessage } from '../errors'\n\n/**\n * Resolve the creds-file path at call time rather than module-load time, so\n * env changes between import and first OAuth use (test suites, multi-project\n * CLIs) are honored.\n *\n * Order:\n * 1. `ZIDANE_CREDENTIALS_PATH` — explicit override. The TUI sets this at\n * launch to point at `<storageDir>/credentials.json` so the harness\n * providers find the same file the TUI manages.\n * 2. `~/.credentials.json` — home-anchored default.\n *\n * The historic `cwd/.credentials.json` fallback was deliberately dropped:\n * launching zidane inside an untrusted checkout would let that repo plant a\n * `.credentials.json` and become the credential source (and receive rotated\n * refresh tokens on the next refresh persist). Same trust model as the TUI's\n * legacy-file migration in `chat/credentials.ts`, which only honors the\n * home-anchored location. The only \"trusted\" cwd under that model is `$HOME`\n * itself — where the cwd-relative path resolves to `~/.credentials.json`\n * anyway, so anchoring at home preserves the legitimate legacy case.\n */\nexport function credentialsFilePath(): string {\n return process.env.ZIDANE_CREDENTIALS_PATH ?? resolve(homedir(), '.credentials.json')\n}\n\n/**\n * POSIX mode for credentials on disk. Read+write for the owner only — refresh\n * tokens and API keys leak if the file is world-readable on a shared box.\n * Ignored on Windows.\n */\nconst CREDENTIALS_FILE_MODE = 0o600\n\n/**\n * In-process mutex table keyed by provider id. Concurrent `resolveOAuthApiKey`\n * calls for the same provider (typical when a host fans out multiple streams\n * at once) coalesce onto a single refresh. Without this, N concurrent calls\n * each hit `getOAuthApiKey`, producing N writes to `.credentials.json` with\n * last-write-wins semantics — and, in worst-case interleaving, a corrupted\n * file.\n */\nconst refreshLocks = new Map<string, Promise<string>>()\n\nexport interface OAuthParams {\n apiKey?: string\n access?: string\n refresh?: string\n expires?: number\n}\n\n/**\n * Pull a complete `{ access, refresh, expires }` triple out of provider params\n * when (and only when) all three OAuth fields are present and well-typed.\n * Returns `undefined` for the static-api-key path. Shared by the OAuth-capable\n * providers so the runtime-credential guard can't drift between them.\n */\n/**\n * Whether a credential string is an OAuth *access token* rather than a real,\n * static API key. Anthropic OAuth tokens are prefixed `sk-ant-oat`; OpenAI\n * Codex OAuth access tokens are JWTs (`eyJ...`). Used to decide whether an\n * env-provided value can be refreshed (OAuth) or must be sent verbatim (API key).\n */\nexport function isOAuthAccessToken(value: string): boolean {\n return value.startsWith('sk-ant-oat') || isJwtLikeAccessToken(value)\n}\n\nfunction isJwtLikeAccessToken(value: string): boolean {\n const parts = value.split('.')\n if (parts.length !== 3 || !parts[0]?.startsWith('eyJ'))\n return false\n try {\n const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString('utf8')) as unknown\n return Boolean(header && typeof header === 'object' && 'alg' in header)\n }\n catch {\n return false\n }\n}\n\nexport function extractRuntimeCredentials(\n params?: OAuthParams,\n): { access: string, refresh: string, expires: number } | undefined {\n if (\n typeof params?.access === 'string'\n && typeof params.refresh === 'string'\n && typeof params.expires === 'number'\n ) {\n return { access: params.access, refresh: params.refresh, expires: params.expires }\n }\n return undefined\n}\n\nexport interface ResolveOAuthApiKeyOptions<TParams extends OAuthParams = OAuthParams> {\n provider: string\n providerId: string\n params?: TParams\n envKey?: string\n extraCredentialKeys?: (keyof TParams & string)[]\n missingError: string\n refreshError: (reason: string) => string\n readCredentials?: () => Record<string, OAuthCredentials | undefined>\n writeCredentials?: (credentials: Record<string, OAuthCredentials | undefined>) => void\n getOAuthApiKey?: typeof getOAuthApiKey\n}\n\n/**\n * Read the shared credentials file.\n *\n * Returns `{}` when the file is missing OR when the file exists but is corrupted\n * / not valid JSON. Corrupt-file tolerance is important: the refresh-then-persist\n * path below writes atomically, but older builds wrote in place and could have\n * truncated the file on a crash. Treating corruption as \"no stored creds\" lets\n * users re-auth without manually deleting the file.\n *\n * Supports two on-disk shapes:\n * 1. **Legacy** (untagged): `{ \"anthropic\": { access, refresh, expires, ... } }`\n * — written by older `bun run auth`.\n * 2. **New** (kind-tagged): `{ \"anthropic\": { kind: 'oauth', access, refresh, expires, ... } }`\n * — written by the TUI. Entries with `kind: 'apikey'` are skipped — those\n * reach providers via env vars set at TUI launch (see `applyApiKeyEnv`).\n */\nexport function readOAuthCredentials(): Record<string, OAuthCredentials | undefined> {\n const path = credentialsFilePath()\n if (!existsSync(path))\n return {}\n\n try {\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))\n return {}\n const result: Record<string, OAuthCredentials | undefined> = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n continue\n const v = value as Record<string, unknown>\n // New schema: explicit `kind` tag.\n if (v.kind === 'apikey')\n continue\n // Both new (`kind: 'oauth'`) and legacy (untagged) entries have `access`;\n // the harmless `kind` field is allowed by `OAuthCredentials`'s\n // `[key: string]: unknown` index signature. Validate the required\n // fields explicitly so the assignment doesn't need a double-cast.\n if (\n typeof v.access === 'string'\n && typeof v.refresh === 'string'\n && typeof v.expires === 'number'\n ) {\n result[key] = { ...v, access: v.access, refresh: v.refresh, expires: v.expires }\n }\n }\n return result\n }\n catch {\n return {}\n }\n}\n\n/**\n * Cross-process lockfile parameters for the credentials read-merge-write.\n * A holder normally completes in well under a millisecond (read + JSON merge\n * + atomic write of a tiny file), so the stale threshold is generous and the\n * total wait short — on timeout we proceed without the lock rather than fail\n * the refresh (degrades to the historic last-write-wins behavior).\n */\nconst CREDENTIALS_LOCK_STALE_MS = 5000\nconst CREDENTIALS_LOCK_RETRY_MS = 20\nconst CREDENTIALS_LOCK_MAX_WAIT_MS = 2000\n\n/** Synchronous sleep without spinning — works on Bun and Node main threads. */\nfunction sleepSync(ms: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)\n}\n\n/**\n * Best-effort exclusive lock via `O_EXCL` create of `<file>.lock`. Returns\n * `true` when the lock was acquired (caller must release), `false` on\n * timeout (caller proceeds unlocked — see threshold rationale above). Locks\n * older than {@link CREDENTIALS_LOCK_STALE_MS} are treated as leftovers from\n * a crashed process and broken.\n */\nfunction acquireCredentialsLock(lockPath: string): boolean {\n const deadline = Date.now() + CREDENTIALS_LOCK_MAX_WAIT_MS\n while (true) {\n try {\n writeFileSync(lockPath, String(process.pid), { flag: 'wx', mode: CREDENTIALS_FILE_MODE })\n return true\n }\n catch (err) {\n // Only EEXIST means \"lock held\" — anything else (EPERM, ENOENT for a\n // missing parent dir, read-only fs) won't resolve by waiting, so bail\n // immediately and let the subsequent write surface the real error.\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST')\n return false\n try {\n const age = Date.now() - statSync(lockPath).mtimeMs\n if (age > CREDENTIALS_LOCK_STALE_MS) {\n unlinkSync(lockPath)\n continue\n }\n }\n catch { /* lock vanished between create-fail and stat — retry */ }\n if (Date.now() >= deadline)\n return false\n sleepSync(CREDENTIALS_LOCK_RETRY_MS)\n }\n }\n}\n\nfunction releaseCredentialsLock(lockPath: string): void {\n try {\n unlinkSync(lockPath)\n }\n catch { /* already gone */ }\n}\n\n/**\n * Atomically write `.credentials.json` with mode 0o600.\n *\n * Writes to a sibling temp file first, then renames. `rename(2)` is atomic on\n * the same filesystem, so readers either see the old file or the new one —\n * never a half-written one. This matters when a host has multiple processes\n * pointed at the same creds file.\n *\n * Merges the incoming OAuth entries on top of the raw file contents so that\n * entries this layer doesn't manage (e.g. `kind: 'apikey'` from the TUI\n * wizard) survive an OAuth refresh cycle. Without this merge,\n * `readOAuthCredentials` filters those entries out, and a naive overwrite\n * would delete them.\n *\n * The read-merge-write runs under a best-effort cross-process lockfile\n * (`<file>.lock`) so two processes refreshing different providers at the\n * same moment can't drop each other's rotated refresh tokens. On lock\n * timeout the write proceeds unlocked (last-write-wins, the pre-lock\n * behavior) rather than failing the refresh.\n */\nexport function writeOAuthCredentials(credentials: Record<string, OAuthCredentials | undefined>) {\n const path = credentialsFilePath()\n const lockPath = `${path}.lock`\n const locked = acquireCredentialsLock(lockPath)\n\n try {\n let existing: Record<string, unknown> = {}\n try {\n if (existsSync(path)) {\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n existing = parsed as Record<string, unknown>\n }\n }\n catch { /* corrupt file — start fresh */ }\n\n const merged = { ...existing, ...credentials }\n // Remove keys explicitly set to undefined (provider was deleted).\n for (const [key, value] of Object.entries(merged)) {\n if (value === undefined)\n delete merged[key]\n }\n\n writeFileAtomic(path, JSON.stringify(merged, null, 2), { mode: CREDENTIALS_FILE_MODE })\n }\n finally {\n if (locked)\n releaseCredentialsLock(lockPath)\n }\n}\n\nexport function credentialsFromParams<TParams extends OAuthParams>(params?: TParams, extraKeys: (keyof TParams & string)[] = []): OAuthCredentials | undefined {\n if (typeof params?.access !== 'string' || typeof params.refresh !== 'string' || typeof params.expires !== 'number')\n return undefined\n\n const extras = Object.fromEntries(\n extraKeys\n .map(key => [key, params[key]])\n .filter(([, value]) => value !== undefined),\n )\n\n return {\n access: params.access,\n refresh: params.refresh,\n expires: params.expires,\n ...extras,\n }\n}\n\nexport async function resolveOAuthApiKey<TParams extends OAuthParams>(\n options: ResolveOAuthApiKeyOptions<TParams>,\n callbacks?: Pick<StreamCallbacks, 'onOAuthRefresh'>,\n): Promise<string> {\n if (typeof options.params?.apiKey === 'string')\n return options.params.apiKey\n\n const paramsCredentials = credentialsFromParams(options.params, options.extraCredentialKeys)\n if (paramsCredentials) {\n return await withRefreshLock(\n `params:${options.providerId}`,\n () => resolveCredentialSource('params', paramsCredentials),\n )\n }\n\n if (typeof options.params?.access === 'string')\n return options.params.access\n\n const readCredentials = options.readCredentials ?? readOAuthCredentials\n const writeCredentials = options.writeCredentials ?? writeOAuthCredentials\n\n // Env key handling. A real API key (e.g. `sk-ant-api…`) is used as-is. But an\n // OAuth *access token* (`sk-ant-oat…`) pasted into the API-key env var can't\n // be refreshed and will 401 once expired — so if refreshable OAuth creds for\n // this provider exist on disk, prefer those (they self-heal via refresh).\n const envValue = options.envKey ? process.env[options.envKey] : undefined\n if (envValue) {\n if (!isOAuthAccessToken(envValue))\n return envValue\n if (!readCredentials()[options.providerId])\n return envValue // no refreshable creds — fall back to the raw token\n return await withRefreshLock(`file:${options.providerId}`, async () => {\n // Re-read under the lock — a concurrent resolve may have rotated the\n // refresh token between the pre-check above and lock acquisition, and\n // refreshing with the stale token would invalidate the new one.\n const allCredentials = readCredentials()\n const stored = allCredentials[options.providerId]\n if (!stored)\n return envValue\n return await resolveCredentialSource('file', stored, allCredentials, writeCredentials)\n })\n }\n\n return await withRefreshLock(`file:${options.providerId}`, async () => {\n // Read under lock so we're always operating on the latest file state and\n // never interleave read/write against another concurrent resolve.\n const allCredentials = readCredentials()\n const storedCredentials = allCredentials[options.providerId]\n if (!storedCredentials)\n throw new Error(options.missingError)\n\n return await resolveCredentialSource('file', storedCredentials, allCredentials, writeCredentials)\n })\n\n async function resolveCredentialSource(\n source: OAuthRefreshHookContext['source'],\n current: OAuthCredentials,\n allCredentials?: Record<string, OAuthCredentials | undefined>,\n persistCredentials?: (credentials: Record<string, OAuthCredentials | undefined>) => void,\n ): Promise<string> {\n // Only the refresh call itself maps to `refreshError` — a throwing\n // persist or onOAuthRefresh hook after a SUCCESSFUL refresh must not be\n // misreported as a refresh failure, so those run outside the try.\n let result: Awaited<ReturnType<typeof getOAuthApiKey>>\n try {\n const refreshOAuthApiKey = options.getOAuthApiKey ?? getOAuthApiKey\n result = await refreshOAuthApiKey(options.providerId, { [options.providerId]: current } as Record<string, OAuthCredentials>)\n }\n catch (err) {\n throw new Error(options.refreshError(errorMessage(err)))\n }\n if (!result)\n throw new Error(options.refreshError(options.missingError))\n\n if (result.newCredentials !== current) {\n if (source === 'file' && allCredentials && persistCredentials) {\n allCredentials[options.providerId] = result.newCredentials\n persistCredentials(allCredentials)\n }\n\n await callbacks?.onOAuthRefresh?.({\n provider: options.provider,\n providerId: options.providerId,\n source,\n previousCredentials: { ...current },\n credentials: { ...result.newCredentials },\n })\n }\n\n return result.apiKey\n }\n}\n\n/**\n * Coalesce concurrent refresh calls onto a single in-flight promise per key.\n * The key combines the source (`params` vs `file`) and provider id, so a\n * per-agent param-only refresh does not starve a separate file-backed one.\n */\nasync function withRefreshLock(key: string, fn: () => Promise<string>): Promise<string> {\n const existing = refreshLocks.get(key)\n if (existing)\n return existing\n\n const task = (async () => {\n try {\n return await fn()\n }\n finally {\n refreshLocks.delete(key)\n }\n })()\n refreshLocks.set(key, task)\n return task\n}\n","// Type-only imports — erased at build time. Safe when the peer dep is not installed\n// at consume time; the types only need to resolve during Zidane's own build\n// (where `@anthropic-ai/sdk` is present as a devDependency).\nimport type Anthropic from '@anthropic-ai/sdk'\nimport type { Model } from '@anthropic-ai/sdk/resources'\nimport type { Provider, StreamCallbacks, ToolResult, ToolSpec, TurnResult } from '.'\nimport type { ClassifiedError } from '../errors'\nimport type { PromptPart, SessionContentBlock, SessionMessage, ThinkingLevel, TurnFinishReason } from '../types'\nimport type { OAuthParams } from './oauth'\nimport { fastModeCostMultiplier } from '../chat/anthropic-models'\nimport { classifyErrorPrelude, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError } from '../errors'\nimport { unsupportedMediaError } from '../prompt'\nimport { fromAnthropic, toAnthropic } from '../session/messages'\nimport { renderSystemForWire, splitSystemPrompt } from '../system-prompt'\nimport { fillEstimatedCost } from './cost'\nimport { extractRuntimeCredentials, readOAuthCredentials, resolveOAuthApiKey } from './oauth'\nimport { sanitizeToolSpecs } from './schema-sanitize'\n\ntype AnthropicCtor = typeof Anthropic\ntype AnthropicInstance = InstanceType<AnthropicCtor>\n\n// Lazy-loaded SDK class. `@anthropic-ai/sdk` is an OPTIONAL peer dependency — the\n// module is only imported when the anthropic provider actually needs to open a\n// connection, so installing-without-using-it remains free for consumers who route\n// through other providers (openrouter, cerebras, openaiCompat, openai).\nlet _sdkCtor: AnthropicCtor | null = null\n\nasync function loadAnthropicSdk(): Promise<AnthropicCtor> {\n if (_sdkCtor)\n return _sdkCtor\n try {\n const mod = await import('@anthropic-ai/sdk')\n _sdkCtor = mod.default as unknown as AnthropicCtor\n return _sdkCtor\n }\n catch (err) {\n throw new Error(\n 'The `anthropic` provider requires the `@anthropic-ai/sdk` package, which is an optional peer dependency. '\n + 'Install it with your package manager (e.g. `bun add @anthropic-ai/sdk`).',\n err instanceof Error ? { cause: err } : undefined,\n )\n }\n}\n\n/**\n * Server-side context-management config — the body of `context_management` on\n * the Messages API. Typed loosely (Record-of-unknown) so we don't pin a specific\n * SDK schema version: the v0.90 SDK does not yet type this field, but the wire\n * format is stable behind the `context-management-2025-06-27` beta.\n *\n * See: https://docs.anthropic.com/en/docs/build-with-claude/context-management\n */\nexport interface AnthropicContextManagement {\n edits?: Array<Record<string, unknown>>\n [key: string]: unknown\n}\n\nexport interface AnthropicParams extends OAuthParams {\n defaultModel?: string\n /**\n * Optional override for the Anthropic SDK base URL. Honored end-to-end — headers and\n * routing pass through to the forwarded host. Useful for proxies (e.g. corporate\n * gateways, internal router).\n */\n baseURL?: string\n /**\n * Additional `anthropic-beta` flags to opt into. Merged with the OAuth-path\n * defaults (`claude-code-20250219`, `oauth-2025-04-20`); duplicates are\n * de-duped. Examples:\n *\n * - `'context-management-2025-06-27'` — server-side context compaction\n * (token-accurate; pair with {@link AnthropicParams.contextManagement}).\n * - `'token-efficient-tools-2026-03-28'` — terser tool_use wire format.\n * - `'interleaved-thinking-2025-05-14'` — think between tool calls within\n * one turn.\n * - `'redact-thinking-2026-02-12'` — replace large thinking blocks with\n * stubs server-side.\n * - `'prompt-caching-scope-2026-01-05'` — extended prompt-cache scope.\n *\n * Honored on both the OAuth and API-key paths.\n */\n extraBetas?: readonly string[]\n /**\n * Server-side context-management directive. Sent on the request body as\n * `context_management`. Requires the `context-management-2025-06-27` beta —\n * add it to {@link AnthropicParams.extraBetas}.\n *\n * Typed loosely so future Anthropic schema additions land without an SDK\n * bump. A typical compaction edit:\n *\n * ```ts\n * contextManagement: {\n * edits: [{\n * type: 'clear_tool_uses_20250919',\n * trigger: { type: 'input_tokens', value: 180_000 },\n * clear_at_least: { type: 'input_tokens', value: 140_000 },\n * clear_tool_inputs: ['Read', 'Bash', 'Grep'],\n * }],\n * }\n * ```\n */\n contextManagement?: AnthropicContextManagement\n /**\n * Generic pass-through for fields on the Messages API request body that the\n * SDK does not yet type. Spread into the request before the typed fields,\n * so explicit options ({@link AnthropicParams.contextManagement} and the\n * built-in fields like `model` / `tools` / `messages`) win on collision.\n *\n * Forward-compat escape hatch for new Anthropic betas — when a future flag\n * ships before zidane has a dedicated typed knob, set it here without\n * waiting on a release. Most fields will still need the matching beta in\n * {@link AnthropicParams.extraBetas}.\n */\n extraBodyParams?: Record<string, unknown>\n /**\n * Extra HTTP headers sent on every request, merged into the SDK's\n * `defaultHeaders`. Honored on both the OAuth and API-key paths.\n *\n * Use for routing/attribution headers a proxy or gateway in front of the\n * `baseURL` consumes (e.g. a target-provider selector). Reserved zidane\n * headers (`anthropic-beta`, `user-agent`, `x-app`, and the OAuth browser\n * flag) take precedence on collision.\n */\n extraHeaders?: Record<string, string>\n}\n\n/** Beta flags sent unconditionally on the OAuth path (Claude Code parity). */\nconst OAUTH_DEFAULT_BETAS = ['claude-code-20250219', 'oauth-2025-04-20'] as const\n\n/**\n * Beta flag that enables the `speed: \"fast\"` request field (fast mode — up to\n * 2.5× output tokens/sec on Opus 4.6/4.7/4.8 at premium pricing). Sent as an\n * `anthropic-beta` header only on requests that opt into fast mode; absent\n * otherwise so standard requests keep a byte-stable header for prompt caching.\n *\n * See: https://platform.claude.com/docs/en/build-with-claude/fast-mode\n */\nconst FAST_MODE_BETA = 'fast-mode-2026-02-01'\nconst API_KEY_RESERVED_EXTRA_HEADER_NAMES = new Set(['anthropic-beta'])\nconst OAUTH_RESERVED_EXTRA_HEADER_NAMES = new Set([\n 'anthropic-beta',\n 'anthropic-dangerous-direct-browser-access',\n 'user-agent',\n 'x-app',\n])\n\nfunction filterReservedExtraHeaders(\n extraHeaders: Record<string, string> | undefined,\n reservedNames: ReadonlySet<string>,\n): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [name, value] of Object.entries(extraHeaders ?? {})) {\n if (!reservedNames.has(name.toLowerCase()))\n out[name] = value\n }\n return out\n}\n\n/**\n * Build the `anthropic-beta` header value — OAuth defaults plus caller-supplied\n * extras, de-duped while preserving order. Returns `undefined` when no betas\n * apply (non-OAuth, no extras).\n */\nexport function resolveAnthropicBetas(\n isOAuth: boolean,\n extraBetas?: readonly string[],\n): string | undefined {\n const seen = new Set<string>()\n const out: string[] = []\n if (isOAuth) {\n for (const b of OAUTH_DEFAULT_BETAS) {\n if (!seen.has(b)) { seen.add(b); out.push(b) }\n }\n }\n if (extraBetas) {\n for (const b of extraBetas) {\n if (typeof b === 'string' && b.length > 0 && !seen.has(b)) {\n seen.add(b)\n out.push(b)\n }\n }\n }\n return out.length > 0 ? out.join(',') : undefined\n}\n\nfunction getConfiguredApiKey(anthropicParams?: AnthropicParams): string {\n if (anthropicParams?.apiKey)\n return anthropicParams.apiKey\n\n if (anthropicParams?.access)\n return anthropicParams.access\n\n if (process.env.ANTHROPIC_API_KEY)\n return process.env.ANTHROPIC_API_KEY\n\n // `readOAuthCredentials` tolerates a missing or corrupted file and returns `{}`\n // in both cases, so stale/half-written creds never crash agent construction.\n const access = readOAuthCredentials().anthropic?.access\n if (typeof access === 'string' && access.length > 0)\n return access\n\n throw new Error('No API key found. Run `bun run auth` first.')\n}\n\nfunction createClient(\n SDK: AnthropicCtor,\n apiKey: string,\n isOAuth: boolean,\n baseURL?: string,\n extraBetas?: readonly string[],\n extraHeaders?: Record<string, string>,\n): AnthropicInstance {\n const base = baseURL ? { baseURL } : {}\n const betaHeader = resolveAnthropicBetas(isOAuth, extraBetas)\n if (isOAuth) {\n const callerHeaders = filterReservedExtraHeaders(extraHeaders, OAUTH_RESERVED_EXTRA_HEADER_NAMES)\n const defaultHeaders: Record<string, string> = {\n ...callerHeaders,\n 'anthropic-dangerous-direct-browser-access': 'true',\n 'user-agent': 'zidane/2.0.0',\n 'x-app': 'cli',\n }\n if (betaHeader)\n defaultHeaders['anthropic-beta'] = betaHeader\n return new SDK({\n apiKey: null,\n authToken: apiKey,\n dangerouslyAllowBrowser: true,\n defaultHeaders,\n ...base,\n })\n }\n // API-key path — only emit the beta header when the caller actually opted in.\n const defaultHeaders = filterReservedExtraHeaders(extraHeaders, API_KEY_RESERVED_EXTRA_HEADER_NAMES)\n if (betaHeader)\n defaultHeaders['anthropic-beta'] = betaHeader\n return new SDK({\n apiKey,\n ...(Object.keys(defaultHeaders).length > 0 ? { defaultHeaders } : {}),\n ...base,\n })\n}\n\ntype BudgetedThinkingLevel = Exclude<ThinkingLevel, 'off' | 'adaptive'>\n\n/**\n * Map `ThinkingLevel` budgeted tiers to Anthropic's `output_config.effort`\n * enum. `minimal` collapses to `low` (the closest equivalent — Anthropic does\n * not have a sub-`low` tier).\n */\nconst EFFORT_FOR_LEVEL: Record<BudgetedThinkingLevel, 'low' | 'medium' | 'high' | 'xhigh' | 'max'> = {\n minimal: 'low',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'xhigh',\n max: 'max',\n}\n\n/**\n * Description of the Anthropic-side thinking configuration derived from a\n * ThinkingLevel. `null` means no thinking-related field should be set on the\n * request.\n *\n * Two shapes:\n * - `adaptive` — `thinking.type='adaptive'`. The model self-budgets per turn.\n * When `effort` is set, also emits `output_config.effort` to hint at the\n * level of reasoning the caller wants. This is the post-Claude-4.6 default\n * for level-based control and avoids the `thinking.type='enabled'`\n * deprecation warning. When `maxTokensCap` is set, the request builder\n * reduces `max_tokens` to `min(max_tokens, maxTokensCap)` — adaptive thinks\n * and replies inside one envelope, so capping the envelope soft-bounds the\n * thinking too.\n * - `enabled` — explicit-budget path: `thinking.type='enabled'` with an\n * explicit `budget_tokens`. `maxTokensBump` is added to the request's\n * `max_tokens` so the budget sits on top of the response cap. The only\n * way to pin a precise token budget; Anthropic emits a deprecation\n * warning for this shape on opus 4.6+, so we only route here when the\n * caller explicitly sets `behavior.thinkingBudget`.\n *\n * In both shapes Anthropic requires `temperature` to be `1`.\n */\nexport type AnthropicThinkingPlan\n = | { kind: 'enabled', budgetTokens: number, maxTokensBump: number }\n | { kind: 'adaptive', effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max', maxTokensCap?: number }\n\n/**\n * Decide how to translate a `ThinkingLevel` into Anthropic's request shape.\n * Pure / synchronous — exported so tests can assert routing without standing\n * up the SDK.\n *\n * Routing rules:\n * - `'off'` → `null` (no thinking field, no effort hint).\n * - `'adaptive'` → adaptive thinking with no effort hint (model decides\n * everything). When `customBudget` is set, it is carried as `maxTokensCap`\n * so the request builder caps `max_tokens` accordingly — adaptive has no\n * native budget knob, but capping the response envelope soft-bounds the\n * thinking that lives inside it.\n * - Budgeted levels → adaptive thinking with an `effort` hint, unless\n * `customBudget` is provided.\n * - Any level + `customBudget` → explicit-budget `enabled` path. The caller\n * has opted into precise budget control and accepts the Anthropic\n * deprecation warning that comes with it on opus 4.6+. `'adaptive'` is the\n * sole exception: it never falls back to enabled, since adaptive is the\n * current Anthropic API surface for self-budgeted thinking.\n */\nexport function planAnthropicThinking(\n level: ThinkingLevel,\n customBudget?: number,\n): AnthropicThinkingPlan | null {\n if (level === 'off')\n return null\n if (level === 'adaptive') {\n if (typeof customBudget === 'number' && customBudget > 0)\n return { kind: 'adaptive', maxTokensCap: customBudget }\n return { kind: 'adaptive' }\n }\n if (customBudget !== undefined) {\n return { kind: 'enabled', budgetTokens: customBudget, maxTokensBump: customBudget }\n }\n return { kind: 'adaptive', effort: EFFORT_FOR_LEVEL[level] }\n}\n\n/**\n * Map Anthropic's native `stop_reason` to the zidane `TurnFinishReason` union.\n *\n * `pause_turn` and `model_context_window_exceeded` are 4.6+ stop reasons that\n * pre-Z21 collapsed to `'other'` and silently terminated the run. They now\n * map to `'pause'` and `'length'` respectively, and the surrounding caller\n * adjusts the `done` flag so the loop can recover.\n */\nfunction mapStopReason(stopReason: string | null | undefined): TurnFinishReason | undefined {\n if (!stopReason)\n return undefined\n switch (stopReason) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop'\n case 'tool_use':\n return 'tool-calls'\n case 'max_tokens':\n case 'model_context_window_exceeded':\n // 4.6+: response bumped against the model's context window mid-stream.\n // Treat as a length-class stop so consumers can prune + retry; the\n // partial assistant response is preserved.\n return 'length'\n case 'refusal':\n return 'content-filter'\n // 4.6+: server-side mid-turn pause for long thinking. The loop\n // continues with a synthetic continue message rather than terminating.\n case 'pause_turn':\n return 'pause'\n default:\n return 'other'\n }\n}\n\nconst EPHEMERAL: Anthropic.CacheControlEphemeral = { type: 'ephemeral' }\n\n/**\n * Mutate an Anthropic request in place to add cache breakpoints on the three\n * stable prefixes:\n * 1. System prompt — `cache_control` on the static prefix only (see below).\n * 2. Tool definitions — last tool.\n * 3. Conversation — last content block of the last message.\n *\n * Each breakpoint tells Anthropic to cache the prefix ending at that block;\n * subsequent turns reuse the cached prefix and pay only for the delta. Safe\n * no-op when any prefix is empty (no tools, empty system, etc.).\n *\n * System-prompt boundary handling (`SYSTEM_PROMPT_BOUNDARY`):\n *\n * - When `originalSystem` is provided AND carries the marker, the system\n * block is rewritten as a 2-block array: static (cached) then dynamic\n * (uncached). The caller is expected to have already stripped the marker\n * from `params.system` via {@link renderSystemForWire} — this helper\n * only re-splits to apply `cache_control` cleanly.\n * - When `originalSystem` is omitted or marker-free, the existing single-\n * block treatment applies: `cache_control` on the whole system string.\n * - Array system prompts: existing semantics — `cache_control` lands on the\n * last block. Callers building their own multi-block layout own the\n * breakpoint placement.\n */\nexport function applyAnthropicCacheBreakpoints(\n params: Anthropic.MessageCreateParamsStreaming,\n originalSystem?: string,\n): void {\n if (typeof params.system === 'string') {\n if (params.system.length > 0) {\n // `originalSystem` is the authoritative source for the boundary split\n // — `params.system` may have been pre-rendered by `renderSystemForWire`.\n // Fall back to `params.system` itself when no original was supplied\n // (or an empty original) so an external caller that embedded a marker\n // directly doesn't leak it into the cached block on the wire.\n const splitSource = originalSystem && originalSystem.length > 0\n ? originalSystem\n : params.system\n const parts = splitSystemPrompt(splitSource)\n if (parts.dynamic.length > 0) {\n const blocks: Anthropic.TextBlockParam[] = []\n if (parts.static.length > 0)\n blocks.push({ type: 'text', text: parts.static, cache_control: EPHEMERAL })\n blocks.push({ type: 'text', text: parts.dynamic })\n params.system = blocks\n }\n else {\n // No marker — wrap the (already marker-free) string in a single\n // cached block. `parts.static` equals `splitSource` in this branch.\n params.system = [{ type: 'text', text: parts.static, cache_control: EPHEMERAL }]\n }\n }\n }\n else if (Array.isArray(params.system) && params.system.length > 0) {\n const lastIdx = params.system.length - 1\n params.system = params.system.map((block, i) =>\n i === lastIdx ? { ...block, cache_control: EPHEMERAL } : block,\n )\n }\n\n if (params.tools && params.tools.length > 0) {\n const lastIdx = params.tools.length - 1\n params.tools = params.tools.map((tool, i) =>\n i === lastIdx ? { ...tool, cache_control: EPHEMERAL } : tool,\n ) as Anthropic.ToolUnion[]\n }\n\n if (params.messages.length === 0)\n return\n const lastMsgIdx = params.messages.length - 1\n const lastMsg = params.messages[lastMsgIdx]\n if (typeof lastMsg.content === 'string') {\n if (lastMsg.content.length === 0)\n return\n params.messages[lastMsgIdx] = {\n ...lastMsg,\n content: [{ type: 'text', text: lastMsg.content, cache_control: EPHEMERAL }],\n }\n return\n }\n if (!Array.isArray(lastMsg.content) || lastMsg.content.length === 0)\n return\n const blocks = lastMsg.content\n // `ThinkingBlockParam` and `RedactedThinkingBlockParam` do not accept `cache_control`\n // in the SDK types — walk backward past any trailing thinking blocks to find the\n // nearest cache-eligible block. Returns -1 when every block is a thinking variant,\n // which skips this breakpoint; system + tools still carry the cache prefix.\n let targetIdx = blocks.length - 1\n while (targetIdx >= 0 && isThinkingBlock(blocks[targetIdx]))\n targetIdx -= 1\n if (targetIdx < 0)\n return\n const nextBlocks = blocks.slice()\n nextBlocks[targetIdx] = { ...nextBlocks[targetIdx], cache_control: EPHEMERAL } as typeof nextBlocks[number]\n params.messages[lastMsgIdx] = { ...lastMsg, content: nextBlocks }\n}\n\nfunction isThinkingBlock(block: { type: string }): boolean {\n return block.type === 'thinking' || block.type === 'redacted_thinking'\n}\n\n/**\n * Duck-type check for an Anthropic SDK `APIError` — avoids a runtime dependency\n * on `@anthropic-ai/sdk` so `classifyError` stays usable even when the optional\n * peer dep isn't loaded (e.g. host code calling it on an unrelated provider's\n * error).\n *\n * Anthropic's APIError shape: `.status: number` + `.error` (parsed body, object\n * or null). Plain `Error`s don't have `.status` + `.error`.\n */\nfunction looksLikeAnthropicApiError(err: unknown): boolean {\n if (!err || typeof err !== 'object')\n return false\n const e = err as { status?: unknown, error?: unknown }\n return typeof e.status === 'number' && 'error' in e\n}\n\n/**\n * Anthropic SSE `error` event types that warrant a retry. `overloaded_error`\n * is the headline case (capacity event mid-stream); `api_error` and\n * `timeout_error` are both server-side transient failures. `invalid_request_error`,\n * `authentication_error`, `permission_error`, `not_found_error`, `billing_error`\n * are terminal — retrying them would just hammer a bad request.\n *\n * `rate_limit_error` here would be redundant: the SDK's pre-stream retry\n * handles 429, and a mid-stream `rate_limit_error` is exceedingly rare. We\n * include it anyway for symmetry with the HTTP-level retry policy.\n */\nconst SSE_RETRYABLE_ERROR_TYPES = new Set<string>([\n 'overloaded_error',\n 'api_error',\n 'timeout_error',\n 'rate_limit_error',\n])\n\n/**\n * Try to parse an Anthropic SSE `error` event payload out of a thrown error's\n * message. The SDK's `MessageStream` surfaces mid-stream error events by\n * throwing an `AnthropicError` whose `.message` contains the raw JSON shape:\n *\n * {\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"},\"request_id\":\"req_...\"}\n *\n * Returns the inner `{ type, message }` or `null` when the message isn't\n * the canonical SSE error shape. Tolerant: silently returns `null` for\n * non-string input, non-JSON content, or any shape mismatch.\n */\nfunction matchSseErrorEvent(message: unknown): { type: string, message: string } | null {\n if (typeof message !== 'string' || message.length === 0)\n return null\n // Cheap pre-check to avoid JSON.parse on every error message.\n if (!message.includes('\"type\":\"error\"') && !message.includes('\"type\": \"error\"'))\n return null\n // The message may be the JSON itself or have it embedded (some SDK paths\n // prefix a human prelude). Scan for the first `{` and try from there.\n const start = message.indexOf('{')\n if (start < 0)\n return null\n try {\n const parsed = JSON.parse(message.slice(start)) as unknown\n if (!parsed || typeof parsed !== 'object')\n return null\n const outer = parsed as { type?: unknown, error?: unknown }\n if (outer.type !== 'error' || !outer.error || typeof outer.error !== 'object')\n return null\n const inner = outer.error as { type?: unknown, message?: unknown }\n if (typeof inner.type !== 'string')\n return null\n return {\n type: inner.type,\n message: typeof inner.message === 'string' ? inner.message : inner.type,\n }\n }\n catch {\n return null\n }\n}\n\n/**\n * Classify an Anthropic SDK / HTTP error for typed-error wrapping.\n *\n * - `prompt is too long` (400 invalid_request_error) → `context_exceeded`.\n * - `'tool_use' ids were found without 'tool_result' blocks` /\n * `'tool_result must be preceded by a tool_call'` (400) →\n * `tool_pairing_corruption`. The local repair pass should have caught\n * this — the typed error tells consumers their pre-send pipeline is\n * shipping orphaned blocks somehow (custom `context:transform` hook,\n * bypassed loop, mid-stream session edit) so they can patch the root\n * cause instead of chasing 400s.\n * - Any other Anthropic `APIError`-shaped value → `provider_error` with the\n * native status/type code.\n * - Unknown errors → `null` (loop wraps in `AgentProviderError` generically).\n *\n * Anthropic's wire error shape is `{ type: 'error', error: { type, message } }` — the\n * SDK stores the parsed body on `err.error`. We walk both levels so callers see the\n * most specific `providerCode` we can find.\n */\nexport function classifyAnthropicError(err: unknown): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n\n interface InnerError { type?: string, message?: string }\n interface AnthError {\n name?: string\n message?: string\n status?: number\n error?: InnerError & { error?: InnerError }\n }\n const anyErr = err as AnthError\n\n // Mid-stream SSE error event — the SDK's `MessageStream` surfaces these by\n // throwing an `AnthropicError` (plain Error subclass, no `.status`) whose\n // `.message` carries the raw SSE error JSON, e.g.\n // `{\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"},\"request_id\":\"...\"}`.\n // The pre-stream HTTP retry inside the SDK can't help here — the response\n // already opened with a 200, then the server emitted `event: error`\n // mid-stream. Classify these so the loop-level retry kicks in.\n //\n // Guarded on `!looksLikeAnthropicApiError(err)` so we don't shadow the\n // structured `APIError` branch below (which also stringifies its body into\n // `.message` and would otherwise match this same pattern).\n if (!looksLikeAnthropicApiError(err)) {\n const sseError = matchSseErrorEvent(anyErr.message)\n if (sseError) {\n return {\n kind: 'provider_error',\n providerCode: sseError.type,\n message: sseError.message,\n retryable: SSE_RETRYABLE_ERROR_TYPES.has(sseError.type),\n }\n }\n return null\n }\n\n // Prefer the inner error when present (Anthropic's nested shape).\n const innerType = anyErr.error?.error?.type\n const outerType = anyErr.error?.type\n const nativeType = innerType && innerType !== 'error' ? innerType : outerType\n const message = anyErr.error?.error?.message\n ?? anyErr.error?.message\n ?? anyErr.message\n ?? ''\n\n if (matchesContextExceeded(message)) {\n return {\n kind: 'context_exceeded',\n providerCode: nativeType ?? 'invalid_request_error',\n message,\n }\n }\n\n if (matchesToolPairingError(message)) {\n return {\n kind: 'tool_pairing_corruption',\n providerCode: nativeType ?? 'invalid_request_error',\n message,\n }\n }\n\n const status = anyErr.status\n const retryable = typeof status === 'number'\n ? isRetryableHttpStatus(status)\n : undefined\n\n return {\n kind: 'provider_error',\n providerCode: nativeType ?? (status ? String(status) : undefined),\n message,\n ...(retryable !== undefined ? { retryable } : {}),\n }\n}\n\n/**\n * Build a user `SessionMessage` from multimodal prompt parts.\n *\n * - Text parts → text blocks.\n * - Image parts → base64 image blocks.\n * - Document parts → canonical document blocks. `toAnthropic` emits native\n * document blocks only for base64 PDFs; text/non-PDF documents fall back to\n * attachment-tagged text to avoid invalid Anthropic source media types.\n *\n * The format mirrors `defaultPromptMessage`'s output on shape — Anthropic-specific\n * handling differs only in that `promptMessage` being present tells the agent loop\n * to route PromptPart[] through this function rather than throwing on base64 docs.\n */\nfunction anthropicPromptMessage(parts: PromptPart[]): SessionMessage {\n const content: SessionContentBlock[] = []\n\n for (const part of parts) {\n if (part.type === 'text') {\n if (part.text.length > 0)\n content.push({ type: 'text', text: part.text })\n continue\n }\n\n if (part.type === 'image') {\n content.push({ type: 'image', mediaType: part.mediaType, data: part.data })\n continue\n }\n\n if (part.type === 'audio')\n throw unsupportedMediaError('audio', 'anthropic')\n if (part.type === 'video')\n throw unsupportedMediaError('video', 'anthropic')\n\n // document\n content.push({\n type: 'document',\n mediaType: part.mediaType,\n data: part.data,\n encoding: part.encoding,\n ...(part.name ? { name: part.name } : {}),\n })\n }\n\n return { role: 'user', content }\n}\n\nexport function anthropic(\n anthropicParams?: AnthropicParams,\n): Provider {\n const configuredApiKey = getConfiguredApiKey(anthropicParams)\n // Factory-time snapshot — used only for the static `meta.isOAuth` flag.\n // Keys resolve per call (env / file creds can change between construction\n // and a turn), so `countTokens` / `stream` re-derive OAuth-ness from the\n // freshly resolved key instead of trusting this.\n const isOAuth = configuredApiKey.includes('sk-ant-oat')\n const defaultModel = anthropicParams?.defaultModel || 'claude-opus-4-8'\n let runtimeCredentials = extractRuntimeCredentials(anthropicParams)\n\n return {\n name: 'anthropic',\n meta: {\n defaultModel,\n isOAuth,\n // True when server-side context management is configured: the API may\n // clear old tool results mid-conversation without the client knowing.\n // The loop reads this to disable the read_file dedup, whose client-side\n // hash can't tell that a server-cleared body left the wire — otherwise\n // the \"unchanged\" replay stub would strand the model on missing content.\n clearsContextServerSide: Boolean(anthropicParams?.contextManagement),\n capabilities: {\n vision: true,\n imageInToolResult: true,\n documents: true,\n // Anthropic Messages API has no audio/video input content block.\n audio: false,\n video: false,\n // Anthropic Messages API supports `web_search_20250305` as a\n // server-side tool — the model issues searches and consumes\n // results without a client-visible tool_use round-trip. The\n // canonical `web_search` `ToolDef` ships as a cross-provider\n // fallback; when this capability is set, `formatTools` rewrites\n // it to the server-tool wire shape and drops the function-tool\n // version so the model uses the native path.\n nativeWebSearch: { maxUses: 5 },\n },\n },\n\n formatTools(tools: ToolSpec[]): Anthropic.ToolUnion[] {\n // Sanitize before forwarding — Anthropic 400s on the strict shapes\n // (root `$ref`, root `oneOf|anyOf|allOf`, `type: ['object', 'null']`,\n // missing `properties`, `nullable: true`) that show up in MCP-server\n // schemas. The strict `anthropic` profile coerces those without\n // changing semantics for valid schemas. Warnings are de-duped to\n // `console.warn` so the same bad schema doesn't spam the log every\n // turn.\n //\n // `web_search` is special-cased: when present, it's emitted as the\n // server-tool `web_search_20250305` block and removed from the\n // function-tools list. The model invokes it without a client-side\n // round-trip; Anthropic injects the search results into the\n // assistant message directly. See the `nativeWebSearch` capability\n // declared above.\n const nativeWebSearch = this.meta.capabilities?.nativeWebSearch\n // `hasWebSearch` is the existence check; `fnTools` is the filtered\n // list. Computing existence via `tools.some` (rather than comparing\n // pre/post-filter lengths) makes the rewrite intent obvious at a\n // glance.\n const hasWebSearch = !!nativeWebSearch && tools.some(t => t.name === 'web_search')\n const fnTools = hasWebSearch ? tools.filter(t => t.name !== 'web_search') : tools\n const sanitized = sanitizeToolSpecs(fnTools, { profile: 'anthropic' })\n const out: Anthropic.ToolUnion[] = sanitized.map(t => ({\n name: t.name,\n description: t.description,\n input_schema: t.inputSchema as Anthropic.Tool['input_schema'],\n }))\n if (hasWebSearch && nativeWebSearch) {\n // `max_uses` is optional — omit when the capability doesn't pin a value\n // so Anthropic's server-side default applies.\n const block: Anthropic.WebSearchTool20250305 = {\n type: 'web_search_20250305',\n name: 'web_search',\n }\n if (typeof nativeWebSearch.maxUses === 'number')\n block.max_uses = nativeWebSearch.maxUses\n out.push(block)\n }\n return out\n },\n\n userMessage(content: string): SessionMessage {\n return { role: 'user', content: [{ type: 'text', text: content }] }\n },\n\n assistantMessage(content: string): SessionMessage {\n return { role: 'assistant', content: [{ type: 'text', text: content }] }\n },\n\n toolResultsMessage(results: ToolResult[]): SessionMessage {\n return {\n role: 'user',\n content: results.map(r => ({\n type: 'tool_result' as const,\n callId: r.id,\n output: r.content,\n ...(r.isError ? { isError: true as const } : {}),\n })),\n }\n },\n\n promptMessage: anthropicPromptMessage,\n\n classifyError: classifyAnthropicError,\n\n async countTokens(payload, signal): Promise<number | null> {\n try {\n const SDK = await loadAnthropicSdk()\n const apiKey = await resolveOAuthApiKey(\n {\n provider: 'anthropic',\n providerId: 'anthropic',\n params: runtimeCredentials ? { ...anthropicParams, ...runtimeCredentials } : anthropicParams,\n envKey: 'ANTHROPIC_API_KEY',\n missingError: 'No API key found. Run `bun run auth` first.',\n refreshError: reason => `Anthropic OAuth token refresh failed. ${reason}`,\n },\n )\n // Derive OAuth-ness from the freshly resolved key — auth mode can\n // change between factory construction and this call (env var set,\n // creds file rotated), and a stale flag would skew the count's\n // system-prompt folding relative to what `stream()` actually sends.\n const callIsOAuth = apiKey.includes('sk-ant-oat')\n const client = createClient(\n SDK,\n apiKey,\n callIsOAuth,\n anthropicParams?.baseURL,\n anthropicParams?.extraBetas,\n anthropicParams?.extraHeaders,\n )\n\n // Mirror `stream()`'s wire-payload build so the count matches what is\n // actually sent: OAuth folds the real system prompt into a synthetic\n // user/assistant pair and sends the canonical Claude Code prompt as\n // the system block.\n const wireSystem = renderSystemForWire(payload.system)\n const system = callIsOAuth\n ? `You are Claude Code, Anthropic's official CLI for Claude.`\n : wireSystem\n const messages: SessionMessage[] = callIsOAuth && payload.system\n ? [\n { role: 'user', content: [{ type: 'text' as const, text: wireSystem }] },\n { role: 'assistant', content: [{ type: 'text' as const, text: 'Understood. I will proceed with these instructions above the rest of my system prompt.' }] },\n ...payload.messages,\n ]\n : [...payload.messages]\n\n const res = await client.messages.countTokens(\n {\n model: payload.model as Model,\n system,\n tools: payload.tools as Anthropic.Tool[],\n messages: messages.map(m => toAnthropic(m)) as Anthropic.MessageParam[],\n },\n signal ? { signal } : undefined,\n )\n return res.input_tokens\n }\n catch (err) {\n // Unreachable under the active auth / network — caller falls back to\n // the heuristic. Surface the cause when debugging so a silent auth /\n // scope rejection (e.g. OAuth lacking the count endpoint) is visible.\n if (process.env.ZIDANE_DEBUG_COUNT)\n console.error('[anthropic.countTokens] failed:', err)\n return null\n }\n },\n\n async stream(options, callbacks: StreamCallbacks): Promise<TurnResult> {\n const SDK = await loadAnthropicSdk()\n const apiKey = await resolveOAuthApiKey(\n {\n provider: 'anthropic',\n providerId: 'anthropic',\n params: runtimeCredentials ? { ...anthropicParams, ...runtimeCredentials } : anthropicParams,\n envKey: 'ANTHROPIC_API_KEY',\n missingError: 'No API key found. Run `bun run auth` first.',\n refreshError: reason => `Anthropic OAuth token refresh failed. Run \\`bun run auth --anthropic\\` again. ${reason}`,\n },\n {\n ...callbacks,\n async onOAuthRefresh(ctx) {\n if (ctx.source === 'params') {\n runtimeCredentials = {\n access: ctx.credentials.access,\n refresh: ctx.credentials.refresh,\n expires: ctx.credentials.expires,\n }\n }\n await callbacks.onOAuthRefresh?.(ctx)\n },\n },\n )\n // Fast mode (`speed: \"fast\"`) is gated behind the `fast-mode-2026-02-01`\n // beta — without the header Anthropic rejects the body field with\n // `speed: Extra inputs are not permitted`. Inject it here (not in the\n // static default betas) so the header is present exactly when the request\n // will carry `speed: \"fast\"`, keeping non-fast requests byte-stable for\n // the prompt cache.\n const requestBetas = options.modelOptions?.fast\n ? [...(anthropicParams?.extraBetas ?? []), FAST_MODE_BETA]\n : anthropicParams?.extraBetas\n // Per-call OAuth detection — see the matching note in `countTokens`.\n const callIsOAuth = apiKey.includes('sk-ant-oat')\n const client = createClient(\n SDK,\n apiKey,\n callIsOAuth,\n anthropicParams?.baseURL,\n requestBetas,\n anthropicParams?.extraHeaders,\n )\n\n // System prompt injection is handled by agent.ts — we just pass it through.\n // For OAuth, the Claude Code API requires the system block to start with\n // the canonical Claude Code prompt — we prepend it to the real system prompt.\n // For OAuth, the CC API requires the system block to start with the canonical\n // Claude Code prompt. The real system prompt is injected as user+assistant messages.\n //\n // The boundary marker (`SYSTEM_PROMPT_BOUNDARY`) is structural metadata\n // for `applyAnthropicCacheBreakpoints`; strip it before the bytes hit\n // the wire so it never reaches the model. The original (un-rendered)\n // string is preserved as `options.system` and forwarded to the cache\n // helper below for an accurate static/dynamic split.\n const wireSystem = renderSystemForWire(options.system)\n const system = callIsOAuth\n ? `You are Claude Code, Anthropic's official CLI for Claude.`\n : wireSystem\n const messages: SessionMessage[] = callIsOAuth && options.system\n ? [\n { role: 'user', content: [{ type: 'text' as const, text: wireSystem }] },\n { role: 'assistant', content: [{ type: 'text' as const, text: 'Understood. I will proceed with these instructions above the rest of my system prompt.' }] },\n ...options.messages,\n ]\n : [...options.messages]\n const thinking = options.thinking ?? 'off'\n\n const modelId = options.model as Model\n\n // `context_management` is an untyped beta in SDK v0.90; widen `params` with\n // an optional field so we don't have to double-cast through `unknown` to\n // attach it below.\n const params: Anthropic.MessageCreateParamsStreaming & {\n context_management?: AnthropicContextManagement\n speed?: 'fast' | 'standard'\n } = {\n // Forward-compat escape hatch for un-typed beta fields. Spread first so\n // the typed core (model / max_tokens / system / tools / messages /\n // stream) and the explicit `context_management` below override on\n // collision — explicit always wins.\n ...((anthropicParams?.extraBodyParams ?? {}) as Record<string, unknown>),\n model: modelId,\n max_tokens: options.maxTokens,\n system,\n tools: options.tools as Anthropic.ToolUnion[],\n messages: messages.map(m => toAnthropic(m)) as Anthropic.MessageParam[],\n stream: true,\n }\n\n // Server-side context management (beta `context-management-2025-06-27`).\n // Skipped when the caller didn't pass a config — leaving the field off\n // the wire keeps requests valid on accounts that don't have the beta enabled.\n if (anthropicParams?.contextManagement)\n params.context_management = anthropicParams.contextManagement\n\n // Prompt caching — inject `cache_control: { type: 'ephemeral' }` breakpoints\n // on the three largest stable prefixes: system prompt, tool definitions, and\n // the last message's final content block. Three of Anthropic's four allowed\n // breakpoints; leaves headroom for a future thinking-block breakpoint.\n //\n // On the API-key path, `params.system` was derived from\n // `renderSystemForWire(options.system)` so the cache helper can split\n // the original on the `SYSTEM_PROMPT_BOUNDARY` marker and apply\n // `cache_control` to the static prefix only — per-turn churn in the\n // dynamic suffix no longer invalidates the cached doctrine above.\n //\n // On the OAuth path, `params.system` is the canonical Claude Code\n // prompt (`\"You are Claude Code...\"`) — `options.system` lives in the\n // injected user message instead, so we do NOT forward it here. Passing\n // it would replace the CC prompt with the user's doctrine. The user\n // message is still naturally cached via the last-message breakpoint\n // applied below; per-turn churn there bypasses the boundary feature on\n // OAuth, but parity with the pre-feature behavior is preserved.\n //\n // Skipped when `options.cache === false` (opt-out) or on any shape that would\n // produce an invalid request (empty system string, zero tools, empty message list).\n if (options.cache !== false)\n applyAnthropicCacheBreakpoints(params, callIsOAuth ? undefined : options.system)\n\n // Enable thinking / extended thinking when requested. The default path\n // for level-based control is `thinking.type='adaptive'` plus an\n // `output_config.effort` hint — Anthropic deprecated the explicit\n // `thinking.type='enabled' + budget_tokens` shape on opus 4.6+ and\n // recommends adaptive instead. Callers who need a precise token budget\n // can opt into the explicit-budget path by setting\n // `behavior.thinkingBudget`, accepting Anthropic's deprecation\n // warning in exchange. Either shape requires `temperature=1`.\n //\n // `display: 'summarized'` is set explicitly on both shapes — Opus 4.7\n // and Claude Mythos Preview silently flipped the default to\n // `'omitted'` (signature-only, no text), which makes the SDK fire\n // `thinking` deltas with empty `thinking` content and breaks every\n // host that surfaces traces live. Older models still default to\n // `'summarized'` so this is a no-op there.\n const plan = planAnthropicThinking(thinking, options.thinkingBudget)\n if (plan) {\n if (plan.kind === 'enabled') {\n params.thinking = { type: 'enabled', budget_tokens: plan.budgetTokens, display: 'summarized' }\n params.max_tokens = plan.maxTokensBump + params.max_tokens\n }\n else {\n params.thinking = { type: 'adaptive', display: 'summarized' }\n if (plan.effort)\n params.output_config = { effort: plan.effort }\n // Adaptive has no native budget knob — soft-cap the response envelope\n // (`max_tokens`) so unbounded thinking can't run away. Reduce only;\n // never raise above the caller's request.\n if (typeof plan.maxTokensCap === 'number' && plan.maxTokensCap > 0)\n params.max_tokens = Math.min(params.max_tokens, plan.maxTokensCap)\n }\n params.temperature = 1\n }\n\n // Fast mode (`speed: \"fast\"`) — ~2.5× output throughput at premium\n // pricing. Supported only on Opus 4.6 / 4.7 / 4.8; the model-options\n // surface only offers it on those, and Anthropic 400s a request with\n // `speed` on an unsupported model. `speed` is an untyped beta field in\n // SDK v0.90 (widened on `params` above).\n if (options.modelOptions?.fast)\n params.speed = 'fast'\n\n // Tool choice forcing\n if (options.toolChoice) {\n if (options.toolChoice.type === 'tool' && options.toolChoice.name)\n params.tool_choice = { type: 'tool', name: options.toolChoice.name }\n else if (options.toolChoice.type === 'required')\n params.tool_choice = { type: 'any' }\n else\n params.tool_choice = { type: 'auto' }\n }\n\n const s = client.messages.stream(params, {\n signal: options.signal,\n })\n\n let text = ''\n\n s.on('text', (delta) => {\n text += delta\n callbacks.onText(delta)\n })\n\n if (callbacks.onThinking) {\n s.on('thinking', (delta) => {\n callbacks.onThinking!(delta)\n })\n }\n\n // Server-tool blocks (e.g. `web_search_20250305`) execute on Anthropic's\n // side and arrive in the assistant content stream — not via our tool\n // loop. The SDK fires `contentBlock` once per block as it closes, so\n // listen for the two we care about and dispatch generic callbacks.\n // Other block types (text, thinking, tool_use, …) have their own paths\n // above / in `finalMessage()` — ignored here to avoid double-emission.\n if (callbacks.onServerToolUse || callbacks.onServerToolResult) {\n s.on('contentBlock', (block) => {\n if (block.type === 'server_tool_use') {\n callbacks.onServerToolUse?.({\n id: block.id,\n name: block.name,\n input: (block.input as Record<string, unknown> | undefined) ?? {},\n })\n }\n else if (block.type === 'web_search_tool_result') {\n callbacks.onServerToolResult?.({\n toolUseId: block.tool_use_id,\n toolName: 'web_search',\n content: block.content,\n })\n }\n })\n }\n\n const response = await s.finalMessage()\n\n const toolCalls = response.content\n .filter((b): b is Anthropic.ToolUseBlock => b.type === 'tool_use')\n .map(b => ({ id: b.id, name: b.name, input: b.input as Record<string, unknown> }))\n\n const finishReason = mapStopReason(response.stop_reason)\n\n // `pause_turn` is *not* terminal — the loop has to inject a continue\n // message and run another turn. Without this branch, the previous\n // `toolCalls.length === 0` shortcut would mark the run done at the\n // pause and silently drop the work in flight.\n const isPause = response.stop_reason === 'pause_turn'\n\n return {\n assistantMessage: fromAnthropic({ role: 'assistant', content: response.content }),\n text,\n toolCalls,\n done: !isPause && (response.stop_reason === 'end_turn' || toolCalls.length === 0),\n usage: fillEstimatedCost({\n input: response.usage.input_tokens,\n output: response.usage.output_tokens,\n cacheCreation: response.usage.cache_creation_input_tokens ?? undefined,\n cacheRead: response.usage.cache_read_input_tokens ?? undefined,\n ...(finishReason ? { finishReason } : {}),\n modelId: response.model ?? (options.model as string),\n }, 'anthropic', options.modelOptions?.fast\n ? fastModeCostMultiplier(response.model ?? (options.model as string))\n : undefined),\n }\n },\n }\n}\n","import type { Provider, ProviderCapabilities } from '.'\nimport { openaiCompat } from './openai-compat'\n\n// Arcee Platform API (OpenAI-compatible). Exposes Trinity models by plain\n// slug (`trinity-large-thinking`, `trinity-mini`, …) and returns reasoning in\n// the `reasoning_content` / `reasoning` field. NOTE: this is the Platform API\n// (`api.arcee.ai/api/v1`), not Conductor (`conductor.arcee.ai/v1`) — the latter\n// routes via different model names (`auto`, `blitz`). For self-hosted vLLM,\n// override `baseURL` and use the HF slug (`arcee-ai/Trinity-Large-Thinking`).\nconst BASE_URL = 'https://api.arcee.ai/api/v1'\n\nexport interface ArceeParams {\n apiKey?: string\n defaultModel?: string\n /**\n * Override the base URL — e.g. point at a self-hosted vLLM deployment serving\n * Trinity-Thinking instead of Arcee's hosted Platform API.\n */\n baseURL?: string\n /**\n * Provider capability flags. Trinity models are text-only — default:\n * `{ vision: false, imageInToolResult: false }`.\n */\n capabilities?: ProviderCapabilities\n /**\n * Wire field used to echo plain reasoning back across turns. Arcee's hosted\n * API accepts both names; some self-hosted vLLM versions only read `reasoning`\n * on input (vllm#38488). Default: `'reasoning'`.\n */\n reasoningContentField?: 'reasoning_content' | 'reasoning'\n /**\n * Extra HTTP headers sent on every request. Forwarded to the underlying\n * {@link openaiCompat} client — use for routing/attribution headers a proxy\n * in front of `baseURL` consumes.\n */\n extraHeaders?: Record<string, string>\n}\n\nfunction getApiKey(params?: ArceeParams): string {\n // Resolution order aligned with the other providers: explicit > env > fail.\n if (typeof params?.apiKey === 'string' && params.apiKey.length > 0)\n return params.apiKey\n\n if (process.env.ARCEE_API_KEY)\n return process.env.ARCEE_API_KEY\n\n throw new Error('No Arcee API key found. Pass `apiKey` or set ARCEE_API_KEY in your environment.')\n}\n\n/**\n * Arcee provider (Trinity-Large-Thinking and friends).\n *\n * Thin wrapper around {@link openaiCompat} pinned to the `reasoning_content`\n * round-trip mode: Trinity emits chain-of-thought in `<think>…</think>` blocks\n * that vLLM parses into a plain `reasoning_content` string. We capture it and\n * echo it back on every assistant message so the model resumes its prior\n * reasoning across tool calls — without this, tool calls leak into the\n * reasoning field as raw XML (Arcee's `xml_in_reasoning` pitfall). `content` is\n * also normalized from `null` → `''` on tool-call turns per the same guidance.\n *\n * See https://docs.arcee.ai/capabilities/reasoning-traces.\n */\nexport function arcee(params?: ArceeParams): Provider {\n return openaiCompat({\n name: 'arcee',\n apiKey: getApiKey(params),\n baseURL: params?.baseURL || BASE_URL,\n defaultModel: params?.defaultModel || 'trinity-large-thinking',\n capabilities: params?.capabilities ?? { vision: false, imageInToolResult: false },\n supportsReasoning: true,\n reasoningMode: 'reasoning_content',\n reasoningContentField: params?.reasoningContentField ?? 'reasoning',\n normalizeNullContent: true,\n extraHeaders: params?.extraHeaders,\n })\n}\n","import type { Provider, ProviderCapabilities } from '.'\nimport type { ThinkingLevel } from '../types'\nimport { openaiCompat } from './openai-compat'\n\n// Baseten Model APIs (OpenAI-compatible, shared infrastructure). Models are\n// addressed by HF-style slugs (`zai-org/GLM-5.1`, `moonshotai/Kimi-K2.6`, …)\n// and reasoning text streams in the `reasoning_content` delta field.\n// See https://docs.baseten.co/inference/model-apis/overview.\nconst BASE_URL = 'https://inference.baseten.co/v1'\n\n/**\n * Models that take OpenAI-style `reasoning_effort` (low/medium/high) and\n * reason by default. Everything else on Model APIs (Kimi, GLM, Nemotron) is\n * opt-in via `chat_template_args: { enable_thinking: true }`.\n * See https://docs.baseten.co/inference/model-apis/reasoning.\n */\nconst EFFORT_MODELS = new Set([\n 'deepseek-ai/DeepSeek-V4-Pro',\n 'openai/gpt-oss-120b',\n])\n\nexport interface BasetenParams {\n apiKey?: string\n defaultModel?: string\n /**\n * Override the base URL — e.g. point at a dedicated Baseten deployment's\n * OpenAI-compatible bridge instead of the shared Model APIs endpoint.\n */\n baseURL?: string\n /**\n * Provider capability flags. Default: `{ vision: false, imageInToolResult: false }`\n * — conservative, since most Model APIs are text-only. Set `vision: true`\n * when pinning a Kimi K2.x model (the only vision-capable ones).\n */\n capabilities?: ProviderCapabilities\n /**\n * Extra HTTP headers sent on every request. Forwarded to the underlying\n * {@link openaiCompat} client.\n */\n extraHeaders?: Record<string, string>\n}\n\nfunction getApiKey(params?: BasetenParams): string {\n // Resolution order aligned with the other providers: explicit > env > fail.\n if (typeof params?.apiKey === 'string' && params.apiKey.length > 0)\n return params.apiKey\n\n if (process.env.BASETEN_API_KEY)\n return process.env.BASETEN_API_KEY\n\n throw new Error('No Baseten API key found. Pass `apiKey` or set BASETEN_API_KEY in your environment.')\n}\n\n/**\n * Map zidane's thinking level to Baseten's per-model reasoning request shape:\n *\n * - `reasoning_effort` models (DeepSeek V4 Pro, GPT-OSS 120B) reason by\n * default; the effort string tunes depth. `'minimal'` maps to `'low'`,\n * Anthropic-only upper tiers map to `'high'`, `'adaptive'` sends nothing\n * (server default = medium); `'off'` sends nothing (cannot be disabled).\n * - All other models opt in via `chat_template_args.enable_thinking` — any\n * non-off level enables it (the template arg is boolean, no depth knob).\n *\n * Exported for tests.\n */\nexport function planBasetenReasoning(\n ctx: { model: string, thinking?: ThinkingLevel },\n): Record<string, unknown> | undefined {\n const { model, thinking } = ctx\n if (!thinking || thinking === 'off')\n return undefined\n if (EFFORT_MODELS.has(model)) {\n if (thinking === 'adaptive')\n return undefined\n const effort = thinking === 'minimal' ? 'low' : thinking === 'xhigh' || thinking === 'max' ? 'high' : thinking\n return { reasoning_effort: effort }\n }\n return { chat_template_args: { enable_thinking: true } }\n}\n\n/**\n * Baseten Model APIs provider.\n *\n * Thin wrapper around {@link openaiCompat} pinned to the `reasoning_content`\n * round-trip mode: thinking arrives in the `reasoning_content` delta field and\n * is echoed back on assistant messages under the same name so reasoning\n * models resume their chain-of-thought across tool calls. The thinking level\n * maps to Baseten's request shape via {@link planBasetenReasoning}.\n */\nexport function baseten(params?: BasetenParams): Provider {\n return openaiCompat({\n name: 'baseten',\n apiKey: getApiKey(params),\n baseURL: params?.baseURL || BASE_URL,\n defaultModel: params?.defaultModel || 'zai-org/GLM-5.1',\n capabilities: params?.capabilities ?? { vision: false, imageInToolResult: false },\n supportsReasoning: true,\n reasoningMode: 'reasoning_content',\n reasoningContentField: 'reasoning_content',\n planReasoningRequest: planBasetenReasoning,\n extraHeaders: params?.extraHeaders,\n })\n}\n","import type { Provider, ProviderCapabilities } from '.'\nimport { openaiCompat } from './openai-compat'\n\nconst BASE_URL = 'https://api.cerebras.ai/v1'\n\nexport interface CerebrasParams {\n apiKey?: string\n defaultModel?: string\n /**\n * Provider capability flags. Cerebras currently serves text-only OSS models\n * (GLM, Llama-family, Qwen-family) — default: `{ vision: false, imageInToolResult: false }`.\n * Override when routing to a vision-capable deployment.\n */\n capabilities?: ProviderCapabilities\n /**\n * Extra HTTP headers sent on every request. Forwarded to the underlying\n * {@link openaiCompat} client — use for routing/attribution headers a proxy\n * in front of `baseURL` consumes.\n */\n extraHeaders?: Record<string, string>\n}\n\nfunction getApiKey(params?: CerebrasParams): string {\n // Resolution order is intentionally aligned with `anthropic` + `openai` —\n // explicit params > env var > fail. Host code that composes providers from\n // config (e.g. a YAML-driven CLI) relies on `params.apiKey` winning in all\n // providers, not just some.\n if (typeof params?.apiKey === 'string' && params.apiKey.length > 0)\n return params.apiKey\n\n if (process.env.CEREBRAS_API_KEY)\n return process.env.CEREBRAS_API_KEY\n\n throw new Error('No Cerebras API key found. Pass `apiKey` or set CEREBRAS_API_KEY in your environment.')\n}\n\n/**\n * Cerebras provider.\n *\n * Thin wrapper around {@link openaiCompat} with Cerebras-specific defaults\n * (base URL, default model).\n */\nexport function cerebras(params?: CerebrasParams): Provider {\n const apiKey = getApiKey(params)\n return openaiCompat({\n name: 'cerebras',\n apiKey,\n baseURL: BASE_URL,\n defaultModel: params?.defaultModel || 'zai-glm-4.7',\n capabilities: params?.capabilities ?? { vision: false, imageInToolResult: false },\n extraHeaders: params?.extraHeaders,\n })\n}\n","/**\n * PKCE helper. Inlined here (rather than imported from pi-ai) because\n * `@earendil-works/pi-ai/oauth` does not re-export it, and we don't want\n * to reach into `node_modules/.../utils/oauth/pkce.js` — that's an\n * implementation-detail path that breaks on minor upstream rearrangements.\n *\n * Web Crypto API only. Works under Bun + Node 22+ without any node:crypto\n * import (matches pi-ai's own behavior). Output is base64url per RFC 7636.\n */\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = ''\n for (const byte of bytes)\n binary += String.fromCharCode(byte)\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n}\n\nexport interface PkcePair {\n /** Random verifier used in the token-exchange step. */\n verifier: string\n /** SHA-256(verifier) sent on the authorize URL. */\n challenge: string\n}\n\nexport async function generatePkce(): Promise<PkcePair> {\n const verifierBytes = new Uint8Array(32)\n crypto.getRandomValues(verifierBytes)\n const verifier = base64UrlEncode(verifierBytes)\n\n const data = new TextEncoder().encode(verifier)\n const hashBuffer = await crypto.subtle.digest('SHA-256', data)\n const challenge = base64UrlEncode(new Uint8Array(hashBuffer))\n\n return { verifier, challenge }\n}\n","/**\n * Cursor OAuth flow.\n *\n * Unlike Anthropic / OpenAI Codex (loopback-redirect PKCE), Cursor uses a\n * **poll-based** PKCE flow with no local callback server:\n *\n * 1. Generate a PKCE verifier + challenge and a random UUID.\n * 2. Open the browser to `cursor.com/loginDeepControl?challenge&uuid&mode&redirectTarget`.\n * 3. Poll `api2.cursor.sh/auth/poll?uuid&verifier` until tokens come back\n * (HTTP 404 = \"not ready yet\", keep polling with backoff).\n * 4. Refresh via `POST api2.cursor.sh/auth/exchange_user_api_key` with\n * `Authorization: Bearer <refresh>`.\n *\n * Token expiry is derived from the access token's JWT `exp` claim (minus a\n * 5-minute safety margin), falling back to +1h when the claim is missing.\n *\n * Flow adapted from https://github.com/ndraiman/pi-cursor-provider, itself\n * derived from https://github.com/ephraimduncan/opencode-cursor.\n *\n * Cursor's auth + inference protocol is unofficial and undocumented — re-verify\n * the endpoints/params below if login starts failing.\n */\n\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n OAuthProviderInterface,\n} from '@earendil-works/pi-ai/oauth'\nimport { generatePkce } from './pkce'\n\n/** pi-ai / zidane OAuth provider id. Also the credentials-file key. */\nexport const CURSOR_OAUTH_PROVIDER_ID = 'cursor'\n\nconst CURSOR_LOGIN_URL = 'https://cursor.com/loginDeepControl'\nconst CURSOR_POLL_URL = 'https://api2.cursor.sh/auth/poll'\nconst CURSOR_REFRESH_URL = 'https://api2.cursor.sh/auth/exchange_user_api_key'\n\nconst POLL_MAX_ATTEMPTS = 150\nconst POLL_BASE_DELAY_MS = 1000\nconst POLL_MAX_DELAY_MS = 10_000\nconst POLL_BACKOFF_MULTIPLIER = 1.2\nconst POLL_MAX_CONSECUTIVE_ERRORS = 3\n\n/** Fallback lifetime when the JWT carries no `exp`. */\nconst DEFAULT_TOKEN_TTL_MS = 3600 * 1000\n/** Refresh slightly early so requests don't race expiry. */\nconst TOKEN_EXPIRY_SKEW_MS = 5 * 60 * 1000\n\ninterface CursorTokenResponse {\n accessToken: string\n refreshToken: string\n}\n\n/**\n * Derive expiry (epoch ms) from a JWT's `exp` claim, minus a safety skew.\n * Returns `now + 1h` for malformed tokens so a missing claim never wedges\n * refresh into an immediate-expire loop.\n */\nexport function cursorTokenExpiry(token: string): number {\n try {\n const parts = token.split('.')\n const payload = parts[1]\n if (parts.length !== 3 || !payload)\n return Date.now() + DEFAULT_TOKEN_TTL_MS\n\n const json = JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/'))) as { exp?: unknown }\n if (typeof json.exp === 'number')\n return json.exp * 1000 - TOKEN_EXPIRY_SKEW_MS\n }\n catch {\n // fall through to default\n }\n return Date.now() + DEFAULT_TOKEN_TTL_MS\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise(r => setTimeout(r, ms))\n}\n\n/**\n * Poll Cursor's auth endpoint until login completes. `404` means the user\n * hasn't finished the browser flow yet; anything else non-2xx is a hard error.\n */\nasync function pollForTokens(\n uuid: string,\n verifier: string,\n callbacks: OAuthLoginCallbacks,\n): Promise<CursorTokenResponse> {\n let wait = POLL_BASE_DELAY_MS\n let consecutiveErrors = 0\n\n for (let attempt = 0; attempt < POLL_MAX_ATTEMPTS; attempt++) {\n if (callbacks.signal?.aborted)\n throw new Error('Cursor login aborted')\n\n await delay(wait)\n\n try {\n const url = `${CURSOR_POLL_URL}?uuid=${encodeURIComponent(uuid)}&verifier=${encodeURIComponent(verifier)}`\n const response = await fetch(url, { signal: callbacks.signal })\n\n if (response.status === 404) {\n consecutiveErrors = 0\n wait = Math.min(wait * POLL_BACKOFF_MULTIPLIER, POLL_MAX_DELAY_MS)\n continue\n }\n\n if (response.ok) {\n const data = await response.json() as Partial<CursorTokenResponse>\n if (!data.accessToken || !data.refreshToken)\n throw new Error(`Cursor poll response missing tokens: ${JSON.stringify(data)}`)\n return { accessToken: data.accessToken, refreshToken: data.refreshToken }\n }\n\n throw new Error(`Cursor poll failed (${response.status})`)\n }\n catch (err) {\n if (callbacks.signal?.aborted)\n throw new Error('Cursor login aborted')\n consecutiveErrors++\n if (consecutiveErrors >= POLL_MAX_CONSECUTIVE_ERRORS)\n throw err instanceof Error ? err : new Error(String(err))\n callbacks.onProgress?.('Waiting for Cursor login to complete…')\n }\n }\n\n throw new Error('Cursor authentication timed out')\n}\n\nexport async function loginCursor(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n const { verifier, challenge } = await generatePkce()\n const uuid = crypto.randomUUID()\n\n const authUrl = new URL(CURSOR_LOGIN_URL)\n authUrl.searchParams.set('challenge', challenge)\n authUrl.searchParams.set('uuid', uuid)\n authUrl.searchParams.set('mode', 'login')\n authUrl.searchParams.set('redirectTarget', 'cli')\n\n callbacks.onAuth({\n url: authUrl.toString(),\n instructions: 'A browser window should open. Complete login in Cursor to finish.',\n })\n\n const tokens = await pollForTokens(uuid, verifier, callbacks)\n\n return {\n access: tokens.accessToken,\n refresh: tokens.refreshToken,\n expires: cursorTokenExpiry(tokens.accessToken),\n }\n}\n\nexport async function refreshCursorToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const response = await fetch(CURSOR_REFRESH_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.refresh}`,\n 'Content-Type': 'application/json',\n },\n body: '{}',\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => '')\n throw new Error(`Cursor token refresh failed (${response.status}): ${text || response.statusText}`)\n }\n\n const data = await response.json() as Partial<CursorTokenResponse>\n if (!data.accessToken)\n throw new Error(`Cursor token refresh response missing access token: ${JSON.stringify(data)}`)\n\n return {\n access: data.accessToken,\n // Cursor may omit a rotated refresh token — keep the existing one.\n refresh: data.refreshToken || credentials.refresh,\n expires: cursorTokenExpiry(data.accessToken),\n }\n}\n\n/**\n * Build a Cursor `OAuthProviderInterface`. Shape matches Anthropic / Codex so\n * it drops into `BUILTIN_PROVIDERS` and `src/auth.ts` unchanged.\n *\n * No `renderPage` parameter: Cursor's poll flow has no local callback server,\n * so there is no post-redirect page to theme.\n */\nexport function createCursorOAuthProvider(): OAuthProviderInterface {\n return {\n id: CURSOR_OAUTH_PROVIDER_ID,\n name: 'Cursor',\n usesCallbackServer: false,\n login: loginCursor,\n refreshToken: refreshCursorToken,\n getApiKey: credentials => credentials.access,\n }\n}\n","import type { Provider, StreamCallbacks } from '.'\nimport { CURSOR_OAUTH_PROVIDER_ID } from '../chat/oauth-page/cursor'\nimport { resolveOAuthApiKey } from './oauth'\nimport { openaiCompat } from './openai-compat'\n\n/**\n * Cursor provider (OAuth).\n *\n * Auth is fully wired: `bun run auth --cursor` (or the TUI wizard) logs in via\n * Cursor's poll-based PKCE flow and persists credentials; this provider resolves\n * + refreshes the OAuth token on every turn via {@link resolveOAuthApiKey}.\n *\n * Inference is **not** wired yet. Cursor does not expose an OpenAI-compatible\n * HTTP endpoint — it speaks a protobuf/Connect agent protocol over HTTP/2 to\n * `api2.cursor.sh`. Implementing `stream()` requires porting that transport\n * (generated protobuf schemas + an HTTP/2 streaming client) in-process, which\n * is intentionally left as a follow-up. Until then `stream()` resolves the\n * token (proving auth works) and then throws a clear, actionable error.\n *\n * The `openaiCompat` base supplies the message-format helpers (`formatTools`,\n * `userMessage`, `toolResultsMessage`, …) so the provider satisfies the full\n * `Provider` contract and slots into the registry; only `stream` is overridden.\n */\nexport interface CursorParams {\n /** Bypass OAuth resolution with an explicit token (mainly for tests). */\n apiKey?: string\n defaultModel?: string\n /**\n * Extra HTTP headers for the eventual Cursor transport. Accepted for API\n * parity with the other providers and forwarded to the openai-compat base,\n * but inert until Cursor inference is implemented (the `stream` override\n * currently throws before any request is made).\n */\n extraHeaders?: Record<string, string>\n}\n\nconst DEFAULT_MODEL = 'claude-4.6-sonnet'\n\nconst NOT_IMPLEMENTED_MESSAGE\n = 'Cursor OAuth login works, but inference over Cursor is not implemented yet. '\n + 'Cursor uses a protobuf/HTTP-2 agent protocol (not an OpenAI-compatible API), '\n + 'so the streaming transport still needs to be ported. Use another provider for now.'\n\nexport function cursor(params?: CursorParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n\n // Base only provides the format/serialization methods; `baseURL` is never\n // hit because we override `stream` below.\n const base = openaiCompat({\n name: 'cursor',\n apiKey: params?.apiKey ?? 'oauth',\n baseURL: 'https://api2.cursor.sh',\n defaultModel,\n capabilities: { vision: true, imageInToolResult: false },\n extraHeaders: params?.extraHeaders,\n })\n\n return {\n ...base,\n meta: { ...base.meta, defaultModel },\n async stream(options, callbacks: StreamCallbacks) {\n // Resolve (and lazily refresh) the OAuth token so auth failures surface\n // here with the right remediation, distinct from the not-implemented path.\n await resolveOAuthApiKey(\n {\n provider: 'cursor',\n providerId: CURSOR_OAUTH_PROVIDER_ID,\n params,\n missingError: 'No Cursor credentials found. Run `bun run auth --cursor` first.',\n refreshError: reason => `Cursor OAuth token refresh failed. Run \\`bun run auth --cursor\\` again. ${reason}`,\n },\n callbacks,\n )\n void options\n throw new Error(NOT_IMPLEMENTED_MESSAGE)\n },\n }\n}\n","import type { Provider, ProviderCapabilities } from '.'\nimport { openaiCompat } from './openai-compat'\n\nexport interface LocalParams {\n /**\n * Base URL of the local OpenAI-compatible server. `/chat/completions` is\n * appended. Examples:\n * - Ollama: `http://localhost:11434/v1`\n * - vLLM: `http://localhost:8000/v1`\n * - LM Studio: `http://localhost:1234/v1`\n * - Lemonade: `http://localhost:8000/api/v1`\n * - llama.cpp: `http://localhost:8080/v1`\n *\n * Resolution order: explicit `params.baseURL` > `LOCAL_LLM_BASE_URL` env >\n * throw.\n */\n baseURL?: string\n /**\n * Optional bearer key. Most local servers don't authenticate; some (vLLM\n * with `--api-key`, gateway proxies, llama.cpp with `--api-key`) do.\n * Falls back to `LOCAL_LLM_API_KEY`, then to a placeholder string accepted\n * by unauthenticated endpoints.\n */\n apiKey?: string\n /**\n * Default model id. Local runtimes have no fixed catalogue — whatever the\n * user has loaded (e.g. `llama3.1:8b`, `qwen2.5-coder`, a HF repo path).\n * Falls back to `LOCAL_LLM_DEFAULT_MODEL`.\n */\n defaultModel?: string\n /**\n * Provider capability flags. Defaults to text-only — typical OSS local\n * deployment. Override when pointing at a vision-capable runtime (e.g.\n * Ollama serving a multimodal model, vLLM with a VLM).\n */\n capabilities?: ProviderCapabilities\n /**\n * Extra HTTP headers sent on every request. Forwarded to the underlying\n * {@link openaiCompat} client — use for auth/routing headers a self-hosted\n * gateway in front of `baseURL` consumes.\n */\n extraHeaders?: Record<string, string>\n}\n\nfunction getBaseURL(params?: LocalParams): string {\n if (typeof params?.baseURL === 'string' && params.baseURL.length > 0)\n return params.baseURL\n if (process.env.LOCAL_LLM_BASE_URL)\n return process.env.LOCAL_LLM_BASE_URL\n throw new Error(\n 'No local LLM base URL found. Pass `baseURL` or set LOCAL_LLM_BASE_URL '\n + '(e.g. http://localhost:11434/v1 for Ollama, http://localhost:8000/v1 for vLLM).',\n )\n}\n\nfunction getApiKey(params?: LocalParams): string {\n if (typeof params?.apiKey === 'string' && params.apiKey.length > 0)\n return params.apiKey\n if (process.env.LOCAL_LLM_API_KEY)\n return process.env.LOCAL_LLM_API_KEY\n // Most local servers don't authenticate; send a placeholder so the factory's\n // Authorization header is well-formed (servers that ignore the header are\n // unaffected; servers that strict-check will be configured via env anyway).\n return 'no-key'\n}\n\nfunction getDefaultModel(params?: LocalParams): string | undefined {\n if (typeof params?.defaultModel === 'string' && params.defaultModel.length > 0)\n return params.defaultModel\n if (process.env.LOCAL_LLM_DEFAULT_MODEL)\n return process.env.LOCAL_LLM_DEFAULT_MODEL\n return undefined\n}\n\n/**\n * Local OpenAI-compatible LLM provider.\n *\n * Thin wrapper around {@link openaiCompat} for self-hosted runtimes that\n * speak the standard `POST /chat/completions` + SSE dialect: Ollama, vLLM,\n * LM Studio, Lemonade, llama.cpp's server, text-generation-webui, etc.\n *\n * Caching and reasoning are left off — local runtimes typically strict-\n * validate the request schema and would 400 on the extra fields. Override\n * `capabilities` when pointing at a vision-capable deployment.\n */\nexport function local(params?: LocalParams): Provider {\n return openaiCompat({\n name: 'local',\n apiKey: getApiKey(params),\n baseURL: getBaseURL(params),\n defaultModel: getDefaultModel(params),\n capabilities: params?.capabilities ?? { vision: false, imageInToolResult: false },\n extraHeaders: params?.extraHeaders,\n })\n}\n","import type {\n AssistantMessage as PiAssistantMessage,\n Context as PiContext,\n Message as PiMessage,\n Model as PiModel,\n Tool as PiTool,\n Usage as PiUsage,\n} from '@earendil-works/pi-ai'\nimport type { Provider, StreamCallbacks, StreamOptions, ToolSpec, TurnResult } from '.'\nimport type { ClassifiedError } from '../errors'\nimport type { SessionContentBlock, SessionMessage, ToolResultDocumentContent, TurnFinishReason } from '../types'\nimport type { OAuthParams } from './oauth'\nimport { getModel } from '@earendil-works/pi-ai'\nimport { streamOpenAICodexResponses } from '@earendil-works/pi-ai/openai-codex-responses'\nimport { classifyErrorPrelude, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError } from '../errors'\nimport { unsupportedMediaError } from '../prompt'\nimport { SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from '../session/messages'\nimport { renderSystemForWire } from '../system-prompt'\nimport { assertResolvedMediaBlock, documentBlockMarker } from '../types'\nimport { fillEstimatedCost } from './cost'\nimport { extractRuntimeCredentials, resolveOAuthApiKey } from './oauth'\nimport {\n assistantMessage,\n toolResultsMessage,\n userMessage,\n} from './openai-compat'\nimport { sanitizeToolSpecs } from './schema-sanitize'\n\nconst PROVIDER_ID = 'openai-codex'\nconst DEFAULT_MODEL = 'gpt-5.5'\n\ntype CodexModel = PiModel<'openai-codex-responses'>\n\nexport interface OpenAIParams extends OAuthParams {\n accountId?: string\n defaultModel?: string\n transport?: 'sse' | 'websocket' | 'auto'\n /**\n * Extra HTTP headers merged into every request (the streaming Responses call\n * and the token-count endpoint). Use for routing/attribution headers a proxy\n * in front of the OpenAI Codex endpoint consumes. Merged with provider\n * defaults; pi-ai lets these override defaults, so avoid `authorization` /\n * `content-type` unless you intend to replace them.\n */\n extraHeaders?: Record<string, string>\n}\n\n// pi-ai's `getModel` is typed for `KnownProvider` × `keyof models[P]`;\n// we look up by free-form `modelId` (the registry holds string ids at\n// runtime) and let pi-ai's miss-throw fall through via the wider lookup.\nconst lookupModel = getModel as (provider: string, modelId: string) => CodexModel | undefined\n\nfunction resolveModel(modelId: string): CodexModel {\n const model = lookupModel(PROVIDER_ID, modelId)\n if (model)\n return model\n\n const fallback = lookupModel(PROVIDER_ID, DEFAULT_MODEL)\n if (!fallback)\n throw new Error(`OpenAI Codex model registry is missing the default model: ${DEFAULT_MODEL}`)\n\n return { ...fallback, id: modelId, name: modelId }\n}\n\nfunction emptyUsage(): PiUsage {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n }\n}\n\nfunction formatTools(tools: ToolSpec[]): PiTool[] {\n // Codex's Responses API runs the same schema validator as the OpenAI\n // Chat Completions endpoint — apply the same sanitisation pass so MCP\n // tools with non-standard root shapes don't 400 here either.\n const sanitized = sanitizeToolSpecs(tools, { profile: 'openai' })\n return sanitized.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as PiTool['parameters'],\n }))\n}\n\nfunction documentMarker(doc: ToolResultDocumentContent): string {\n return documentBlockMarker(doc, 'document omitted')\n}\n\nfunction piToolResultMessage(\n result: Extract<SessionContentBlock, { type: 'tool_result' }>,\n toolName = '',\n): PiMessage {\n // pi-ai's ToolResultMessage natively accepts (TextContent | ImageContent)[].\n // Map zidane's canonical union directly — no flattening needed.\n const content = typeof result.output === 'string'\n ? [{ type: 'text' as const, text: result.output }]\n : result.output.map((block) => {\n if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'image' as const, data: block.data, mimeType: block.mediaType }\n }\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', 'openai')\n if (block.type === 'video')\n throw unsupportedMediaError('video', 'openai')\n if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'text' as const, text: documentMarker(block) }\n }\n return { type: 'text' as const, text: block.text }\n })\n\n return {\n role: 'toolResult',\n toolCallId: result.callId,\n toolName,\n content,\n isError: result.isError ?? false,\n timestamp: Date.now(),\n }\n}\n\nfunction piUserMessage(\n content: SessionContentBlock[],\n): PiMessage | null {\n for (const b of content) {\n if (b.type === 'audio')\n throw unsupportedMediaError('audio', 'openai')\n if (b.type === 'video')\n throw unsupportedMediaError('video', 'openai')\n }\n\n const textBlocks = content.filter(b => b.type === 'text')\n const imageBlocks = content.filter(b => b.type === 'image')\n const documentBlocks = content.filter(b => b.type === 'document')\n\n if (imageBlocks.length === 0 && textBlocks.length === 0 && documentBlocks.length === 0)\n return null\n\n if (imageBlocks.length === 0 && documentBlocks.length === 0 && textBlocks.length === 1)\n return { role: 'user', content: textBlocks[0].text, timestamp: Date.now() }\n\n return {\n role: 'user',\n content: [\n ...imageBlocks.map((img) => {\n assertResolvedMediaBlock(img, 'OpenAI wire messages')\n return { type: 'image' as const, data: img.data, mimeType: img.mediaType }\n }),\n // NOTE: OpenAI's API natively accepts PDFs (Responses `input_file` /\n // Chat Completions `file`), but pi-ai's message content union is\n // text|image only — it has no file content type — so documents degrade to\n // a marker here. To forward PDFs to OpenAI, route via:\n // openaiCompat({ name: 'openai', apiKey, baseURL: 'https://api.openai.com/v1',\n // capabilities: { documents: true } })\n // which emits the `{type:'file'}` Chat Completions part directly. (That\n // path accepts application/pdf only; spreadsheets/.docx need the\n // Responses API, which would require an input_file content type in pi-ai.)\n ...documentBlocks.map((block) => {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'text' as const, text: documentMarker(block) }\n }),\n ...textBlocks.map(block => ({ type: 'text' as const, text: block.text })),\n ],\n timestamp: Date.now(),\n }\n}\n\nfunction piAssistantMessage(\n content: SessionContentBlock[],\n modelId: string,\n): PiAssistantMessage {\n const piContent: PiAssistantMessage['content'] = []\n for (const block of content) {\n if (block.type === 'text') {\n piContent.push({ type: 'text', text: block.text })\n }\n else if (block.type === 'thinking') {\n // Drop thinking blocks minted by another provider — Anthropic signatures\n // are not valid OpenAI `encrypted_content` and Responses API rejects them.\n if (block.signatureProducer === 'anthropic')\n continue\n piContent.push({ type: 'thinking', thinking: block.text, thinkingSignature: block.signature })\n }\n else if (block.type === 'tool_call') {\n piContent.push({ type: 'toolCall', id: block.id, name: block.name, arguments: block.input })\n }\n // `redacted_thinking` (Anthropic-only) and `provider_reasoning` (provider-\n // bound reasoning state) are intentionally dropped — Codex Responses\n // doesn't accept them.\n }\n\n return {\n role: 'assistant',\n content: piContent,\n api: 'openai-codex-responses',\n provider: PROVIDER_ID,\n model: modelId,\n usage: emptyUsage(),\n stopReason: 'stop',\n timestamp: Date.now(),\n }\n}\n\nexport function toPiMessages(messages: SessionMessage[], modelId: string): PiMessage[] {\n const out: PiMessage[] = []\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]\n const toolCalls = msg.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_call' }> => b.type === 'tool_call')\n\n if (msg.role === 'assistant' && toolCalls.length > 0) {\n const next = messages[i + 1]\n const nextToolResults = next?.role === 'user'\n ? next.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_result' }> => b.type === 'tool_result')\n : []\n const resultById = new Map(nextToolResults.map(result => [result.callId, result]))\n\n let assistantContent: SessionContentBlock[] = []\n for (const block of msg.content) {\n assistantContent.push(block)\n if (block.type !== 'tool_call')\n continue\n\n out.push(piAssistantMessage(assistantContent, modelId))\n assistantContent = []\n\n const result = resultById.get(block.id)\n if (result) {\n out.push(piToolResultMessage(result, block.name))\n }\n else {\n out.push(piToolResultMessage({\n type: 'tool_result',\n callId: block.id,\n output: SYNTHETIC_TOOL_RESULT_PLACEHOLDER,\n isError: true,\n }, block.name))\n }\n }\n if (assistantContent.length > 0)\n out.push(piAssistantMessage(assistantContent, modelId))\n\n if (next?.role === 'user') {\n const remainingUserContent = next.content.filter((block) => {\n if (block.type !== 'tool_result')\n return true\n // Orphan/duplicate tool results should already be removed by the\n // canonical repair pass. If one reaches this adapter, do not send it\n // as an unpaired provider message.\n return false\n })\n const userMessage = piUserMessage(remainingUserContent)\n if (userMessage)\n out.push(userMessage)\n i++\n }\n continue\n }\n\n const toolResults = msg.content.filter(b => b.type === 'tool_result')\n if (toolResults.length > 0) {\n const userMsg = msg.role === 'user'\n ? piUserMessage(msg.content.filter(b => b.type !== 'tool_result'))\n : null\n if (userMsg)\n out.push(userMsg)\n continue\n }\n\n if (msg.role === 'user') {\n const userMsg = piUserMessage(msg.content)\n if (userMsg)\n out.push(userMsg)\n continue\n }\n\n out.push(piAssistantMessage(msg.content, modelId))\n }\n\n return out\n}\n\n/**\n * Map pi-ai's `StopReason` to the zidane `TurnFinishReason` union — the same\n * native-stop-reason fidelity anthropic's `mapStopReason` / openai-compat's\n * `mapOAIFinishReason` provide. Notably `length` (max-token truncation) is no\n * longer misreported as a clean `stop`. `hasToolCalls` is the fallback for\n * messages whose stop reason is missing or doesn't carry the tool-call signal.\n */\nexport function mapCodexStopReason(stopReason: string | undefined, hasToolCalls: boolean): TurnFinishReason {\n switch (stopReason) {\n case 'toolUse':\n return 'tool-calls'\n case 'length':\n return 'length'\n case 'error':\n return 'error'\n case 'stop':\n return hasToolCalls ? 'tool-calls' : 'stop'\n case 'aborted':\n return 'other'\n default:\n return hasToolCalls ? 'tool-calls' : 'stop'\n }\n}\n\nfunction fromPiAssistantMessage(message: PiAssistantMessage): SessionMessage {\n const content: SessionContentBlock[] = []\n\n for (const block of message.content) {\n if (block.type === 'text') {\n content.push({ type: 'text', text: block.text })\n }\n else if (block.type === 'thinking') {\n const out: Extract<SessionContentBlock, { type: 'thinking' }> = {\n type: 'thinking',\n text: block.thinking,\n }\n if (typeof block.thinkingSignature === 'string') {\n out.signature = block.thinkingSignature\n out.signatureProducer = 'openai'\n }\n content.push(out)\n }\n else if (block.type === 'toolCall') {\n content.push({ type: 'tool_call', id: block.id, name: block.name, input: block.arguments })\n }\n }\n\n return { role: 'assistant', content }\n}\n\nfunction extractToolCalls(message: PiAssistantMessage) {\n return message.content\n .filter(block => block.type === 'toolCall')\n .map(block => ({\n id: block.id,\n name: block.name,\n input: block.arguments as Record<string, unknown>,\n }))\n}\n\nfunction extractText(message: PiAssistantMessage): string {\n return message.content\n .filter((block): block is Extract<PiAssistantMessage['content'][number], { type: 'text' }> => block.type === 'text')\n .map(block => block.text)\n .join('')\n}\n\nfunction toTurnUsage(usage: PiUsage, finishReason: TurnFinishReason | undefined, modelId: string) {\n return fillEstimatedCost({\n input: usage.input,\n output: usage.output,\n cacheRead: usage.cacheRead || undefined,\n cacheCreation: usage.cacheWrite || undefined,\n cost: usage.cost.total || undefined,\n ...(finishReason ? { finishReason } : {}),\n modelId,\n }, 'openai')\n}\n\n/**\n * Transient pi-ai error patterns worth a loop-level retry. pi-ai already retries\n * 429 / 5xx pre-stream 3× internally (see `openai-codex-responses.js`); by the\n * time the error reaches us, that budget is exhausted. The loop-level retry\n * with its longer backoff is a second line of defense for capacity events\n * that persist past pi-ai's short retry window, plus mid-stream emissions\n * (pi-ai surfaces those as plain `Error`s with no status).\n *\n * Mirrors pi-ai's own `isRetryableError` regex so the two retry layers\n * recognize the same failure modes.\n */\nconst TRANSIENT_OPENAI_MESSAGE_RE = /rate.?limit|overloaded|service.?unavailable|upstream.?connect|connection.?refused|gateway.?time.?out|temporarily.?unavailable/i\n\n/** Numeric HTTP status codes pi-ai sometimes attaches when bubbling structured errors. */\nfunction isRetryableStatusCode(err: object): boolean {\n const status = (err as { status?: unknown }).status\n if (typeof status !== 'number')\n return false\n return isRetryableHttpStatus(status)\n}\n\n/**\n * Classify an OpenAI Codex error. pi-ai surfaces errors either as thrown `Error`s\n * (wrapping `event.error.errorMessage`) or via stream event types.\n *\n * Retryable hint is set when pi-ai's own retry budget is exhausted on a\n * transient failure — pattern-matched against `message` since pi-ai strips\n * structured fields on plain-Error throws. Set `behavior.retry.maxAttempts: 1`\n * to disable the loop-level retry.\n */\nexport function classifyOpenAIError(err: unknown): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n\n const anyErr = err as { name?: string, message?: string, code?: string, type?: string }\n\n const message = anyErr.message ?? ''\n const code = anyErr.code ?? anyErr.type\n\n if (code === 'context_length_exceeded' || matchesContextExceeded(message)) {\n return {\n kind: 'context_exceeded',\n providerCode: code ?? 'context_length_exceeded',\n message,\n }\n }\n\n if (matchesToolPairingError(message)) {\n return {\n kind: 'tool_pairing_corruption',\n providerCode: code ?? 'invalid_request_error',\n message,\n }\n }\n\n // pi-ai wraps API errors in generic `Error` — treat as provider_error when we have a message.\n if (message.length > 0) {\n const retryable = isRetryableStatusCode(anyErr) || TRANSIENT_OPENAI_MESSAGE_RE.test(message)\n return {\n kind: 'provider_error',\n providerCode: code,\n message,\n ...(retryable ? { retryable: true } : {}),\n }\n }\n\n return null\n}\n\n/**\n * A standard OpenAI API key usable against `api.openai.com` (for the exact\n * token-count endpoint), or `null` when only a Codex-OAuth credential is\n * available. Codex OAuth access tokens are JWTs (`eyJ…`) and are NOT valid\n * bearers for the standard API; a real key looks like `sk-…` (but not the\n * Anthropic `sk-ant-…` form). Checks `params.apiKey` then `OPENAI_API_KEY`.\n */\nfunction pickStandardOpenAIKey(params?: OpenAIParams): string | null {\n const candidates = [params?.apiKey, process.env.OPENAI_API_KEY]\n for (const key of candidates) {\n if (typeof key === 'string' && key.startsWith('sk-') && !key.startsWith('sk-ant-'))\n return key\n }\n return null\n}\n\n/**\n * Convert canonical {@link SessionMessage}s to OpenAI Responses-API `input`\n * items for the token-count endpoint. Only the text-bearing shape is needed\n * here (the count path sends a tiny dummy message); images/tool-results are\n * down-converted to text so the count never throws on an exotic block.\n */\nfunction toResponsesInput(messages: SessionMessage[]): unknown[] {\n return messages.map((msg) => {\n const text = msg.content\n .map(b => (b.type === 'text' ? b.text : ''))\n .filter(Boolean)\n .join('\\n')\n const part = msg.role === 'assistant' ? 'output_text' : 'input_text'\n return { role: msg.role === 'assistant' ? 'assistant' : 'user', content: [{ type: part, text }] }\n })\n}\n\n/** Convert pi-ai `PiTool` specs to Responses-API function tools. */\nfunction toResponsesTools(tools: unknown[]): unknown[] {\n return tools.map((t) => {\n const tool = t as { name?: string, description?: string, parameters?: unknown }\n return {\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }\n })\n}\n\nfunction applyPayloadOverrides(payload: unknown, options: StreamOptions): unknown {\n const body = payload as Record<string, unknown>\n\n if (options.toolChoice) {\n if (options.toolChoice.type === 'tool' && options.toolChoice.name)\n body.tool_choice = { type: 'function', name: options.toolChoice.name }\n else if (options.toolChoice.type === 'required')\n body.tool_choice = 'required'\n else\n body.tool_choice = 'auto'\n }\n\n return body\n}\n\nexport function openai(params?: OpenAIParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n const baseCredentials = extractRuntimeCredentials(params)\n let runtimeCredentials = baseCredentials\n ? { ...baseCredentials, ...(params?.accountId ? { accountId: params.accountId } : {}) }\n : undefined\n\n return {\n name: 'openai',\n meta: {\n defaultModel,\n isOAuth: true,\n capabilities: {\n vision: true,\n imageInToolResult: true,\n // pi-ai's Codex Responses wire has no audio/video input content type.\n audio: false,\n video: false,\n },\n },\n formatTools,\n userMessage,\n assistantMessage,\n toolResultsMessage,\n classifyError: classifyOpenAIError,\n\n async countTokens(payload, signal): Promise<number | null> {\n // The exact count endpoint (`POST /v1/responses/input_tokens`) lives on\n // the standard OpenAI API and needs a standard `OPENAI_API_KEY` bearer.\n // This provider authenticates via Codex OAuth against the Codex backend,\n // whose token is NOT valid for that endpoint — so we only attempt the\n // count when a standard key is present (env or params.apiKey that isn't\n // an OAuth/JWT token). Otherwise return null → heuristic fallback.\n const standardKey = pickStandardOpenAIKey(params)\n if (!standardKey)\n return null\n try {\n const res = await fetch('https://api.openai.com/v1/responses/input_tokens', {\n method: 'POST',\n headers: {\n ...params?.extraHeaders,\n 'authorization': `Bearer ${standardKey}`,\n 'content-type': 'application/json',\n },\n // The Responses `input_tokens` endpoint takes the same shape as\n // `responses.create`: `instructions` (system), `input` (Responses\n // input items — NOT pi-ai messages), and function-shaped `tools`.\n body: JSON.stringify({\n model: payload.model || defaultModel,\n instructions: renderSystemForWire(payload.system),\n input: toResponsesInput(payload.messages),\n tools: toResponsesTools(payload.tools),\n }),\n ...(signal ? { signal } : {}),\n })\n if (!res.ok)\n return null\n const json = (await res.json()) as { input_tokens?: unknown }\n return typeof json.input_tokens === 'number' ? json.input_tokens : null\n }\n catch {\n return null\n }\n },\n\n async stream(options: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n const modelId = options.model || defaultModel\n const model = resolveModel(modelId)\n const apiKey = await resolveOAuthApiKey(\n {\n provider: 'openai',\n providerId: PROVIDER_ID,\n params: runtimeCredentials ? { ...params, ...runtimeCredentials } : params,\n envKey: 'OPENAI_CODEX_API_KEY',\n extraCredentialKeys: ['accountId'],\n missingError: 'No OpenAI Codex OAuth token found. Run `bun run auth --openai` first.',\n refreshError: reason => `OpenAI Codex OAuth token refresh failed. Run \\`bun run auth --openai\\` again. ${reason}`,\n },\n {\n ...callbacks,\n async onOAuthRefresh(ctx) {\n if (ctx.source === 'params') {\n runtimeCredentials = {\n access: ctx.credentials.access,\n refresh: ctx.credentials.refresh,\n expires: ctx.credentials.expires,\n ...(typeof ctx.credentials.accountId === 'string' ? { accountId: ctx.credentials.accountId } : {}),\n }\n }\n await callbacks.onOAuthRefresh?.(ctx)\n },\n },\n )\n // Codex's Responses API has no `cache_control` analogue, but the\n // system-prompt boundary marker is structural metadata that should\n // never reach the model. Strip it via `renderSystemForWire`; the\n // doctrine + env are collapsed into a single byte stream the model\n // sees as one logical prompt.\n const context: PiContext = {\n systemPrompt: renderSystemForWire(options.system),\n messages: toPiMessages(options.messages, modelId),\n tools: options.tools as PiTool[],\n }\n // OpenAI's `reasoning_effort` accepts minimal/low/medium/high. Clamp\n // Anthropic-only upper tiers to `high`; `'adaptive'` degrades to no\n // reasoning rather than forwarding an unknown value the API would reject.\n const reasoningLevel\n = options.thinking && options.thinking !== 'off' && options.thinking !== 'adaptive'\n ? options.thinking === 'xhigh' || options.thinking === 'max' ? 'high' : options.thinking\n : undefined\n const stream = streamOpenAICodexResponses(model, context, {\n apiKey,\n maxTokens: options.maxTokens,\n signal: options.signal,\n transport: params?.transport,\n reasoningEffort: reasoningLevel,\n reasoningSummary: reasoningLevel ? 'auto' : undefined,\n ...(params?.extraHeaders ? { headers: params.extraHeaders } : {}),\n onPayload: payload => applyPayloadOverrides(payload, options),\n })\n\n let finalMessage: PiAssistantMessage | undefined\n let text = ''\n let thinking = ''\n\n for await (const event of stream) {\n if (event.type === 'text_delta') {\n text += event.delta\n callbacks.onText(event.delta)\n }\n else if (event.type === 'thinking_delta') {\n thinking += event.delta\n callbacks.onThinking?.(event.delta)\n }\n else if (event.type === 'thinking_end') {\n const delta = event.content.startsWith(thinking)\n ? event.content.slice(thinking.length)\n : (thinking ? '' : event.content)\n if (delta) {\n thinking += delta\n callbacks.onThinking?.(delta)\n }\n }\n else if (event.type === 'done') {\n finalMessage = event.message\n }\n else if (event.type === 'error') {\n throw new Error(event.error.errorMessage || 'OpenAI Codex API error')\n }\n }\n\n finalMessage ??= await stream.result()\n text ||= extractText(finalMessage)\n\n const toolCalls = extractToolCalls(finalMessage)\n const assistantTurn = fromPiAssistantMessage(finalMessage)\n const finishReason = mapCodexStopReason(finalMessage.stopReason, toolCalls.length > 0)\n\n return {\n assistantMessage: assistantTurn,\n text,\n toolCalls,\n done: toolCalls.length === 0,\n usage: toTurnUsage(finalMessage.usage, finishReason, modelId),\n }\n },\n }\n}\n","import type { Provider, ProviderCapabilities } from '.'\nimport { openaiCompat } from './openai-compat'\n\nconst BASE_URL = 'https://openrouter.ai/api/v1'\n\nexport interface OpenRouterParams {\n apiKey?: string\n defaultModel?: string\n /**\n * Provider capability flags. OpenRouter itself is a router — whether vision,\n * native image-in-tool-result, or document/PDF input are supported depends on\n * the downstream model. Default: `{ vision: true, imageInToolResult: false,\n * documents: true }` — matches the default `anthropic/claude-sonnet-4-6` model\n * (vision + PDF capable; OpenRouter forwards the OpenAI `file` content part to\n * Anthropic/OpenAI/Gemini routes).\n *\n * Override when routing to a known-text-only model (e.g. `meta-llama/llama-3-8b-instruct`),\n * setting the relevant flags to `false`.\n */\n capabilities?: ProviderCapabilities\n /**\n * PDF-parsing engine for OpenRouter's `file-parser` plugin. Applied only when\n * a request carries a forwarded PDF/`file` part. Default `'native'` (free;\n * uses the downstream model's own file support). Set `'mistral-ocr'` for\n * scanned/image PDFs, or `'pdf-text'` for free text-only extraction. See\n * {@link OpenAICompatParams.pdfEngine}.\n */\n pdfEngine?: 'native' | 'pdf-text' | 'mistral-ocr'\n}\n\nfunction getApiKey(params?: OpenRouterParams): string {\n // Resolution order aligned with other providers — explicit params win, env\n // is the fallback. See cerebras.ts for the rationale.\n if (typeof params?.apiKey === 'string' && params.apiKey.length > 0)\n return params.apiKey\n\n if (process.env.OPENROUTER_API_KEY)\n return process.env.OPENROUTER_API_KEY\n\n throw new Error('No OpenRouter API key found. Pass `apiKey` or set OPENROUTER_API_KEY in your environment.')\n}\n\n/**\n * OpenRouter provider.\n *\n * Thin wrapper around {@link openaiCompat} with OpenRouter-specific defaults\n * (base URL, default model) and required attribution headers.\n */\nexport function openrouter(params?: OpenRouterParams): Provider {\n const apiKey = getApiKey(params)\n return openaiCompat({\n name: 'openrouter',\n apiKey,\n baseURL: BASE_URL,\n defaultModel: params?.defaultModel || 'anthropic/claude-sonnet-4-6',\n extraHeaders: {\n 'HTTP-Referer': 'https://github.com/Tahul/zidane',\n 'X-Title': 'zidane',\n },\n capabilities: params?.capabilities ?? { vision: true, imageInToolResult: false, documents: true },\n // Make PDF parsing deterministic. OpenRouter routes to many models, so the\n // default must work on ANY of them: `'pdf-text'` (free, text-only\n // extraction) never 400s regardless of the downstream model's file support.\n // `'native'` would route to the model's own file handling (richer — page\n // images — for gpt-4o / Gemini / Claude) but 400s on text-only models, so\n // it's opt-in via `pdfEngine: 'native'` (or `'mistral-ocr'` for scans).\n pdfEngine: params?.pdfEngine ?? 'pdf-text',\n // OpenRouter honors `cache_control` markers for Anthropic + Gemini routes and\n // silently ignores them for routes that cache automatically. Safe to turn on\n // by default — the caller can still flip `behavior.cache = false` to opt out\n // without needing to re-instantiate the provider.\n cacheBreakpoints: true,\n // OpenRouter speaks the normalized `reasoning` request field and round-trips\n // structured `reasoning_details` on assistant messages. Captured into\n // `provider_reasoning` blocks and echoed back to preserve extended-reasoning\n // state across turns on the same upstream route.\n supportsReasoning: true,\n })\n}\n","/**\n * xAI Grok OAuth flow (SuperGrok / X Premium+).\n *\n * xAI is **not** built into pi-ai, so — like Cursor — we implement the flow\n * here and register it with pi-ai's OAuth registry (`registerXaiOAuthProvider`)\n * so `getOAuthApiKey('xai-oauth', …)` resolves to it during lazy token refresh.\n *\n * Auth shape: OAuth 2.0 + PKCE with a loopback callback server, against xAI's\n * OIDC issuer (`https://auth.x.ai`). Differs from the Anthropic / Codex flows\n * (which use the shared `startCallbackServer`) on three points, so it gets its\n * own login impl rather than reusing that primitive:\n *\n * 1. The `redirect_uri` must be `http://127.0.0.1:56121/callback` verbatim\n * (xAI matches the registered loopback IP, not `localhost`).\n * 2. Endpoints come from OIDC discovery, not hard-coded constants.\n * 3. Token exchange + refresh are `application/x-www-form-urlencoded`\n * (the Anthropic flow posts JSON).\n *\n * The callback page still routes through {@link OAuthCallbackPageRenderer} so\n * the post-redirect HTML matches the rest of zidane's themed flows.\n *\n * Flow + constants adapted from the public reference implementations\n * (`stnly/pi-grok`, `BlockedPath/pi-xai-oauth`) and the Hermes Agent docs.\n * xAI's OAuth surface is unofficial/undocumented — re-verify the client id,\n * scopes, and callback port if login starts failing.\n */\n\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n OAuthProviderInterface,\n} from '@earendil-works/pi-ai/oauth'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { OAuthCallbackPageRenderer } from './render'\nimport { createServer } from 'node:http'\nimport { generatePkce } from './pkce'\n\n/** pi-ai / zidane OAuth provider id. Also the credentials-file key. */\nexport const XAI_OAUTH_PROVIDER_ID = 'xai-oauth'\n\nconst DEFAULT_BASE_URL = 'https://api.x.ai/v1'\nconst ISSUER = 'https://auth.x.ai'\nconst DISCOVERY_URL = `${ISSUER}/.well-known/openid-configuration`\n/** Public client id used by the Grok CLI OAuth surface. */\nconst CLIENT_ID = process.env.PI_XAI_OAUTH_CLIENT_ID || 'b1a00492-073a-47ea-816f-4c329264a828'\nconst SCOPE = process.env.PI_XAI_OAUTH_SCOPE || 'openid profile email offline_access grok-cli:access api:access'\n/** xAI matches the registered loopback IP exactly — `localhost` is rejected. */\nconst CALLBACK_HOST = process.env.PI_XAI_OAUTH_CALLBACK_HOST || '127.0.0.1'\nconst CALLBACK_PORT = Number.parseInt(process.env.PI_XAI_OAUTH_CALLBACK_PORT || '56121', 10)\nconst CALLBACK_PATH = '/callback'\nconst PROVIDER_NAME = 'xAI Grok'\n/** Refresh slightly early so requests don't race expiry. */\nconst REFRESH_SKEW_MS = 120_000\nconst CALLBACK_TIMEOUT_MS = 180_000\n\n/** Resolve the xAI API base URL (env override → default). */\nexport function xaiBaseUrl(): string {\n return (process.env.PI_XAI_BASE_URL || process.env.XAI_BASE_URL || DEFAULT_BASE_URL)\n .replace(/\\/+$/, '')\n}\n\ninterface XaiDiscovery {\n authorization_endpoint: string\n token_endpoint: string\n}\n\n/**\n * xAI OAuth credentials. Extends the base `{ access, refresh, expires }` with\n * the resolved `token_endpoint` so refresh doesn't need a second discovery\n * round-trip, plus the cached discovery doc for validation.\n */\nexport interface XaiOAuthCredentials extends OAuthCredentials {\n tokenEndpoint?: string\n discovery?: XaiDiscovery\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n let binary = ''\n for (const b of bytes)\n binary += String.fromCharCode(b)\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction randomToken(byteLength = 16): string {\n return base64Url(crypto.getRandomValues(new Uint8Array(byteLength)))\n}\n\n/**\n * Refuse any OIDC endpoint that isn't HTTPS on an xAI origin.\n *\n * The discovery doc is cached long-term in `credentials.json`. A single MITM\n * during initial login could otherwise pin a malicious `token_endpoint` that\n * receives every subsequent refresh token. Validating scheme + host keeps the\n * endpoint on `x.ai` / `*.x.ai`.\n */\nfunction validateEndpoint(value: string, field: string): string {\n let url: URL\n try {\n url = new URL(value)\n }\n catch {\n throw new Error(`xAI OAuth discovery returned an invalid ${field}: ${value}`)\n }\n if (url.protocol !== 'https:')\n throw new Error(`xAI OAuth ${field} must use HTTPS: ${value}`)\n const host = url.hostname.toLowerCase()\n if (host !== 'x.ai' && !host.endsWith('.x.ai'))\n throw new Error(`Refusing non-xAI OAuth ${field}: ${value}`)\n return url.toString()\n}\n\nasync function discover(): Promise<XaiDiscovery> {\n let response: Response\n try {\n response = await fetch(DISCOVERY_URL, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(15_000),\n })\n }\n catch (cause) {\n throw new Error(`xAI OIDC discovery failed: ${cause instanceof Error ? cause.message : String(cause)}`)\n }\n if (!response.ok)\n throw new Error(`xAI OIDC discovery returned ${response.status}`)\n\n const payload = await response.json() as Record<string, unknown>\n return {\n authorization_endpoint: validateEndpoint(String(payload.authorization_endpoint ?? ''), 'authorization_endpoint'),\n token_endpoint: validateEndpoint(String(payload.token_endpoint ?? ''), 'token_endpoint'),\n }\n}\n\ninterface CallbackResult {\n code?: string\n state?: string\n error?: string\n errorDescription?: string\n}\n\ninterface XaiCallbackServer {\n redirectUri: string\n waitForCallback: (timeoutMs: number) => Promise<CallbackResult>\n close: () => void\n}\n\n/**\n * Start the loopback callback server on `127.0.0.1:56121`. Falls back to an\n * OS-assigned port if 56121 is taken — xAI accepts any loopback port as long\n * as the `redirect_uri` we send on the authorize URL matches the listener.\n */\nasync function startXaiCallbackServer(renderPage: OAuthCallbackPageRenderer): Promise<XaiCallbackServer> {\n let settle: ((value: CallbackResult) => void) | undefined\n let settled = false\n const callbackPromise = new Promise<CallbackResult>((resolve) => {\n settle = (value) => {\n if (settled)\n return\n settled = true\n resolve(value)\n }\n })\n\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n try {\n // accounts.x.ai may issue a CORS preflight against the loopback listener.\n const origin = req.headers.origin\n if (origin === 'https://accounts.x.ai' || origin === 'https://auth.x.ai') {\n res.setHeader('Access-Control-Allow-Origin', origin)\n res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n res.setHeader('Access-Control-Allow-Private-Network', 'true')\n res.setHeader('Vary', 'Origin')\n }\n if (req.method === 'OPTIONS') {\n res.statusCode = 204\n res.end()\n return\n }\n\n const url = new URL(req.url ?? '/', `http://${CALLBACK_HOST}`)\n if (url.pathname !== CALLBACK_PATH) {\n res.statusCode = 404\n res.end('Not found')\n return\n }\n\n const result: CallbackResult = {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n error: url.searchParams.get('error') ?? undefined,\n errorDescription: url.searchParams.get('error_description') ?? undefined,\n }\n\n res.statusCode = result.error ? 400 : 200\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end(renderPage(result.error\n ? {\n kind: 'error',\n provider: PROVIDER_NAME,\n message: `${PROVIDER_NAME} authentication did not complete.`,\n details: result.errorDescription ?? result.error,\n }\n : {\n kind: 'success',\n provider: PROVIDER_NAME,\n message: 'xAI authentication completed. You can close this window.',\n }))\n settle?.(result)\n }\n catch {\n res.statusCode = 500\n res.end('Internal error')\n }\n })\n\n const listen = (port: number) => new Promise<number>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, CALLBACK_HOST, () => {\n server.removeListener('error', reject)\n const addr = server.address()\n resolve(typeof addr === 'object' && addr ? addr.port : port)\n })\n })\n\n let actualPort: number\n try {\n actualPort = await listen(CALLBACK_PORT)\n }\n catch {\n actualPort = await listen(0)\n }\n\n return {\n redirectUri: `http://${CALLBACK_HOST}:${actualPort}${CALLBACK_PATH}`,\n waitForCallback: timeoutMs => Promise.race([\n callbackPromise,\n new Promise<CallbackResult>(resolve =>\n setTimeout(\n resolve,\n timeoutMs,\n { error: 'timeout', errorDescription: 'Timed out waiting for the xAI OAuth callback.' },\n )),\n ]),\n close: () => {\n try { server.close() }\n catch { /* already closed */ }\n },\n }\n}\n\nfunction expiryFromPayload(payload: Record<string, unknown>): number {\n const expiresIn = typeof payload.expires_in === 'number'\n ? payload.expires_in\n : Number(payload.expires_in ?? 3600)\n return Date.now() + expiresIn * 1000 - REFRESH_SKEW_MS\n}\n\nasync function exchangeCode(\n tokenEndpoint: string,\n code: string,\n redirectUri: string,\n verifier: string,\n discovery: XaiDiscovery,\n): Promise<XaiOAuthCredentials> {\n const response = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code,\n redirect_uri: redirectUri,\n code_verifier: verifier,\n }),\n signal: AbortSignal.timeout(30_000),\n })\n if (!response.ok)\n throw new Error(`xAI token exchange failed: ${response.status} ${await response.text().catch(() => '')}`)\n\n const payload = await response.json() as Record<string, unknown>\n const access = String(payload.access_token ?? '')\n const refresh = String(payload.refresh_token ?? '')\n if (!access)\n throw new Error('xAI token exchange did not return an access_token.')\n if (!refresh)\n throw new Error('xAI token exchange did not return a refresh_token.')\n\n return { access, refresh, expires: expiryFromPayload(payload), tokenEndpoint, discovery }\n}\n\nexport async function loginXai(\n renderPage: OAuthCallbackPageRenderer,\n callbacks: OAuthLoginCallbacks,\n): Promise<XaiOAuthCredentials> {\n const discovery = await discover()\n const { verifier, challenge } = await generatePkce()\n const state = randomToken()\n const nonce = randomToken()\n const server = await startXaiCallbackServer(renderPage)\n\n try {\n const authUrl = new URL(discovery.authorization_endpoint)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('client_id', CLIENT_ID)\n authUrl.searchParams.set('redirect_uri', server.redirectUri)\n authUrl.searchParams.set('scope', SCOPE)\n authUrl.searchParams.set('code_challenge', challenge)\n authUrl.searchParams.set('code_challenge_method', 'S256')\n authUrl.searchParams.set('state', state)\n authUrl.searchParams.set('nonce', nonce)\n // Opt into xAI's generic OAuth plan tier (SuperGrok / X Premium+).\n authUrl.searchParams.set('plan', 'generic')\n authUrl.searchParams.set('referrer', 'zidane')\n\n callbacks.onAuth({\n url: authUrl.toString(),\n instructions: `Sign in to xAI and approve access. If the browser is on another machine, the callback listener is ${server.redirectUri}.`,\n })\n\n const result = await server.waitForCallback(CALLBACK_TIMEOUT_MS)\n if (result.error)\n throw new Error(result.errorDescription ?? result.error)\n if (result.state !== state)\n throw new Error('xAI OAuth state mismatch — possible CSRF. Please retry.')\n if (!result.code)\n throw new Error('xAI OAuth callback did not include an authorization code.')\n\n callbacks.onProgress?.('Exchanging authorization code for tokens...')\n return await exchangeCode(discovery.token_endpoint, result.code, server.redirectUri, verifier, discovery)\n }\n finally {\n server.close()\n }\n}\n\nexport async function refreshXaiToken(credentials: OAuthCredentials): Promise<XaiOAuthCredentials> {\n const xai = credentials as XaiOAuthCredentials\n if (!credentials.refresh)\n throw new Error('xAI credentials are missing a refresh token — re-login required.')\n\n const tokenEndpoint = xai.tokenEndpoint\n ?? xai.discovery?.token_endpoint\n ?? (await discover()).token_endpoint\n validateEndpoint(tokenEndpoint, 'token_endpoint')\n\n const response = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: CLIENT_ID,\n refresh_token: credentials.refresh,\n }),\n signal: AbortSignal.timeout(30_000),\n })\n if (!response.ok)\n throw new Error(`xAI token refresh failed: ${response.status} ${await response.text().catch(() => '')}`)\n\n const payload = await response.json() as Record<string, unknown>\n const access = String(payload.access_token ?? '')\n if (!access)\n throw new Error('xAI token refresh did not return an access_token.')\n\n return {\n ...xai,\n access,\n // xAI may omit a rotated refresh token — keep the existing one.\n refresh: String(payload.refresh_token ?? credentials.refresh),\n expires: expiryFromPayload(payload),\n tokenEndpoint,\n }\n}\n\n/**\n * Build an xAI `OAuthProviderInterface`. Shape matches Anthropic / Codex /\n * Cursor so it drops into `BUILTIN_PROVIDERS` and `src/auth.ts` unchanged.\n *\n * `usesCallbackServer: true` — the loopback flow has a real callback server,\n * so the TUI doesn't need to prompt for a manual code paste.\n */\nexport function createXaiOAuthProvider(renderPage: OAuthCallbackPageRenderer): OAuthProviderInterface {\n return {\n id: XAI_OAUTH_PROVIDER_ID,\n name: 'xAI Grok (SuperGrok / X Premium+)',\n usesCallbackServer: true,\n login: callbacks => loginXai(renderPage, callbacks),\n refreshToken: refreshXaiToken,\n getApiKey: credentials => credentials.access,\n }\n}\n","import type { Provider, ProviderCapabilities, StreamCallbacks, StreamOptions, TurnResult } from '.'\nimport type { OAuthParams } from './oauth'\nimport { XAI_OAUTH_PROVIDER_ID, xaiBaseUrl } from '../chat/oauth-page/xai'\nimport { extractRuntimeCredentials, isOAuthAccessToken, resolveOAuthApiKey } from './oauth'\nimport { openaiCompat } from './openai-compat'\n\nconst DEFAULT_MODEL = 'grok-4.3'\n\n/**\n * xAI Grok provider — supports both a static API key (`XAI_API_KEY`) and the\n * SuperGrok / X Premium+ OAuth subscription.\n *\n * Both auth modes hit the same OpenAI-compatible endpoint (`https://api.x.ai/v1`),\n * so the wire handling is entirely {@link openaiCompat}. The only difference is\n * the bearer:\n *\n * - **API key**: `XAI_API_KEY` (or `params.apiKey`) → used verbatim.\n * - **OAuth**: no static key → {@link resolveOAuthApiKey} resolves + lazily\n * refreshes the stored `xai-oauth` token on every turn.\n *\n * `resolveOAuthApiKey` unifies the two: a real API key in `XAI_API_KEY` is\n * returned as-is, while an OAuth access token (or no env value at all) falls\n * through to the refreshable stored credentials. So this single factory serves\n * both paths without branching at construction time.\n */\nexport interface XaiParams extends OAuthParams {\n defaultModel?: string\n /**\n * Provider capability flags. Grok models are vision-capable; default\n * `{ vision: true, imageInToolResult: false }`. Override for text-only\n * deployments.\n */\n capabilities?: ProviderCapabilities\n /** Extra HTTP headers sent on every request. */\n extraHeaders?: Record<string, string>\n}\n\nexport function xai(params?: XaiParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n const baseURL = xaiBaseUrl()\n const capabilities: ProviderCapabilities = params?.capabilities ?? {\n vision: true,\n imageInToolResult: false,\n }\n const baseCredentials = extractRuntimeCredentials(params)\n let runtimeCredentials = baseCredentials\n\n // Factory-time snapshot for the static `meta.isOAuth` display flag only (the\n // terminal header's `oauth`/`key` badge). The real bearer resolves per turn\n // in `stream`, so this is best-effort, mirroring anthropic's pattern. It's\n // OAuth unless a genuine static API key is present: a `xai-…` key → key mode;\n // runtime OAuth creds, a JWT access token, or no static key (stored creds\n // used) → oauth mode.\n const staticKey = params?.apiKey ?? process.env.XAI_API_KEY\n const isOAuth = baseCredentials !== undefined || !staticKey || isOAuthAccessToken(staticKey)\n\n /**\n * Build the openai-compat delegate for a resolved bearer. Cheap — the factory\n * only wires closures — so we re-create it per turn with the freshly resolved\n * (possibly refreshed) OAuth token rather than baking a stale key in once.\n */\n function delegateFor(apiKey: string): Provider {\n return openaiCompat({\n name: 'xai',\n apiKey,\n baseURL,\n defaultModel,\n capabilities,\n extraHeaders: params?.extraHeaders,\n })\n }\n\n // A delegate built with a placeholder key supplies the non-stream methods\n // (formatTools, userMessage, message builders, classifyError). Only `stream`\n // resolves the real bearer, so the placeholder never reaches the wire.\n const skeleton = delegateFor('placeholder-resolved-at-stream')\n\n return {\n ...skeleton,\n name: 'xai',\n // Reuse the delegate's normalized capability flags (openaiCompat fills the\n // audio/video/documents defaults) so the advertised shape matches the wire.\n meta: { ...skeleton.meta, defaultModel, isOAuth },\n\n async stream(options: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n const apiKey = await resolveOAuthApiKey(\n {\n provider: 'xai',\n providerId: XAI_OAUTH_PROVIDER_ID,\n params: runtimeCredentials ? { ...params, ...runtimeCredentials } : params,\n envKey: 'XAI_API_KEY',\n missingError: 'No xAI credentials found. Set XAI_API_KEY or run `bun run auth --xai` first.',\n refreshError: reason => `xAI OAuth token refresh failed. Run \\`bun run auth --xai\\` again. ${reason}`,\n },\n {\n ...callbacks,\n async onOAuthRefresh(ctx) {\n // Keep param-sourced credentials current so a long-lived provider\n // instance reuses the rotated token instead of re-refreshing.\n if (ctx.source === 'params') {\n runtimeCredentials = {\n access: ctx.credentials.access,\n refresh: ctx.credentials.refresh,\n expires: ctx.credentials.expires,\n }\n }\n await callbacks.onOAuthRefresh?.(ctx)\n },\n },\n )\n\n return delegateFor(apiKey).stream(options, callbacks)\n },\n }\n}\n"],"mappings":"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"}
|
package/dist/providers.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { At as
|
|
2
|
-
export { type AnthropicParams, type ArceeParams, type BasetenParams, type CerebrasParams, type CursorParams, type LocalParams, type OpenAICompatAuthHeader, OpenAICompatHttpError, type OpenAICompatParams, type OpenAIParams, type OpenRouterParams, Provider, ProviderCapabilities, type SchemaSanitizeOptions, type SchemaSanitizeProfile, type SchemaSanitizeResult, StreamCallbacks, StreamOptions, TokenCountPayload, ToolCall, ToolResult, ToolSpec, TurnResult, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs };
|
|
1
|
+
import { $t as applyAnthropicCacheBreakpoints, At as OpenRouterParams, Bt as LocalParams, Ct as XaiParams, Dt as SchemaSanitizeResult, Et as SchemaSanitizeProfile, Ft as classifyOpenAICompatError, Gt as cerebras, Ht as CursorParams, It as mapOAIFinishReason, Jt as planBasetenReasoning, Kt as BasetenParams, Lt as openaiCompat, Mt as OpenAICompatAuthHeader, Nt as OpenAICompatHttpError, Ot as sanitizeToolSchema, Pt as OpenAICompatParams, Qt as anthropic, Rt as OpenAIParams, St as TurnResult, Tt as SchemaSanitizeOptions, Ut as cursor, Vt as local, Wt as CerebrasParams, Xt as arcee, Yt as ArceeParams, Zt as AnthropicParams, _t as StreamOptions, bt as ToolResult, gt as StreamCallbacks, ht as ProviderCapabilities, jt as openrouter, kt as sanitizeToolSpecs, mt as Provider, qt as baseten, vt as TokenCountPayload, wt as xai, xt as ToolSpec, yt as ToolCall, zt as openai } from "./agent-CVTAoYS0.js";
|
|
2
|
+
export { type AnthropicParams, type ArceeParams, type BasetenParams, type CerebrasParams, type CursorParams, type LocalParams, type OpenAICompatAuthHeader, OpenAICompatHttpError, type OpenAICompatParams, type OpenAIParams, type OpenRouterParams, Provider, ProviderCapabilities, type SchemaSanitizeOptions, type SchemaSanitizeProfile, type SchemaSanitizeResult, StreamCallbacks, StreamOptions, TokenCountPayload, ToolCall, ToolResult, ToolSpec, TurnResult, type XaiParams, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs, xai };
|
package/dist/providers.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as local, d as planBasetenReasoning, f as arcee, i as openai, l as cerebras, m as applyAnthropicCacheBreakpoints, o as cursor, p as anthropic, r as openrouter, t as xai, u as baseten } from "./providers-C_zClj1S.js";
|
|
2
2
|
import { C as sanitizeToolSchema, b as openaiCompat, g as OpenAICompatHttpError, v as classifyOpenAICompatError, w as sanitizeToolSpecs, y as mapOAIFinishReason } from "./messages-9wyCuvLF.js";
|
|
3
|
-
export { OpenAICompatHttpError, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs };
|
|
3
|
+
export { OpenAICompatHttpError, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs, xai };
|
package/dist/restate.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ln as ToolResultContent, Nn as ToolBatchExecutor, R as SessionStore, _t as StreamOptions, b as ToolDef, en as AgentBehavior, mt as Provider, tn as AgentClock, y as ToolContext } from "./agent-CVTAoYS0.js";
|
|
2
2
|
import { o as DetachedTasksCapability } from "./types-B39tBba1.js";
|
|
3
3
|
|
|
4
4
|
//#region src/restate/types.d.ts
|
package/dist/session/sqlite.d.ts
CHANGED
package/dist/session.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { B as demoteStaleRunningStatus,
|
|
1
|
+
import { B as demoteStaleRunningStatus, F as Session, G as FileMapAdapter, H as RemoteStoreOptions, I as SessionData, K as FileMapStoreOptions, L as SessionRun, On as SessionMessage, P as CreateSessionOptions, R as SessionStore, Tn as SessionContentBlock, U as createRemoteStore, V as loadSession, W as createMemoryStore, ct as fromAnthropic, dt as toAnthropic, ft as toOpenAI, kn as SessionTurn, lt as fromOpenAI, pt as toWireMessages, q as createFileMapStore, rt as autoDetectAndConvert, tt as ToWireMessagesOptions, z as createSession } from "./agent-CVTAoYS0.js";
|
|
2
2
|
export { CreateSessionOptions, type FileMapAdapter, type FileMapStoreOptions, type RemoteStoreOptions, Session, type SessionContentBlock, SessionData, type SessionMessage, SessionRun, SessionStore, type SessionTurn, type ToWireMessagesOptions, autoDetectAndConvert, createFileMapStore, createMemoryStore, createRemoteStore, createSession, demoteStaleRunningStatus, fromAnthropic, fromOpenAI, loadSession, toAnthropic, toOpenAI, toWireMessages };
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as SkillDiagnostic, M as SkillSource, N as SkillsConfig, O as ShellInterpolationApproval, c as DeactivationReason, d as createSkillActivationState, j as SkillResource, k as SkillConfig, l as SkillActivationState, o as ActivationVia, s as ActiveSkill, u as SkillActivationStateOptions } from "./agent-
|
|
2
|
-
import { C as buildCatalog, S as parseSkillFile, T as installAllowedToolsGate, _ as SourcedScanPath, a as SkillValidationResult, b as inferSource, c as parseAllowedToolPattern, d as validateSkillForWrite, f as validateSkillName, g as stripShellInterpolations, h as interpolateShellCommands, i as SkillValidationIssue, l as validateResourcePath, m as InterpolateShellCommandsOptions, n as writeSkillToDisk, o as isToolAllowedByUnion, p as resolveSkills, r as writeSkillsToDisk, s as matchesAllowedTool, t as defineSkill, u as validateResourcePathReal, v as discoverSkills, w as IMPLICITLY_ALLOWED_SKILL_TOOLS, x as parseFrontmatter, y as getDefaultScanPaths } from "./index-
|
|
1
|
+
import { A as SkillDiagnostic, M as SkillSource, N as SkillsConfig, O as ShellInterpolationApproval, c as DeactivationReason, d as createSkillActivationState, j as SkillResource, k as SkillConfig, l as SkillActivationState, o as ActivationVia, s as ActiveSkill, u as SkillActivationStateOptions } from "./agent-CVTAoYS0.js";
|
|
2
|
+
import { C as buildCatalog, S as parseSkillFile, T as installAllowedToolsGate, _ as SourcedScanPath, a as SkillValidationResult, b as inferSource, c as parseAllowedToolPattern, d as validateSkillForWrite, f as validateSkillName, g as stripShellInterpolations, h as interpolateShellCommands, i as SkillValidationIssue, l as validateResourcePath, m as InterpolateShellCommandsOptions, n as writeSkillToDisk, o as isToolAllowedByUnion, p as resolveSkills, r as writeSkillsToDisk, s as matchesAllowedTool, t as defineSkill, u as validateResourcePathReal, v as discoverSkills, w as IMPLICITLY_ALLOWED_SKILL_TOOLS, x as parseFrontmatter, y as getDefaultScanPaths } from "./index-BuIaw3r3.js";
|
|
3
3
|
export { type ActivationVia, type ActiveSkill, type DeactivationReason, IMPLICITLY_ALLOWED_SKILL_TOOLS, type InterpolateShellCommandsOptions, type ShellInterpolationApproval, type SkillActivationState, type SkillActivationStateOptions, type SkillConfig, type SkillDiagnostic, type SkillResource, type SkillSource, type SkillValidationIssue, type SkillValidationResult, type SkillsConfig, type SourcedScanPath, buildCatalog, createSkillActivationState, defineSkill, discoverSkills, getDefaultScanPaths, inferSource, installAllowedToolsGate, interpolateShellCommands, isToolAllowedByUnion, matchesAllowedTool, parseAllowedToolPattern, parseFrontmatter, parseSkillFile, resolveSkills, stripShellInterpolations, validateResourcePath, validateResourcePathReal, validateSkillForWrite, validateSkillName, writeSkillToDisk, writeSkillsToDisk };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Mn as ThinkingLevel, mt as Provider } from "./agent-CVTAoYS0.js";
|
|
2
2
|
import { OAuthProviderInterface } from "@earendil-works/pi-ai/oauth";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
@@ -1468,4 +1468,4 @@ declare function displayNameFor(name: string, input?: Record<string, unknown>):
|
|
|
1468
1468
|
declare function formatToolCall(name: string, input: Record<string, unknown>): ToolFormatLine | null;
|
|
1469
1469
|
//#endregion
|
|
1470
1470
|
export { anthropicDescriptor as $, SessionMeta as A, collectReferences as B, EditHunk as C, Owner as D, EditPayload as E, CompletionContext as F, ProviderKey as G, mergeReferences as H, CompletionItem as I, CustomField as J, detectAuth as K, CompletionProvider as L, StreamEvent as M, ToolCallDisplay as N, Picked as O, ActiveTrigger as P, ProviderDescriptor as Q, CompletionReference as R, EditDiffDisplay as S, EditOutcomeKind as T, AuthMethod as U, findActiveTrigger as V, ProviderAuth as W, ModelOption as X, ModelInfo as Y, OUTPUT_RESERVE_TOKENS as Z, isEditErrorResult as _, formatToolCall as a, getModelInfo as at, selectableTurnIds as b, splitPromptSegments as c, modelSupportsReasoning as ct, RequestApproval as d, openrouterDescriptor as dt, cerebrasDescriptor as et, SafeModeActions as f, piIdOf as ft, EDIT_TOOL_NAMES as g, useSafeModeQueue as h, displayNameFor as i, getContextWindow as it, Settings as j, Screen as k, ApprovalDecision as l, modelsForDescriptor as lt, useSafeModeActions as m, ToolDisplayMeta as n, effectiveContextWindow as nt, PromptSegment as o, localDescriptor as ot, SafeModeProvider as p, restoreModelOptions as pt, BUILTIN_PROVIDERS as q, ToolFormatLine as r, enabledModelOptions as rt, PromptSegmentRef as s, modelOptionsFor as st, TOOL_DISPLAY as t, credKeyOf as tt, ApprovalRequest as u, openaiDescriptor as ut, isTurnHighlighted as v, EditOutcome as w, turnSelectionOwnership as x, isVisible as y, applyInsert as z };
|
|
1471
|
-
//# sourceMappingURL=tool-formatters-
|
|
1471
|
+
//# sourceMappingURL=tool-formatters-Chwpa2Ix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-formatters-Chwpa2Ix.d.ts","names":[],"sources":["../src/chat/providers.ts","../src/chat/auth.ts","../src/chat/completion-core.ts","../src/chat/types.ts","../src/chat/turn-selection.ts","../src/chat/safe-mode-context.tsx","../src/chat/prompt-segments.ts","../src/chat/tool-formatters.ts"],"mappings":"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"}
|