@justin06lee/yagami 0.8.1 → 0.8.2
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 +1 -1
- package/dist/{chunk-U3RFT7QV.js → chunk-EKN223KD.js} +153 -39
- package/dist/chunk-EKN223KD.js.map +1 -0
- package/dist/{chunk-4S5QNDQK.js → chunk-UGIJV6FZ.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +17 -1
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-U3RFT7QV.js.map +0 -1
- /package/dist/{chunk-4S5QNDQK.js.map → chunk-UGIJV6FZ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/core/errors.ts","../src/core/provider.ts","../src/core/executable.ts","../src/version.ts","../src/core/providers/acp.ts","../src/core/interaction.ts","../src/core/providers/process.ts","../src/core/providers/queue.ts","../src/core/providers/claude.ts","../src/core/providers/codex.ts","../src/core/providers/codexSession.ts","../src/core/providers/jsonl.ts","../src/core/providers/registry.ts","../src/core/sessionCache.ts","../src/core/engine.ts","../src/core/sse.ts","../src/core/transcript.ts","../src/core/serverTools.ts","../src/core/hostConfig.ts","../src/core/openai.ts"],"sourcesContent":["/**\n * Anthropic Messages API shapes (the subset yagami implements) and the error\n * type shared across the engine and the HTTP layer.\n */\n\nexport type ApiErrorType =\n | \"invalid_request_error\"\n | \"authentication_error\"\n | \"permission_error\"\n | \"not_found_error\"\n | \"rate_limit_error\"\n | \"api_error\"\n | \"overloaded_error\";\n\nexport class ApiError extends Error {\n constructor(\n readonly status: number,\n readonly type: ApiErrorType,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n\n toBody(): { type: \"error\"; error: { type: ApiErrorType; message: string } } {\n return { type: \"error\", error: { type: this.type, message: this.message } };\n }\n}\n\nexport interface ContentBlockParam {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface TextBlockParam extends ContentBlockParam {\n type: \"text\";\n text: string;\n}\n\nexport type SystemParam = string | TextBlockParam[];\n\nexport interface MessageParam {\n role: \"user\" | \"assistant\";\n content: string | ContentBlockParam[];\n}\n\nexport interface ThinkingParam {\n type: \"enabled\" | \"disabled\" | \"adaptive\" | string;\n budget_tokens?: number;\n}\n\nexport interface MessagesRequest {\n model?: string;\n messages: MessageParam[];\n system?: SystemParam;\n max_tokens?: number;\n stream?: boolean;\n temperature?: number;\n top_p?: number;\n top_k?: number;\n stop_sequences?: string[];\n metadata?: Record<string, unknown>;\n service_tier?: string;\n thinking?: ThinkingParam;\n tools?: unknown;\n tool_choice?: unknown;\n /** yagami extension: Claude Code reasoning effort for this request. */\n effort?: string;\n [key: string]: unknown;\n}\n\nexport interface Usage {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n}\n\nexport interface ContentBlock {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface MessagesResponse {\n id: string;\n type: \"message\";\n role: \"assistant\";\n model: string;\n content: ContentBlock[];\n stop_reason: string | null;\n stop_sequence: string | null;\n usage: Usage;\n}\n\n/** One server-sent event, pre-serialization. */\nexport interface SseEvent {\n event: string;\n data: unknown;\n}\n","import { ApiError } from \"./types.js\";\n\n/** Base class for typed yagami failures — every subclass carries a stable `code`. */\nexport class YagamiError extends Error {\n constructor(\n message: string,\n readonly code: string,\n ) {\n super(message);\n this.name = \"YagamiError\";\n }\n}\n\n/** The provider's CLI could not be found on this machine. */\nexport class ProviderNotInstalledError extends YagamiError {\n constructor(\n readonly provider: string,\n readonly installHint: string,\n detail?: string,\n ) {\n super(\n `${provider}: CLI not found${detail ? ` (${detail})` : \"\"}. ${installHint}`,\n \"provider_not_installed\",\n );\n this.name = \"ProviderNotInstalledError\";\n }\n}\n\n/** The provider's CLI is installed but not logged in (or its login expired). */\nexport class AuthRequiredError extends YagamiError {\n constructor(\n readonly provider: string,\n readonly loginCommand: string,\n detail?: string,\n ) {\n super(\n `${provider}: not logged in${detail ? ` (${detail})` : \"\"}. Run: ${loginCommand}`,\n \"auth_required\",\n );\n this.name = \"AuthRequiredError\";\n }\n}\n\n/** The provider ran but failed — process crash, protocol error, engine error. */\nexport class ProviderError extends YagamiError {\n constructor(\n readonly provider: string,\n message: string,\n ) {\n super(`${provider}: ${message}`, \"provider_error\");\n this.name = \"ProviderError\";\n }\n}\n\n/** Result of comparing an SDK build against the CLI binary it drives. */\nexport interface VersionSkew {\n sdkVersion: string;\n binaryVersion: string;\n inSync: boolean;\n note: string;\n}\n\nconst AUTH_PATTERNS: RegExp[] = [\n /not logged in/i,\n /login required/i,\n /please (run|use) [`'\"]?\\/?login/i,\n /invalid api key/i,\n /authentication[_ ]error/i,\n /auth(entication)? required/i,\n /not authenticated/i,\n /unauthorized/i,\n /credentials? (are|is) (missing|invalid|expired)/i,\n /token (has )?expired/i,\n /no credentials/i,\n];\n\n/** Does this error text look like a sign-in problem rather than a crash? */\nexport function looksLikeAuthFailure(text: string): boolean {\n return AUTH_PATTERNS.some((re) => re.test(text));\n}\n\n/**\n * Normalize any thrown value into a typed yagami error for `provider`,\n * recognizing sign-in failures by message.\n */\nexport function classifyProviderFailure(provider: string, loginCommand: string, err: unknown): YagamiError {\n if (err instanceof YagamiError) return err;\n const message = err instanceof Error ? err.message : String(err);\n if (looksLikeAuthFailure(message)) {\n return new AuthRequiredError(provider, loginCommand, message.split(\"\\n\")[0]?.slice(0, 200));\n }\n return new ProviderError(provider, message);\n}\n\n/** Map any failure onto the Anthropic-shaped HTTP error the API returns. */\nexport function toApiError(err: unknown): ApiError {\n if (err instanceof ApiError) return err;\n if (err instanceof AuthRequiredError || err instanceof ProviderNotInstalledError) {\n return new ApiError(503, \"api_error\", err.message);\n }\n if (err instanceof YagamiError) return new ApiError(500, \"api_error\", err.message);\n const message = err instanceof Error ? err.message : String(err);\n return new ApiError(500, \"api_error\", `engine error: ${message}`);\n}\n","import type { ContentBlockParam, ThinkingParam, Usage } from \"./types.js\";\nimport type { EngineModel } from \"./models.js\";\n\n/** What a provider can natively honor; the engine emulates or rejects the rest. */\nexport interface ProviderCapabilities {\n /** Can continue a previous session by id (otherwise history is replayed as text). */\n resume: boolean;\n /** Resuming leaves the original session intact (branches are safe). */\n fork: boolean;\n images: boolean;\n documents: boolean;\n systemPrompt: boolean;\n thinking: boolean;\n effort: boolean;\n /** Token-level deltas or whole chunks per message part. */\n streaming: \"tokens\" | \"chunks\";\n /**\n * Can run Anthropic server tools (web search/fetch) inside the turn. Still\n * completions-only: results are folded into the reply, never emitted as\n * `tool_use` blocks for the caller to execute.\n */\n serverTools: boolean;\n}\n\n/** One completion turn, already normalized by the engine. */\nexport interface TurnRequest {\n /** Full prompt text (history already flattened, prefill directive appended). */\n prompt: string;\n /** Image/document blocks (Anthropic shape) attached to the prompt. */\n media?: ContentBlockParam[];\n system?: string;\n /** Provider-native model id; undefined means the provider's own default. */\n model?: string;\n /** Provider session id to continue. */\n resume?: string;\n thinking?: ThinkingParam;\n effort?: string;\n /** CLI tool names to enable for this turn (see `core/serverTools.ts`). */\n serverTools?: string[];\n signal?: AbortSignal;\n}\n\nexport type TurnEvent =\n | { type: \"session\"; sessionId: string }\n | { type: \"text\"; text: string }\n | { type: \"thinking\"; text: string }\n | {\n type: \"done\";\n usage: Usage;\n costUsd?: number;\n model?: string;\n stopReason?: string;\n };\n\n/**\n * A coding-agent harness yagami can drive: a signed-in CLI on this machine,\n * wrapped so the engine can run sandboxed completion turns through it.\n */\nexport interface Provider {\n readonly id: string;\n readonly label: string;\n /** Resolved path of the CLI binary (for diagnostics). */\n readonly executable: string;\n readonly capabilities: ProviderCapabilities;\n /** Shell command that signs the CLI in, for error messages. */\n readonly loginCommand: string;\n /** Run one sandboxed completion turn. Throws typed errors on failure. */\n run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined>;\n /** Models the CLI reports as available (may spawn a short-lived process). */\n listModels(): Promise<EngineModel[]>;\n /** CLI version string, if it can be determined. */\n version(): Promise<string | undefined>;\n}\n\nexport interface ModelRef {\n providerId?: string;\n model?: string;\n}\n\n/**\n * Split a request's `model` into provider + native model. `\"codex:gpt-5\"`\n * routes to codex; a bare provider id (`\"codex\"`) means that provider's\n * default model; anything else is a model for the default provider. The\n * split happens only at the first colon and only when the prefix names a\n * known provider, so ids like `\"ollama/llama3:8b\"` stay intact.\n */\nexport function parseModelRef(model: string | undefined, providerIds: Iterable<string>): ModelRef {\n if (!model) return {};\n const ids = new Set(providerIds);\n if (ids.has(model)) return { providerId: model };\n const colon = model.indexOf(\":\");\n if (colon > 0) {\n const prefix = model.slice(0, colon);\n if (ids.has(prefix)) {\n const rest = model.slice(colon + 1);\n return rest ? { providerId: prefix, model: rest } : { providerId: prefix };\n }\n }\n return { model };\n}\n\nexport function qualifiedModel(providerId: string, model: string): string {\n return `${providerId}:${model}`;\n}\n\n// ---------------------------------------------------------------------------\n// Agentic sessions (library mode): tools, permissions, the works.\n// ---------------------------------------------------------------------------\n\nexport type SessionPermissionDecision = \"allow\" | \"allow_always\" | \"deny\" | \"deny_always\";\n\nexport type SessionInputValue = string | number | boolean | string[];\n\nexport interface SessionInputOption {\n value: string;\n label: string;\n description?: string;\n}\n\n/** One renderable field from a harness question or MCP elicitation. */\nexport interface SessionInputField {\n id: string;\n label: string;\n description?: string;\n type: \"string\" | \"number\" | \"integer\" | \"boolean\" | \"select\" | \"multiselect\";\n required: boolean;\n secret?: boolean;\n allowOther?: boolean;\n options?: SessionInputOption[];\n format?: string;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n default?: SessionInputValue;\n}\n\n/** A provider-neutral blocking request for human input. */\nexport interface SessionInputRequest {\n provider: string;\n sessionId?: string;\n kind: \"questions\" | \"form\" | \"url\";\n message: string;\n source?: string;\n fields?: SessionInputField[];\n url?: string;\n blocking?: boolean;\n raw?: unknown;\n}\n\nexport type SessionInputResponse =\n | { action: \"accept\"; values?: Record<string, SessionInputValue> }\n | { action: \"decline\" | \"cancel\" };\n\nexport interface SessionInputHandler {\n respond(req: SessionInputRequest, signal?: AbortSignal): Promise<SessionInputResponse>;\n}\n\nexport type SessionPlanStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface SessionPlanEntry {\n content: string;\n status: SessionPlanStatus;\n priority?: \"high\" | \"medium\" | \"low\";\n}\n\nexport interface SessionPlan {\n id?: string;\n explanation?: string;\n entries?: SessionPlanEntry[];\n markdown?: string;\n uri?: string;\n removed?: boolean;\n}\n\n/** A harness asking the host whether a tool may run. */\nexport interface SessionPermissionRequest {\n provider: string;\n sessionId?: string;\n /** Tool name as the harness calls it (e.g. \"Bash\", \"Edit\", or an ACP title). */\n tool: string;\n /** Coarse category when known: read | edit | delete | execute | fetch | other … */\n kind?: string;\n title?: string;\n input?: unknown;\n /** Provider-native payload for hosts that want to go deep. */\n raw?: unknown;\n}\n\nexport interface SessionPermissionHandler {\n decide(req: SessionPermissionRequest, signal?: AbortSignal): Promise<SessionPermissionDecision>;\n}\n\nexport type AgentEvent =\n | { type: \"session\"; sessionId: string }\n /** Provider-native turn id, used by hosts to fork an exact exchange. */\n | { type: \"turn\"; id: string }\n | { type: \"text\"; text: string }\n | { type: \"thinking\"; text: string }\n | {\n type: \"tool_call\";\n id: string;\n name: string;\n status: \"started\" | \"updated\" | \"completed\" | \"failed\";\n title?: string;\n kind?: string;\n input?: unknown;\n output?: unknown;\n }\n | { type: \"permission\"; request: SessionPermissionRequest; decision: SessionPermissionDecision }\n | { type: \"plan\"; plan: SessionPlan }\n | { type: \"done\"; usage?: Usage; costUsd?: number; stopReason?: string }\n /** Anything the harness said that has no normalized shape. */\n | { type: \"raw\"; provider: string; payload: unknown };\n\nexport interface ProviderSessionOptions {\n /** Project directory the agent works in. */\n cwd: string;\n model?: string;\n /** Provider session id to continue. */\n resume?: string;\n /** Fork the resumed session instead of continuing it in place. */\n fork?: boolean;\n /** Fork the resumed session through this provider-native turn, inclusive. */\n forkAt?: string;\n /**\n * \"terminal\" loads the same settings the interactive CLI would — user and\n * project config, CLAUDE.md, skills, hooks, MCP servers. \"isolated\" loads\n * none of it. Default \"terminal\", because that is the promise.\n */\n parity?: \"terminal\" | \"isolated\";\n permissions: SessionPermissionHandler;\n /** Blocking questions and MCP/ACP elicitations. Omitted means decline safely. */\n input?: SessionInputHandler;\n appName?: string;\n effort?: string;\n thinking?: ThinkingParam;\n /** Override the harness's interactive system prompt. */\n systemPrompt?: string;\n /** Provider-specific escape hatch (Claude: Agent SDK Options; Codex: { sandbox }; ACP: { mode }). */\n native?: Record<string, unknown>;\n}\n\nexport interface ProviderSessionCapabilities {\n /** Can fork a resumed conversation, optionally at an exact reported turn. */\n fork: boolean;\n}\n\n/** One live conversation with a harness: send turns, get normalized events. */\nexport interface ProviderSession {\n readonly provider: string;\n /** Provider session id once known (use it to resume later). */\n readonly id: string | undefined;\n send(input: string | ContentBlockParam[]): AsyncGenerator<AgentEvent, void, undefined>;\n interrupt(): Promise<void>;\n close(): Promise<void>;\n}\n\n/** Providers that can host agentic sessions implement this too. */\nexport interface SessionProvider extends Provider {\n readonly sessionCapabilities: ProviderSessionCapabilities;\n openSession(options: ProviderSessionOptions): ProviderSession;\n}\n\nexport function isSessionProvider(p: Provider): p is SessionProvider {\n return typeof (p as Partial<SessionProvider>).openSession === \"function\";\n}\n","import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { ProviderNotInstalledError } from \"./errors.js\";\n\nexport function expandHome(p: string): string {\n if (p === \"~\") return os.homedir();\n if (p.startsWith(\"~/\")) return path.join(os.homedir(), p.slice(2));\n return p;\n}\n\nfunction isFile(p: string): boolean {\n try {\n return fs.statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Directories CLIs commonly install into when they aren't on PATH. */\nfunction commonBinDirs(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".local\", \"bin\"),\n \"/opt/homebrew/bin\",\n \"/usr/local/bin\",\n path.join(home, \".npm-global\", \"bin\"),\n path.join(home, \"bin\"),\n path.join(home, \".bun\", \"bin\"),\n path.join(home, \".cargo\", \"bin\"),\n ];\n}\n\nexport interface FindExecutableOptions {\n /** Explicit path from config/CLI flags; wins when set, errors when wrong. */\n explicit?: string;\n /** Extra absolute candidates to try after PATH. */\n extraPaths?: string[];\n}\n\n/**\n * Locate a CLI binary: explicit path first, then PATH, then the usual\n * install directories. Returns undefined when nothing is found.\n */\nexport function findExecutable(name: string, options: FindExecutableOptions = {}): string | undefined {\n if (options.explicit) {\n const p = expandHome(options.explicit);\n return isFile(p) ? p : undefined;\n }\n if (name.includes(\"/\")) {\n const p = expandHome(name);\n return isFile(p) ? p : undefined;\n }\n for (const dir of (process.env[\"PATH\"] ?? \"\").split(path.delimiter)) {\n if (!dir) continue;\n const candidate = path.join(dir, name);\n if (isFile(candidate)) return candidate;\n }\n for (const dir of commonBinDirs()) {\n const candidate = path.join(dir, name);\n if (isFile(candidate)) return candidate;\n }\n for (const candidate of options.extraPaths ?? []) {\n if (isFile(expandHome(candidate))) return expandHome(candidate);\n }\n return undefined;\n}\n\n/** Like findExecutable, but throws a typed, actionable error when missing. */\nexport function resolveExecutable(\n providerId: string,\n name: string,\n installHint: string,\n options: FindExecutableOptions = {},\n): string {\n const found = findExecutable(name, options);\n if (found) return found;\n const detail = options.explicit ? `configured path ${options.explicit} does not exist` : `\\`${name}\\` not on PATH`;\n throw new ProviderNotInstalledError(providerId, installHint, detail);\n}\n\n/**\n * Locate the user's installed (and signed-in) Claude Code CLI. The resolved\n * path is handed to the Agent SDK via `pathToClaudeCodeExecutable`, so the\n * spawned engine is the same binary — and the same login — the user gets in\n * their terminal.\n */\nexport function resolveClaudeExecutable(explicit?: string): string {\n const configured = explicit ?? process.env[\"YAGAMI_CLAUDE_PATH\"];\n return resolveExecutable(\n \"claude\",\n \"claude\",\n \"Install Claude Code and sign in (run `claude`, then /login), or point yagami at it with YAGAMI_CLAUDE_PATH or providers.claude.path.\",\n {\n ...(configured ? { explicit: configured } : {}),\n extraPaths: [path.join(os.homedir(), \".claude\", \"local\", \"claude\")],\n },\n );\n}\n","export const VERSION = \"0.8.2\";\n","import { spawn, spawnSync, type ChildProcess } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline\";\nimport { PassThrough, Readable, Writable } from \"node:stream\";\nimport {\n ClientSideConnection,\n ndJsonStream,\n PROTOCOL_VERSION,\n type CreateElicitationRequest,\n type CreateElicitationResponse,\n type InitializeResponse,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type SessionConfigOption,\n type SessionNotification,\n} from \"@agentclientprotocol/sdk\";\nimport type { ContentBlock as AcpContentBlock } from \"@agentclientprotocol/sdk\";\nimport { resolveExecutable } from \"../executable.js\";\nimport { classifyProviderFailure, looksLikeAuthFailure, AuthRequiredError, ProviderError } from \"../errors.js\";\nimport { declineInput, elicitationRequest, elicitationResponse } from \"../interaction.js\";\nimport type { EngineModel } from \"../models.js\";\nimport type {\n AgentEvent,\n Provider,\n ProviderCapabilities,\n ProviderSession,\n ProviderSessionOptions,\n SessionPermissionDecision,\n SessionPermissionRequest,\n SessionPlan,\n SessionPlanEntry,\n SessionProvider,\n TurnEvent,\n TurnRequest,\n} from \"../provider.js\";\nimport type { ContentBlockParam, Usage } from \"../types.js\";\nimport { killTree } from \"./process.js\";\nimport { AsyncQueue } from \"./queue.js\";\nimport { VERSION } from \"../../version.js\";\n\nexport interface AcpHandlers {\n onUpdate?: (n: SessionNotification) => void;\n onPermission?: (p: RequestPermissionRequest) => Promise<RequestPermissionResponse>;\n onInput?: (p: CreateElicitationRequest) => Promise<CreateElicitationResponse>;\n}\n\n/** A live ACP agent process plus its negotiated connection. */\nexport interface AcpConnection {\n agent: ClientSideConnection;\n init: InitializeResponse;\n setHandlers(handlers: AcpHandlers): void;\n close(): void;\n}\n\nexport interface AcpProviderOptions {\n id: string;\n label: string;\n /** Executable name or path, resolved like any other CLI. */\n command: string;\n args?: string[];\n /** Explicit executable path override (wins over `command`). */\n path?: string;\n env?: Record<string, string>;\n workDir?: string;\n appName?: string;\n /** Id of the session config option that selects the model (default \"model\"). */\n modelConfigId?: string;\n loginCommand?: string;\n installHint?: string;\n /** Test seam: replaces process spawning. */\n connect?: (cwd: string) => Promise<AcpConnection>;\n /** How long a spawned agent gets to finish the ACP handshake before it is\n * killed (default 30 s). */\n handshakeTimeoutMs?: number;\n /** How long a model-list or version probe may take end to end before the\n * agent is closed and the probe fails (default 20 s). */\n probeTimeoutMs?: number;\n}\n\nconst HANDSHAKE_TIMEOUT_MS = 30_000;\nconst PROBE_TIMEOUT_MS = 20_000;\n\n/** Pick the most conservative option an agent offers for a permission ask. */\nexport function rejectOption(p: RequestPermissionRequest): RequestPermissionResponse {\n const pick =\n p.options.find((o) => o.kind === \"reject_once\") ??\n p.options.find((o) => o.kind === \"reject_always\") ??\n p.options[0];\n if (!pick) return { outcome: { outcome: \"cancelled\" } };\n return { outcome: { outcome: \"selected\", optionId: pick.optionId } };\n}\n\n/**\n * Any agent speaking the Agent Client Protocol over stdio — OpenCode,\n * Gemini CLI, Copilot, Cursor, Qwen Code, Kimi, Goose, and anything in the\n * ACP registry. One adapter, many harnesses.\n */\nexport class AcpProvider implements SessionProvider {\n readonly id: string;\n readonly label: string;\n readonly executable: string;\n readonly loginCommand: string;\n readonly capabilities: ProviderCapabilities = {\n resume: true,\n fork: false,\n images: true,\n documents: false,\n systemPrompt: false,\n thinking: false,\n effort: false,\n streaming: \"tokens\",\n serverTools: false,\n };\n readonly sessionCapabilities = { fork: false } as const;\n\n private readonly args: string[];\n private readonly env: NodeJS.ProcessEnv;\n private readonly workDir: string;\n private readonly appName: string;\n private readonly modelConfigId: string;\n private readonly connectImpl: (cwd: string) => Promise<AcpConnection>;\n private readonly handshakeTimeoutMs: number;\n private readonly probeTimeoutMs: number;\n\n constructor(options: AcpProviderOptions) {\n this.id = options.id;\n this.label = options.label;\n this.loginCommand = options.loginCommand ?? `${options.command} (sign in per its docs)`;\n this.executable = options.connect\n ? options.path ?? options.command\n : resolveExecutable(options.id, options.command, options.installHint ?? `Install \\`${options.command}\\` and sign in.`, {\n ...(options.path ? { explicit: options.path } : {}),\n });\n this.args = options.args ?? [];\n this.env = { ...process.env, ...options.env };\n this.workDir = options.workDir ?? path.join(os.tmpdir(), \"yagami-workspace\");\n this.appName = options.appName ?? \"yagami\";\n this.modelConfigId = options.modelConfigId ?? \"model\";\n this.connectImpl = options.connect ?? ((cwd) => this.spawnConnection(cwd));\n this.handshakeTimeoutMs = options.handshakeTimeoutMs ?? HANDSHAKE_TIMEOUT_MS;\n this.probeTimeoutMs = options.probeTimeoutMs ?? PROBE_TIMEOUT_MS;\n fs.mkdirSync(this.workDir, { recursive: true });\n }\n\n private spawnConnection(cwd: string): Promise<AcpConnection> {\n return new Promise<AcpConnection>((resolve, reject) => {\n let child: ChildProcess;\n try {\n child = spawn(this.executable, this.args, { cwd, env: this.env, stdio: [\"pipe\", \"pipe\", \"pipe\"] });\n } catch (err) {\n reject(classifyProviderFailure(this.id, this.loginCommand, err));\n return;\n }\n let stderr = \"\";\n const noteNoise = (d: string) => {\n stderr += d;\n if (stderr.length > 16_000) stderr = stderr.slice(-8_000);\n };\n child.stderr?.on(\"data\", (d: Buffer) => noteNoise(d.toString()));\n let handlers: AcpHandlers = {};\n const stream = ndJsonStream(\n Writable.toWeb(child.stdin!) as WritableStream<Uint8Array>,\n Readable.toWeb(jsonLinesOnly(child.stdout!, noteNoise)) as ReadableStream<Uint8Array>,\n );\n const agent = new ClientSideConnection(\n () => ({\n requestPermission: (p) => (handlers.onPermission ? handlers.onPermission(p) : rejectOption(p)),\n unstable_createElicitation: (p) =>\n handlers.onInput ? handlers.onInput(p) : Promise.resolve({ action: \"decline\" }),\n unstable_completeElicitation: () => {},\n sessionUpdate: (n) => {\n handlers.onUpdate?.(n);\n },\n }),\n stream,\n );\n let settled = false;\n // An agent that never answers the handshake used to be left running\n // for good, with nobody holding it and nothing to close it with.\n const handshake = setTimeout(() => {\n if (settled) return;\n settled = true;\n killTree(child);\n reject(new ProviderError(this.id, `${this.label} did not finish the ACP handshake within ${Math.round(this.handshakeTimeoutMs / 1000)}s`));\n }, this.handshakeTimeoutMs);\n handshake.unref?.();\n child.on(\"error\", (err) => {\n if (settled) return;\n settled = true;\n clearTimeout(handshake);\n reject(classifyProviderFailure(this.id, this.loginCommand, err));\n });\n child.on(\"exit\", (code) => {\n if (settled) return;\n settled = true;\n clearTimeout(handshake);\n reject(classifyProviderFailure(this.id, this.loginCommand, new Error(`${this.executable} exited with code ${code}${stderr ? `: ${stderr.trim().slice(-400)}` : \"\"}`)));\n });\n agent\n .initialize({\n protocolVersion: PROTOCOL_VERSION,\n clientInfo: { name: this.appName, version: VERSION },\n clientCapabilities: {\n fs: { readTextFile: false, writeTextFile: false },\n terminal: false,\n session: { configOptions: { boolean: {} } },\n plan: {},\n elicitation: { form: {}, url: {} },\n },\n })\n .then((init) => {\n if (settled) return;\n settled = true;\n clearTimeout(handshake);\n resolve({\n agent,\n init,\n setHandlers: (h) => {\n handlers = h;\n },\n close: () => killTree(child),\n });\n })\n .catch((err) => {\n if (settled) return;\n settled = true;\n clearTimeout(handshake);\n killTree(child);\n reject(this.classify(err, stderr));\n });\n });\n }\n\n private classify(err: unknown, context = \"\"): Error {\n const message = err instanceof Error ? err.message : String(err);\n const code = (err as { code?: number } | undefined)?.code;\n // -32000 is ACP's \"authentication required\" error code.\n if (code === -32000 || looksLikeAuthFailure(message) || looksLikeAuthFailure(context)) {\n return new AuthRequiredError(this.id, this.loginCommand, message.slice(0, 200));\n }\n return classifyProviderFailure(this.id, this.loginCommand, err);\n }\n\n async *run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined> {\n const conn = await this.connectImpl(this.workDir);\n const queue = new AsyncQueue<TurnEvent>();\n let sessionId: string | undefined;\n let costUsd: number | undefined;\n const onAbort = () => {\n if (sessionId) void conn.agent.cancel({ sessionId }).catch(() => {});\n // no session to cancel yet: the only way to stop is to close the agent\n else conn.close();\n };\n if (req.signal?.aborted) {\n conn.close();\n return;\n }\n req.signal?.addEventListener(\"abort\", onAbort, { once: true });\n try {\n let configOptions: SessionConfigOption[] | null | undefined;\n let modes: { currentModeId?: string; availableModes?: Array<{ id: string }> } | null | undefined;\n if (req.resume) {\n if (!supportsResume(conn.init)) {\n throw new ProviderError(this.id, \"this agent cannot resume sessions; replaying the transcript instead\");\n }\n const resumed = await conn.agent.resumeSession({ sessionId: req.resume, cwd: this.workDir }).catch((err) => {\n throw this.classify(err);\n });\n sessionId = req.resume;\n configOptions = resumed.configOptions;\n modes = resumed.modes as typeof modes;\n } else {\n const created = await conn.agent.newSession({ cwd: this.workDir, mcpServers: [] }).catch((err) => {\n throw this.classify(err);\n });\n sessionId = created.sessionId;\n configOptions = created.configOptions;\n modes = created.modes as typeof modes;\n }\n yield { type: \"session\", sessionId };\n\n // Hardening: prefer a read-only/plan mode when the agent offers one.\n const plan = modes?.availableModes?.find((m) => /^(plan|read[-_]?only|ask)$/i.test(m.id));\n if (plan && modes?.currentModeId !== plan.id) {\n await conn.agent.setSessionMode({ sessionId, modeId: plan.id }).catch(() => {});\n }\n if (req.model) await this.selectModel(conn, sessionId, configOptions, req.model);\n if (req.effort) await this.selectEffort(conn, sessionId, configOptions, req.effort);\n\n const sid = sessionId;\n conn.setHandlers({\n onPermission: async (p) => rejectOption(p),\n onUpdate: (n) => {\n if (n.sessionId !== sid) return;\n const u = n.update;\n if (u.sessionUpdate === \"agent_message_chunk\" && u.content.type === \"text\") {\n queue.push({ type: \"text\", text: u.content.text });\n } else if (u.sessionUpdate === \"agent_thought_chunk\" && u.content.type === \"text\") {\n queue.push({ type: \"thinking\", text: u.content.text });\n } else if (u.sessionUpdate === \"usage_update\") {\n const cost = (u as { cost?: { amount?: number; currency?: string } | null }).cost;\n if (cost && typeof cost.amount === \"number\" && (cost.currency ?? \"USD\") === \"USD\") costUsd = cost.amount;\n }\n },\n });\n conn.agent\n .prompt({ sessionId, prompt: toAcpBlocks(req.prompt, req.media ?? [], this.id) })\n .then((res) => {\n queue.push({\n type: \"done\",\n usage: mapAcpUsage((res.usage ?? undefined) as Record<string, unknown> | undefined),\n ...(costUsd !== undefined ? { costUsd } : {}),\n stopReason: mapStopReason(res.stopReason),\n });\n queue.end();\n })\n .catch((err) => queue.fail(this.classify(err)));\n\n for await (const ev of queue) yield ev;\n } finally {\n req.signal?.removeEventListener(\"abort\", onAbort);\n conn.close();\n }\n }\n\n /**\n * A live, interactive ACP session: the agent runs warm in the project\n * directory with ITS OWN defaults — no plan-mode hardening, no forced\n * config. Tool calls stream as normalized events and permission requests\n * go to the host's handler, exactly as the agent's own client would ask.\n */\n openSession(options: ProviderSessionOptions): ProviderSession {\n return new AcpAgentSession({\n id: this.id,\n modelConfigId: this.modelConfigId,\n connect: (cwd) => this.connectImpl(cwd),\n classify: (err, ctx) => this.classify(err, ctx),\n selectModel: (conn, sessionId, configOptions, model) => this.selectModel(conn, sessionId, configOptions, model),\n selectEffort: (conn, sessionId, configOptions, effort) => this.selectEffort(conn, sessionId, configOptions, effort),\n options,\n });\n }\n\n private async selectModel(\n conn: AcpConnection,\n sessionId: string,\n configOptions: SessionConfigOption[] | null | undefined,\n model: string,\n ): Promise<void> {\n const option =\n configOptions?.find((o) => o.id === this.modelConfigId) ?? configOptions?.find((o) => o.category === \"model\");\n if (!option || option.type !== \"select\") {\n throw new ProviderError(this.id, `cannot select model \"${model}\": the agent exposes no model option (omit the model to use its default)`);\n }\n if (option.currentValue === model) return;\n await conn.agent.setSessionConfigOption({ sessionId, configId: option.id, value: model }).catch((err) => {\n throw this.classify(err);\n });\n }\n\n private async selectEffort(\n conn: AcpConnection,\n sessionId: string,\n configOptions: SessionConfigOption[] | null | undefined,\n effort: string,\n ): Promise<void> {\n const option = configOptions?.find(\n (candidate) =>\n candidate.category === \"thought_level\" ||\n /^(?:thought[_-]?level|reasoning[_-]?effort|effort)$/i.test(candidate.id),\n );\n if (!option || option.type !== \"select\" || option.currentValue === effort) return;\n if (!flattenSelectOptions(option).some((candidate) => candidate.value === effort)) return;\n await conn.agent.setSessionConfigOption({ sessionId, configId: option.id, value: effort }).catch((err) => {\n throw this.classify(err);\n });\n }\n\n /**\n * Run a short question against a fresh agent and close it, whatever\n * happens. The deadline covers the whole exchange: an agent that answers\n * the handshake and then sits on newSession forever (Gemini, signed out\n * or mid-update) used to hold the probe open — and its process alive —\n * for as long as the host ran.\n */\n private async probe<T>(ask: (conn: AcpConnection) => Promise<T>): Promise<T> {\n const conn = await this.connectImpl(this.workDir);\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n ask(conn),\n new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new ProviderError(this.id, `${this.label} did not answer within ${Math.round(this.probeTimeoutMs / 1000)}s`)),\n this.probeTimeoutMs,\n );\n timer.unref?.();\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n conn.close();\n }\n }\n\n async listModels(): Promise<EngineModel[]> {\n return this.probe(async (conn) => {\n const created = await conn.agent.newSession({ cwd: this.workDir, mcpServers: [] }).catch((err) => {\n throw this.classify(err);\n });\n const option =\n created.configOptions?.find((o) => o.id === this.modelConfigId) ??\n created.configOptions?.find((o) => o.category === \"model\");\n if (!option || option.type !== \"select\") return [];\n const effortOption = created.configOptions?.find(\n (candidate) =>\n candidate.type === \"select\" &&\n (candidate.category === \"thought_level\" ||\n /^(?:thought[_-]?level|reasoning[_-]?effort|effort)$/i.test(candidate.id)),\n );\n const efforts = effortOption?.type === \"select\"\n ? flattenSelectOptions(effortOption).map((entry) => ({\n id: entry.value,\n ...(entry.description ? { description: entry.description } : {}),\n }))\n : [];\n return flattenSelectOptions(option).map((o) => ({\n id: o.value,\n display_name: o.name,\n ...(o.description ? { description: o.description } : {}),\n ...(efforts.length > 0 ? { reasoning_efforts: efforts } : {}),\n ...(effortOption?.type === \"select\" ? { default_reasoning_effort: effortOption.currentValue } : {}),\n }));\n });\n }\n\n /**\n * The agent's self-reported name/version from the ACP handshake. When the\n * handshake fails (wrong binary, version too old for ACP), falls back to\n * `--version` and says so, because that is exactly what `doctor` needs.\n */\n async version(): Promise<string | undefined> {\n let handshakeError: string | undefined;\n try {\n const conn = await this.connectImpl(this.workDir);\n try {\n const info = conn.init.agentInfo;\n if (info?.version) return `${info.name ?? this.id} ${info.version}`;\n return `${this.id} (ACP ok)`;\n } finally {\n conn.close();\n }\n } catch (err) {\n handshakeError = (err instanceof Error ? err.message : String(err)).split(\"\\n\")[0]?.slice(0, 120);\n }\n let plain: string | undefined;\n try {\n const out = spawnSync(this.executable, [\"--version\"], { encoding: \"utf8\", timeout: 10_000 });\n plain = out.stdout?.trim().split(\"\\n\")[0] || undefined;\n } catch {\n plain = undefined;\n }\n return `${plain ?? \"unknown version\"} ⚠ no ACP handshake (${handshakeError ?? \"unknown error\"}) — too old, or a different program with the same name?`;\n }\n}\n\ninterface AcpSessionConfig {\n id: string;\n modelConfigId: string;\n connect: (cwd: string) => Promise<AcpConnection>;\n classify: (err: unknown, context?: string) => Error;\n selectModel: (\n conn: AcpConnection,\n sessionId: string,\n configOptions: SessionConfigOption[] | null | undefined,\n model: string,\n ) => Promise<void>;\n selectEffort: (\n conn: AcpConnection,\n sessionId: string,\n configOptions: SessionConfigOption[] | null | undefined,\n effort: string,\n ) => Promise<void>;\n options: ProviderSessionOptions;\n}\n\n/** One warm ACP agent process, verbatim, across turns. */\nclass AcpAgentSession implements ProviderSession {\n readonly provider: string;\n\n private conn: AcpConnection | undefined;\n private sessionId: string | undefined;\n private queue: AsyncQueue<AgentEvent> | null = null;\n private opening: Promise<void> | undefined;\n private closed = false;\n private costUsd: number | undefined;\n /** Updates often omit title/kind — remember them from the start event. */\n private readonly toolMeta = new Map<string, { name: string; title?: string; kind?: string }>();\n\n constructor(private readonly cfg: AcpSessionConfig) {\n this.provider = cfg.id;\n }\n\n get id(): string | undefined {\n return this.sessionId;\n }\n\n private ensureOpen(): Promise<void> {\n this.opening ??= this.open();\n return this.opening;\n }\n\n private async open(): Promise<void> {\n const { options } = this.cfg;\n const conn = await this.cfg.connect(options.cwd);\n this.conn = conn;\n let configOptions: SessionConfigOption[] | null | undefined;\n if (options.resume && supportsResume(conn.init)) {\n const resumed = await conn.agent\n .resumeSession({ sessionId: options.resume, cwd: options.cwd })\n .catch((err) => {\n throw this.cfg.classify(err);\n });\n this.sessionId = options.resume;\n configOptions = resumed.configOptions;\n } else {\n const created = await conn.agent.newSession({ cwd: options.cwd, mcpServers: [] }).catch((err) => {\n throw this.cfg.classify(err);\n });\n this.sessionId = created.sessionId;\n configOptions = created.configOptions;\n }\n const sessionId = this.sessionId;\n // verbatim by default: only an explicit native.mode changes the agent's mode\n const mode = (options.native as { mode?: string } | undefined)?.mode;\n if (mode) await conn.agent.setSessionMode({ sessionId, modeId: mode }).catch(() => {});\n if (options.model) await this.cfg.selectModel(conn, sessionId, configOptions, options.model);\n if (options.effort) await this.cfg.selectEffort(conn, sessionId, configOptions, options.effort);\n conn.setHandlers({\n onPermission: (p) => this.onPermission(p),\n onInput: (p) => this.onInput(p),\n onUpdate: (n) => this.onUpdate(n),\n });\n }\n\n private async onPermission(p: RequestPermissionRequest): Promise<RequestPermissionResponse> {\n const toolCall = p.toolCall as { title?: string; kind?: string; rawInput?: unknown } | undefined;\n const request: SessionPermissionRequest = {\n provider: this.provider,\n ...(this.sessionId ? { sessionId: this.sessionId } : {}),\n tool: toolCall?.title ?? \"tool\",\n ...(toolCall?.kind ? { kind: toolCall.kind } : {}),\n ...(toolCall?.title ? { title: toolCall.title } : {}),\n input: toolCall?.rawInput,\n raw: p,\n };\n let decision: SessionPermissionDecision = \"deny\";\n try {\n decision = await this.cfg.options.permissions.decide(request);\n } catch {\n // an unanswerable ask is a denied ask\n }\n this.queue?.push({ type: \"permission\", request, decision });\n const preferred: Record<SessionPermissionDecision, string[]> = {\n allow: [\"allow_once\", \"allow_always\"],\n allow_always: [\"allow_always\", \"allow_once\"],\n deny: [\"reject_once\", \"reject_always\"],\n deny_always: [\"reject_always\", \"reject_once\"],\n };\n for (const kind of preferred[decision]) {\n const option = p.options.find((o) => o.kind === kind);\n if (option) return { outcome: { outcome: \"selected\", optionId: option.optionId } };\n }\n return rejectOption(p);\n }\n\n private async onInput(p: CreateElicitationRequest): Promise<CreateElicitationResponse> {\n const request = elicitationRequest(\n this.provider,\n this.sessionId,\n p as unknown as Record<string, unknown>,\n );\n const handler = this.cfg.options.input;\n let response = declineInput();\n if (handler) {\n try {\n response = await handler.respond(request);\n } catch {\n response = { action: \"cancel\" };\n }\n }\n return elicitationResponse(response) as CreateElicitationResponse;\n }\n\n private onUpdate(n: SessionNotification): void {\n if (n.sessionId !== this.sessionId) return;\n const u = n.update;\n switch (u.sessionUpdate) {\n case \"agent_message_chunk\":\n if (u.content.type === \"text\") this.queue?.push({ type: \"text\", text: u.content.text });\n break;\n case \"agent_thought_chunk\":\n if (u.content.type === \"text\") this.queue?.push({ type: \"thinking\", text: u.content.text });\n break;\n case \"plan\":\n this.queue?.push({ type: \"plan\", plan: acpPlan(u as unknown as Record<string, unknown>) });\n break;\n case \"plan_update\":\n this.queue?.push({ type: \"plan\", plan: acpPlan((u as unknown as { plan?: Record<string, unknown> }).plan ?? {}) });\n break;\n case \"plan_removed\":\n this.queue?.push({\n type: \"plan\",\n plan: {\n ...(typeof (u as unknown as { planId?: unknown }).planId === \"string\"\n ? { id: (u as unknown as { planId: string }).planId }\n : {}),\n removed: true,\n },\n });\n break;\n case \"tool_call\": {\n const t = u as { toolCallId: string; title?: string; kind?: string; rawInput?: unknown };\n const meta = { name: t.kind ?? \"tool\", ...(t.title ? { title: t.title } : {}), ...(t.kind ? { kind: t.kind } : {}) };\n this.toolMeta.set(t.toolCallId, meta);\n this.queue?.push({\n type: \"tool_call\",\n id: t.toolCallId,\n status: \"started\",\n ...meta,\n ...(t.rawInput !== undefined ? { input: t.rawInput } : {}),\n });\n break;\n }\n case \"tool_call_update\": {\n const t = u as { toolCallId: string; status?: string; title?: string; kind?: string; rawOutput?: unknown };\n const known = this.toolMeta.get(t.toolCallId);\n const meta = {\n name: t.kind ?? known?.name ?? \"tool\",\n ...(t.title ?? known?.title ? { title: t.title ?? known?.title } : {}),\n ...(t.kind ?? known?.kind ? { kind: t.kind ?? known?.kind } : {}),\n };\n this.queue?.push({\n type: \"tool_call\",\n id: t.toolCallId,\n status: t.status === \"completed\" ? \"completed\" : t.status === \"failed\" ? \"failed\" : \"updated\",\n ...meta,\n ...(t.rawOutput !== undefined ? { output: t.rawOutput } : {}),\n });\n break;\n }\n case \"usage_update\": {\n const cost = (u as { cost?: { amount?: number; currency?: string } | null }).cost;\n if (cost && typeof cost.amount === \"number\" && (cost.currency ?? \"USD\") === \"USD\") this.costUsd = cost.amount;\n break;\n }\n default:\n this.queue?.push({ type: \"raw\", provider: this.provider, payload: u });\n break;\n }\n }\n\n async *send(input: string | ContentBlockParam[]): AsyncGenerator<AgentEvent, void, undefined> {\n if (this.closed) throw new ProviderError(this.provider, \"session is closed\");\n if (this.queue) throw new ProviderError(this.provider, \"a turn is already running\");\n await this.ensureOpen();\n const sessionId = this.sessionId!;\n const text = typeof input === \"string\" ? input : input.filter((b) => b.type === \"text\").map((b) => (b as { text?: string }).text ?? \"\").join(\"\\n\");\n const media = typeof input === \"string\" ? [] : input.filter((b) => b.type === \"image\");\n\n const queue = new AsyncQueue<AgentEvent>();\n this.queue = queue;\n this.costUsd = undefined;\n this.conn!.agent\n .prompt({ sessionId, prompt: toAcpBlocks(text, media, this.provider) })\n .then((res) => {\n queue.push({\n type: \"done\",\n usage: mapAcpUsage((res.usage ?? undefined) as Record<string, unknown> | undefined),\n ...(this.costUsd !== undefined ? { costUsd: this.costUsd } : {}),\n stopReason: mapStopReason(res.stopReason),\n });\n queue.end();\n })\n .catch((err) => queue.fail(this.cfg.classify(err)));\n try {\n yield { type: \"session\", sessionId };\n for await (const event of queue) yield event;\n } finally {\n if (this.queue === queue) this.queue = null;\n }\n }\n\n async interrupt(): Promise<void> {\n if (!this.sessionId || !this.conn) return;\n await this.conn.agent.cancel({ sessionId: this.sessionId }).catch(() => {});\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.queue?.fail(new ProviderError(this.provider, \"session closed\"));\n this.queue = null;\n this.conn?.close();\n this.conn = undefined;\n }\n}\n\nfunction acpPlan(raw: Record<string, unknown>): SessionPlan {\n const entries = Array.isArray(raw[\"entries\"])\n ? raw[\"entries\"].flatMap((value) => {\n const entry = value as Record<string, unknown>;\n if (typeof entry[\"content\"] !== \"string\") return [];\n const item: SessionPlanEntry = {\n content: entry[\"content\"],\n status:\n entry[\"status\"] === \"completed\"\n ? \"completed\"\n : entry[\"status\"] === \"in_progress\"\n ? \"in_progress\"\n : \"pending\",\n ...([\"high\", \"medium\", \"low\"].includes(String(entry[\"priority\"]))\n ? { priority: entry[\"priority\"] as SessionPlanEntry[\"priority\"] }\n : {}),\n };\n return [item];\n })\n : undefined;\n return {\n ...(typeof raw[\"planId\"] === \"string\" ? { id: raw[\"planId\"] } : {}),\n ...(entries ? { entries } : {}),\n ...(typeof raw[\"content\"] === \"string\" ? { markdown: raw[\"content\"] } : {}),\n ...(typeof raw[\"uri\"] === \"string\" ? { uri: raw[\"uri\"] } : {}),\n };\n}\n\nfunction supportsResume(init: InitializeResponse): boolean {\n const caps = init.agentCapabilities as { sessionCapabilities?: { resume?: unknown } } | undefined;\n return caps?.sessionCapabilities?.resume !== undefined;\n}\n\n/** Select options may be flat or grouped; return the leaves. */\nfunction flattenSelectOptions(option: SessionConfigOption & { type: \"select\" }): Array<{ value: string; name: string; description?: string | null }> {\n const raw = (option as { options?: unknown }).options;\n if (!Array.isArray(raw)) return [];\n const out: Array<{ value: string; name: string; description?: string | null }> = [];\n for (const entry of raw as Array<Record<string, unknown>>) {\n if (typeof entry[\"value\"] === \"string\") {\n out.push({ value: entry[\"value\"], name: String(entry[\"name\"] ?? entry[\"value\"]), description: entry[\"description\"] as string | undefined });\n } else if (Array.isArray(entry[\"options\"])) {\n for (const leaf of entry[\"options\"] as Array<Record<string, unknown>>) {\n if (typeof leaf[\"value\"] === \"string\") {\n out.push({ value: leaf[\"value\"], name: String(leaf[\"name\"] ?? leaf[\"value\"]), description: leaf[\"description\"] as string | undefined });\n }\n }\n }\n }\n return out;\n}\n\nfunction toAcpBlocks(text: string, media: ContentBlockParam[], providerId: string): AcpContentBlock[] {\n const blocks: AcpContentBlock[] = [];\n for (const block of media) {\n if (block.type !== \"image\") continue;\n const source = block[\"source\"] as { type?: string; data?: string; media_type?: string } | undefined;\n if (source?.type !== \"base64\" || typeof source.data !== \"string\") {\n throw new ProviderError(providerId, \"only base64 image sources are supported (URL images are not fetched)\");\n }\n blocks.push({ type: \"image\", data: source.data, mimeType: source.media_type ?? \"image/png\" });\n }\n if (text.length > 0 || blocks.length === 0) blocks.push({ type: \"text\", text });\n return blocks;\n}\n\nfunction mapAcpUsage(u: Record<string, unknown> | undefined): Usage {\n const num = (k: string) => (typeof u?.[k] === \"number\" ? (u[k] as number) : 0);\n return {\n input_tokens: num(\"inputTokens\"),\n output_tokens: num(\"outputTokens\"),\n cache_read_input_tokens: num(\"cachedReadTokens\") || num(\"cacheReadTokens\"),\n cache_creation_input_tokens: num(\"cachedWriteTokens\") || num(\"cacheWriteTokens\"),\n };\n}\n\nfunction mapStopReason(reason: string): string {\n switch (reason) {\n case \"max_tokens\":\n return \"max_tokens\";\n case \"refusal\":\n return \"refusal\";\n default:\n return \"end_turn\";\n }\n}\n\n/**\n * Pass only JSON-looking lines through to the protocol reader. Anything\n * else (banners, usage text from a wrong binary) is reported as noise\n * instead of tripping the SDK's parser.\n */\nfunction jsonLinesOnly(input: NodeJS.ReadableStream, onNoise: (line: string) => void): PassThrough {\n const out = new PassThrough();\n const rl = readline.createInterface({ input, crlfDelay: Infinity });\n rl.on(\"line\", (line) => {\n if (line.trimStart().startsWith(\"{\")) out.write(`${line}\\n`);\n else if (line.trim()) onNoise(`${line}\\n`);\n });\n rl.on(\"close\", () => out.end());\n return out;\n}\n","import type {\n SessionInputField,\n SessionInputRequest,\n SessionInputResponse,\n SessionInputValue,\n} from \"./provider.js\";\n\ntype Raw = Record<string, unknown>;\n\nfunction record(value: unknown): Raw | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Raw)\n : undefined;\n}\n\nfunction optionsOf(schema: Raw): Array<{ value: string; label: string; description?: string }> | undefined {\n const oneOf = Array.isArray(schema[\"oneOf\"]) ? schema[\"oneOf\"] : undefined;\n if (oneOf) {\n const options = oneOf.flatMap((item) => {\n const value = record(item);\n if (!value || typeof value[\"const\"] !== \"string\") return [];\n return [{\n value: value[\"const\"],\n label: typeof value[\"title\"] === \"string\" ? value[\"title\"] : value[\"const\"],\n ...(typeof value[\"description\"] === \"string\" ? { description: value[\"description\"] } : {}),\n }];\n });\n if (options.length > 0) return options;\n }\n const values = Array.isArray(schema[\"enum\"])\n ? schema[\"enum\"].filter((value): value is string => typeof value === \"string\")\n : [];\n return values.length > 0 ? values.map((value) => ({ value, label: value })) : undefined;\n}\n\n/** Convert the primitive JSON-Schema subset used by MCP/ACP into host fields. */\nexport function inputFields(schema: unknown): SessionInputField[] {\n const root = record(schema);\n const properties = record(root?.[\"properties\"]);\n if (!properties) return [];\n const required = new Set(\n Array.isArray(root?.[\"required\"])\n ? root[\"required\"].filter((value): value is string => typeof value === \"string\")\n : [],\n );\n return Object.entries(properties).flatMap(([id, value]) => {\n const property = record(value);\n if (!property || typeof property[\"type\"] !== \"string\") return [];\n let type: SessionInputField[\"type\"];\n let options = optionsOf(property);\n if (property[\"type\"] === \"array\") {\n type = \"multiselect\";\n options = optionsOf(record(property[\"items\"]) ?? {});\n } else if (property[\"type\"] === \"string\" && options) {\n type = \"select\";\n } else if ([\"string\", \"number\", \"integer\", \"boolean\"].includes(property[\"type\"])) {\n type = property[\"type\"] as SessionInputField[\"type\"];\n } else {\n return [];\n }\n const defaultValue = property[\"default\"];\n return [{\n id,\n label: typeof property[\"title\"] === \"string\" ? property[\"title\"] : id,\n type,\n required: required.has(id),\n ...(typeof property[\"description\"] === \"string\" ? { description: property[\"description\"] } : {}),\n ...(options ? { options } : {}),\n ...(typeof property[\"format\"] === \"string\" ? { format: property[\"format\"] } : {}),\n ...(typeof property[\"minimum\"] === \"number\" ? { minimum: property[\"minimum\"] } : {}),\n ...(typeof property[\"maximum\"] === \"number\" ? { maximum: property[\"maximum\"] } : {}),\n ...(typeof property[\"minLength\"] === \"number\" ? { minLength: property[\"minLength\"] } : {}),\n ...(typeof property[\"maxLength\"] === \"number\" ? { maxLength: property[\"maxLength\"] } : {}),\n ...(typeof defaultValue === \"string\" || typeof defaultValue === \"number\" || typeof defaultValue === \"boolean\" ||\n (Array.isArray(defaultValue) && defaultValue.every((item) => typeof item === \"string\"))\n ? { default: defaultValue as SessionInputValue }\n : {}),\n }];\n });\n}\n\n/** Normalize an MCP/ACP elicitation request. */\nexport function elicitationRequest(\n provider: string,\n sessionId: string | undefined,\n raw: Raw,\n): SessionInputRequest {\n const mode = raw[\"mode\"];\n if (mode === \"url\") {\n return {\n provider,\n ...(sessionId ? { sessionId } : {}),\n kind: \"url\",\n message: typeof raw[\"message\"] === \"string\" ? raw[\"message\"] : \"Open the requested URL\",\n ...(typeof raw[\"serverName\"] === \"string\" ? { source: raw[\"serverName\"] } : {}),\n ...(typeof raw[\"url\"] === \"string\" ? { url: raw[\"url\"] } : {}),\n raw,\n };\n }\n return {\n provider,\n ...(sessionId ? { sessionId } : {}),\n kind: \"form\",\n message: typeof raw[\"message\"] === \"string\" ? raw[\"message\"] : \"Input requested\",\n ...(typeof raw[\"serverName\"] === \"string\" ? { source: raw[\"serverName\"] } : {}),\n fields: inputFields(raw[\"requestedSchema\"]),\n raw,\n };\n}\n\nexport function declineInput(): SessionInputResponse {\n return { action: \"decline\" };\n}\n\nexport function elicitationResponse(response: SessionInputResponse): Raw {\n return response.action === \"accept\"\n ? { action: \"accept\", content: response.values ?? null }\n : { action: response.action };\n}\n","import { execFileSync, spawnSync, type ChildProcess } from \"node:child_process\";\n\n/**\n * Ending a CLI for good.\n *\n * `child.kill()` signals the one process yagami spawned, and several CLIs are\n * not one process: Gemini's launcher re-executes itself as a child with a\n * bigger heap, npm-installed CLIs sit behind a node shim, and an agent's MCP\n * servers hang off the agent. Signal only the top and the rest can outlive\n * it — reparented to launchd, holding hundreds of megabytes, for as long as\n * the machine stays up. So the whole tree is found first and every process\n * in it is asked to go; anything still there after a grace period is killed\n * outright.\n */\n\n/** How long a tree gets to exit on SIGTERM before SIGKILL follows. */\nconst GRACE_MS = 3000;\n\n/** Children already on their way out — a second call is a no-op. */\nconst ending = new WeakSet<ChildProcess>();\n\n/** Every descendant of `root`, found from one `ps` listing. */\nfunction descendants(root: number): number[] {\n let listing: string;\n try {\n listing = execFileSync(\"ps\", [\"-A\", \"-o\", \"pid=,ppid=\"], { encoding: \"utf8\", timeout: 2000 });\n } catch {\n return [];\n }\n const children = new Map<number, number[]>();\n for (const line of listing.split(\"\\n\")) {\n const [pid, ppid] = line.trim().split(/\\s+/).map(Number);\n if (!pid || ppid === undefined || Number.isNaN(ppid)) continue;\n const list = children.get(ppid);\n if (list) list.push(pid);\n else children.set(ppid, [pid]);\n }\n const found: number[] = [];\n const stack = [root];\n while (stack.length > 0) {\n for (const child of children.get(stack.pop()!) ?? []) {\n found.push(child);\n stack.push(child);\n }\n }\n return found;\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === \"EPERM\";\n }\n}\n\nfunction signal(pid: number, sig: NodeJS.Signals): void {\n try {\n process.kill(pid, sig);\n } catch {\n // already gone\n }\n}\n\n/**\n * Stop a spawned CLI and everything it started. Safe to call more than once\n * and on a process that has already exited.\n */\nexport function killTree(child: ChildProcess | undefined | null, graceMs = GRACE_MS): void {\n if (!child || child.pid === undefined || ending.has(child)) return;\n if (child.exitCode !== null || child.signalCode !== null) return;\n ending.add(child);\n const pid = child.pid;\n if (process.platform === \"win32\") {\n spawnSync(\"taskkill\", [\"/pid\", String(pid), \"/T\", \"/F\"], { stdio: \"ignore\" });\n return;\n }\n // listed before anything is signalled: once the top exits, its children\n // are reparented and can no longer be found by walking down from it\n const tree = [pid, ...descendants(pid)];\n for (const member of tree) signal(member, \"SIGTERM\");\n const timer = setTimeout(() => {\n for (const member of tree) if (isAlive(member)) signal(member, \"SIGKILL\");\n }, graceMs);\n timer.unref?.();\n}\n","/**\n * Minimal unbounded async queue: producers push, one consumer iterates.\n * `end()` completes the iteration once the buffer drains; `fail()` rejects\n * the consumer with the given error.\n */\nexport class AsyncQueue<T> implements AsyncIterable<T> {\n private readonly buffer: T[] = [];\n private waiting: { resolve: (r: IteratorResult<T>) => void; reject: (e: unknown) => void } | null = null;\n private ended = false;\n private error: unknown = undefined;\n /** Called once if the consumer stops iterating before the queue ends —\n * the producer's cue to stop whatever is feeding it. */\n onReturn: (() => void) | undefined;\n\n push(value: T): void {\n if (this.ended) return;\n if (this.waiting) {\n const w = this.waiting;\n this.waiting = null;\n w.resolve({ value, done: false });\n } else {\n this.buffer.push(value);\n }\n }\n\n end(): void {\n if (this.ended) return;\n this.ended = true;\n if (this.waiting) {\n const w = this.waiting;\n this.waiting = null;\n w.resolve({ value: undefined as never, done: true });\n }\n }\n\n fail(err: unknown): void {\n if (this.ended) return;\n this.error = err;\n this.ended = true;\n if (this.waiting) {\n const w = this.waiting;\n this.waiting = null;\n w.reject(err);\n }\n }\n\n get closed(): boolean {\n return this.ended;\n }\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return {\n next: () => {\n if (this.buffer.length > 0) return Promise.resolve({ value: this.buffer.shift() as T, done: false });\n if (this.error !== undefined) {\n const e = this.error;\n this.error = undefined;\n return Promise.reject(e);\n }\n if (this.ended) return Promise.resolve({ value: undefined as never, done: true });\n return new Promise<IteratorResult<T>>((resolve, reject) => {\n this.waiting = { resolve, reject };\n });\n },\n return: () => {\n const stop = this.ended ? undefined : this.onReturn;\n this.onReturn = undefined;\n this.ended = true;\n stop?.();\n return Promise.resolve({ value: undefined as never, done: true });\n },\n };\n }\n}\n","import { createRequire } from \"node:module\";\nimport { spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n query,\n type CanUseTool,\n type Options,\n type SDKResultMessage,\n type SDKUserMessage,\n type ThinkingConfig,\n type EffortLevel,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"../executable.js\";\nimport { classifyProviderFailure, ProviderError, type VersionSkew } from \"../errors.js\";\nimport type { EngineModel } from \"../models.js\";\nimport type { Provider, ProviderCapabilities, TurnEvent, TurnRequest } from \"../provider.js\";\nimport type { ContentBlockParam, ThinkingParam, Usage } from \"../types.js\";\nimport { VERSION } from \"../../version.js\";\n\n// The API surface is pure completions: even though `tools: []` removes every\n// built-in tool, deny anything that somehow still asks.\nconst DENY_ALL_TOOLS: CanUseTool = async (toolName) => ({\n behavior: \"deny\",\n message: `yagami is a completions-only endpoint; tool \"${toolName}\" is disabled.`,\n interrupt: true,\n});\n\n/**\n * Allow exactly the server tools this turn enabled, deny everything else.\n * Belt and braces: `options.tools` already restricts what exists, but a\n * completions endpoint should not depend on one gate.\n */\nconst allowOnly = (enabled: string[]): CanUseTool => {\n const allowed = new Set(enabled);\n return async (toolName, input) =>\n allowed.has(toolName)\n ? { behavior: \"allow\", updatedInput: input }\n : {\n behavior: \"deny\",\n message: `yagami is a completions-only endpoint; tool \"${toolName}\" is disabled.`,\n interrupt: true,\n };\n};\n\n/**\n * Turn cap once server tools are in play. A search-and-answer turn needs\n * several round trips, but an unbounded loop on a completions endpoint is a\n * cost bug, so it stays bounded.\n */\nconst SERVER_TOOL_MAX_TURNS = 24;\n\nexport interface ClaudeProviderOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n path?: string;\n /** Optional CLAUDE_CONFIG_DIR override for the spawned CLI. */\n configDir?: string;\n /** Working directory for completion turns (inert — tools are disabled). */\n workDir?: string;\n /** Reported to the CLI as the client application. */\n appName?: string;\n}\n\ninterface RawStreamEvent {\n type: string;\n [key: string]: unknown;\n}\n\n/** Claude Code through the Agent SDK, pointed at the user's signed-in binary. */\nexport class ClaudeProvider implements Provider {\n readonly id = \"claude\";\n readonly label = \"Claude Code\";\n readonly executable: string;\n readonly loginCommand = \"claude (then /login)\";\n readonly capabilities: ProviderCapabilities = {\n resume: true,\n fork: true,\n images: true,\n documents: true,\n systemPrompt: true,\n thinking: true,\n effort: true,\n streaming: \"tokens\",\n serverTools: true,\n };\n\n private readonly configDir: string | undefined;\n private readonly workDir: string;\n private readonly appName: string;\n\n constructor(options: ClaudeProviderOptions = {}) {\n this.executable = resolveClaudeExecutable(options.path);\n this.configDir = options.configDir;\n this.appName = options.appName ?? \"yagami\";\n this.workDir = options.workDir ?? path.join(os.tmpdir(), \"yagami-workspace\");\n fs.mkdirSync(this.workDir, { recursive: true });\n }\n\n /** Hardened options shared by every completion turn and probe. */\n private baseOptions(): Options {\n return {\n pathToClaudeCodeExecutable: this.executable,\n cwd: this.workDir,\n // Pure completions: no built-in tools, no settings/CLAUDE.md/skills\n // leaking in, exactly one assistant turn per request.\n tools: [],\n settingSources: [],\n maxTurns: 1,\n canUseTool: DENY_ALL_TOOLS,\n env: {\n ...process.env,\n ...(this.configDir ? { CLAUDE_CONFIG_DIR: this.configDir } : {}),\n CLAUDE_AGENT_SDK_CLIENT_APP: `${this.appName}/${VERSION}`,\n },\n };\n }\n\n async *run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined> {\n const abortController = new AbortController();\n const onAbort = () => abortController.abort();\n req.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n const options: Options = { ...this.baseOptions(), abortController, includePartialMessages: true };\n if (req.serverTools && req.serverTools.length > 0) {\n options.tools = [...req.serverTools];\n options.canUseTool = allowOnly(req.serverTools);\n options.maxTurns = SERVER_TOOL_MAX_TURNS;\n }\n if (req.model) options.model = req.model;\n if (req.system !== undefined) options.systemPrompt = req.system;\n if (req.resume) {\n options.resume = req.resume;\n // Fork so several conversation branches can share one cached prefix\n // without corrupting each other's transcripts.\n options.forkSession = true;\n }\n const thinking = mapThinking(req.thinking);\n if (thinking) options.thinking = thinking;\n if (req.effort) options.effort = req.effort as EffortLevel;\n\n const prompt = req.media && req.media.length > 0 ? mediaPrompt(req.prompt, req.media) : req.prompt;\n\n let result: SDKResultMessage | undefined;\n let model: string | undefined;\n let stopReason: string | undefined;\n let sawText = false;\n\n try {\n for await (const msg of query({ prompt, options })) {\n if (msg.type === \"system\" && msg.subtype === \"init\") {\n yield { type: \"session\", sessionId: msg.session_id };\n } else if (msg.type === \"stream_event\" && msg.parent_tool_use_id === null) {\n const event = msg.event as unknown as RawStreamEvent;\n if (event.type !== \"content_block_delta\") continue;\n const delta = event[\"delta\"] as { type?: string; text?: string; thinking?: string } | undefined;\n if (delta?.type === \"text_delta\" && typeof delta.text === \"string\") {\n sawText = true;\n yield { type: \"text\", text: delta.text };\n } else if (delta?.type === \"thinking_delta\" && typeof delta.thinking === \"string\") {\n yield { type: \"thinking\", text: delta.thinking };\n }\n } else if (msg.type === \"assistant\" && msg.parent_tool_use_id === null) {\n const raw = msg.message as { model?: string; stop_reason?: string | null };\n if (typeof raw.model === \"string\") model = raw.model;\n if (typeof raw.stop_reason === \"string\") stopReason = raw.stop_reason;\n } else if (msg.type === \"result\") {\n result = msg;\n }\n }\n } catch (err) {\n throw classifyProviderFailure(this.id, this.loginCommand, err);\n } finally {\n req.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n if (req.signal?.aborted) return;\n if (!result) throw new ProviderError(this.id, \"engine terminated without producing a result\");\n if (result.subtype !== \"success\") {\n const detail = \"errors\" in result && result.errors.length > 0 ? result.errors.join(\"; \") : result.subtype;\n throw classifyProviderFailure(this.id, this.loginCommand, new Error(`engine error: ${detail}`));\n }\n // Some engine paths emit no partial events; fall back to the final text.\n if (!sawText && result.result) yield { type: \"text\", text: result.result };\n\n yield {\n type: \"done\",\n usage: mapUsage(result.usage as unknown as Record<string, unknown>),\n ...(result.total_cost_usd !== undefined ? { costUsd: result.total_cost_usd } : {}),\n ...(model ? { model } : {}),\n ...(stopReason ? { stopReason } : {}),\n };\n }\n\n /** Ask the CLI which models it supports via a short-lived control session. */\n async listModels(): Promise<EngineModel[]> {\n const abortController = new AbortController();\n // A streaming-input prompt that stays open: the spawned CLI idles while\n // the supported-models control request runs, then gets torn down.\n let release!: () => void;\n const gate = new Promise<void>((resolve) => (release = resolve));\n const idle = (async function* (): AsyncGenerator<SDKUserMessage> {\n await gate;\n })();\n\n const q = query({ prompt: idle, options: { ...this.baseOptions(), abortController } });\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const models = await Promise.race([\n q.supportedModels(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"timed out probing supported models\")), 15_000);\n timer.unref?.();\n }),\n ]);\n return models.map((m) => ({\n id: m.value,\n display_name: m.displayName,\n ...(m.description ? { description: m.description } : {}),\n ...(m.resolvedModel ? { resolved_model: m.resolvedModel } : {}),\n ...(m.supportedEffortLevels?.length\n ? { reasoning_efforts: m.supportedEffortLevels.map((id) => ({ id })) }\n : {}),\n ...(m.supportsAdaptiveThinking ? { supports_adaptive_thinking: true } : {}),\n ...(m.supportsFastMode ? { supports_fast_mode: true } : {}),\n ...(m.supportsAutoMode ? { supports_auto_mode: true } : {}),\n }));\n } catch (err) {\n throw classifyProviderFailure(this.id, this.loginCommand, err);\n } finally {\n if (timer) clearTimeout(timer);\n release();\n abortController.abort();\n }\n }\n\n async version(): Promise<string | undefined> {\n try {\n const out = spawnSync(this.executable, [\"--version\"], { encoding: \"utf8\", timeout: 10_000 });\n return out.stdout?.trim().split(\"\\n\")[0] || undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Compare the bundled Agent SDK build against the installed CLI. Their\n * last version components track the same build number when in sync.\n */\n async versionSkew(): Promise<VersionSkew | undefined> {\n const binary = await this.version();\n const sdk = sdkVersion();\n if (!binary || !sdk) return undefined;\n const binaryVersion = binary.match(/\\d+\\.\\d+\\.\\d+/)?.[0];\n if (!binaryVersion) return undefined;\n const sdkBuild = sdk.split(\".\").pop();\n const binBuild = binaryVersion.split(\".\").pop();\n const inSync = sdkBuild === binBuild;\n return {\n sdkVersion: sdk,\n binaryVersion,\n inSync,\n note: inSync\n ? \"Agent SDK and claude binary are the same build\"\n : `Agent SDK ${sdk} was built alongside claude x.y.${sdkBuild}; you run ${binaryVersion}. Usually fine — update whichever is older if something misbehaves.`,\n };\n }\n}\n\nfunction sdkVersion(): string | undefined {\n try {\n const req = createRequire(import.meta.url);\n const entry = req.resolve(\"@anthropic-ai/claude-agent-sdk\");\n let dir = path.dirname(entry);\n for (let i = 0; i < 4; i += 1) {\n const pkg = path.join(dir, \"package.json\");\n if (fs.existsSync(pkg)) {\n const parsed = JSON.parse(fs.readFileSync(pkg, \"utf8\")) as { name?: string; version?: string };\n if (parsed.name === \"@anthropic-ai/claude-agent-sdk\") return parsed.version;\n }\n dir = path.dirname(dir);\n }\n } catch {\n // not resolvable (bundled differently) — skip the check\n }\n return undefined;\n}\n\nfunction mapThinking(t: ThinkingParam | undefined): ThinkingConfig | undefined {\n if (t == null) return undefined;\n if (t.type === \"enabled\") {\n return typeof t.budget_tokens === \"number\" ? { type: \"enabled\", budgetTokens: t.budget_tokens } : { type: \"enabled\" };\n }\n if (t.type === \"disabled\") return { type: \"disabled\" };\n return { type: \"adaptive\" };\n}\n\nexport function mapUsage(usage: Record<string, unknown>): Usage {\n const num = (key: string): number | undefined => (typeof usage[key] === \"number\" ? (usage[key] as number) : undefined);\n return {\n input_tokens: num(\"input_tokens\") ?? 0,\n output_tokens: num(\"output_tokens\") ?? 0,\n cache_creation_input_tokens: num(\"cache_creation_input_tokens\") ?? 0,\n cache_read_input_tokens: num(\"cache_read_input_tokens\") ?? 0,\n };\n}\n\n/**\n * User turn carrying image/document blocks: sent via the SDK's streaming\n * input mode, which accepts full Anthropic content blocks. The iterable\n * yields exactly one message, so the turn (and process) still ends normally.\n */\nfunction mediaPrompt(text: string, media: ContentBlockParam[]): AsyncIterable<SDKUserMessage> {\n const content = [...media, ...(text.length > 0 ? [{ type: \"text\", text }] : [])];\n const message = {\n type: \"user\",\n message: { role: \"user\", content },\n parent_tool_use_id: null,\n } as unknown as SDKUserMessage;\n return (async function* () {\n yield message;\n })();\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline\";\nimport { resolveExecutable } from \"../executable.js\";\nimport { classifyProviderFailure, ProviderError } from \"../errors.js\";\nimport type { EngineModel } from \"../models.js\";\nimport type {\n Provider,\n ProviderCapabilities,\n ProviderSession,\n ProviderSessionOptions,\n SessionProvider,\n TurnEvent,\n TurnRequest,\n} from \"../provider.js\";\nimport type { ContentBlockParam, Usage } from \"../types.js\";\nimport { CodexAgentSession } from \"./codexSession.js\";\nimport { spawnJsonl } from \"./jsonl.js\";\nimport { killTree } from \"./process.js\";\nimport { VERSION } from \"../../version.js\";\n\nexport type CodexSandboxMode = \"read-only\" | \"workspace-write\" | \"danger-full-access\";\n\nexport interface CodexProviderOptions {\n /** Path to the `codex` binary. Auto-resolved when omitted. */\n path?: string;\n /** Working directory for completion turns. */\n workDir?: string;\n /** Sandbox for completion turns (default read-only). */\n sandbox?: CodexSandboxMode;\n env?: Record<string, string>;\n}\n\nconst INSTALL_HINT = \"Install Codex CLI (npm i -g @openai/codex or brew install codex) and run `codex login`.\";\n\ninterface CodexItem {\n id: string;\n type: string;\n text?: string;\n message?: string;\n}\n\n/** OpenAI Codex CLI via `codex exec --json`, signed in with the user's ChatGPT account. */\nexport class CodexProvider implements SessionProvider {\n readonly id = \"codex\";\n readonly label = \"Codex CLI\";\n readonly executable: string;\n readonly loginCommand = \"codex login\";\n readonly capabilities: ProviderCapabilities = {\n resume: true,\n fork: false,\n images: true,\n documents: false,\n systemPrompt: false,\n thinking: false,\n effort: true,\n streaming: \"chunks\",\n serverTools: false,\n };\n readonly sessionCapabilities = { fork: true } as const;\n\n private readonly workDir: string;\n private readonly sandbox: CodexSandboxMode;\n private readonly env: NodeJS.ProcessEnv;\n\n constructor(options: CodexProviderOptions = {}) {\n this.executable = resolveExecutable(\"codex\", \"codex\", INSTALL_HINT, {\n ...(options.path ?? process.env[\"YAGAMI_CODEX_PATH\"]\n ? { explicit: options.path ?? process.env[\"YAGAMI_CODEX_PATH\"] }\n : {}),\n });\n this.workDir = options.workDir ?? path.join(os.tmpdir(), \"yagami-workspace\");\n this.sandbox = options.sandbox ?? \"read-only\";\n this.env = { ...process.env, ...options.env };\n fs.mkdirSync(this.workDir, { recursive: true });\n }\n\n /** Build the `codex exec` argument list for a turn (exported for tests). */\n buildArgs(req: TurnRequest, imagePaths: string[]): string[] {\n const args = [\"exec\", \"--json\", \"--skip-git-repo-check\", \"-C\", this.workDir, \"-s\", this.sandbox, \"--color\", \"never\"];\n if (req.model) args.push(\"-m\", req.model);\n if (req.effort) args.push(\"-c\", `model_reasoning_effort=\"${req.effort}\"`);\n for (const p of imagePaths) args.push(\"-i\", p);\n if (req.resume) args.push(\"resume\", req.resume);\n args.push(req.prompt);\n return args;\n }\n\n async *run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined> {\n const { paths: imagePaths, cleanup } = writeTempImages(req.media ?? []);\n const emitted = new Map<string, number>();\n let done = false;\n try {\n for await (const raw of spawnJsonl({\n command: this.executable,\n args: this.buildArgs(req, imagePaths),\n cwd: this.workDir,\n env: this.env,\n ...(req.signal ? { signal: req.signal } : {}),\n })) {\n const ev = raw as { type: string; thread_id?: string; item?: CodexItem; usage?: Record<string, number>; error?: { message?: string }; message?: string };\n switch (ev.type) {\n case \"thread.started\":\n if (ev.thread_id) yield { type: \"session\", sessionId: ev.thread_id };\n break;\n case \"item.started\":\n case \"item.updated\":\n case \"item.completed\": {\n const item = ev.item;\n if (!item || typeof item.text !== \"string\") break;\n if (item.type !== \"agent_message\" && item.type !== \"reasoning\") break;\n // Items carry their full text so far; emit only what is new.\n const seen = emitted.get(item.id) ?? 0;\n const fresh = item.text.slice(seen);\n emitted.set(item.id, item.text.length);\n if (fresh) yield { type: item.type === \"agent_message\" ? \"text\" : \"thinking\", text: fresh };\n break;\n }\n case \"turn.completed\":\n done = true;\n yield { type: \"done\", usage: mapCodexUsage(ev.usage ?? {}), stopReason: \"end_turn\" };\n break;\n case \"turn.failed\":\n throw new Error(ev.error?.message ?? \"turn failed\");\n case \"error\":\n throw new Error(ev.message ?? \"codex error\");\n default:\n break;\n }\n }\n } catch (err) {\n throw classifyProviderFailure(this.id, this.loginCommand, err);\n } finally {\n cleanup();\n }\n if (req.signal?.aborted) return;\n if (!done) throw new ProviderError(this.id, \"codex exited without completing the turn\");\n }\n\n /**\n * A live, interactive Codex session (`codex app-server` — the TUI's own\n * engine): streamed tool events, the user's config.toml verbatim, and\n * approval requests forwarded to the host's permission handler. The\n * completion-turn `run()` path above stays for API-style callers.\n */\n openSession(options: ProviderSessionOptions): ProviderSession {\n return new CodexAgentSession({\n executable: this.executable,\n env: this.env,\n loginCommand: this.loginCommand,\n options,\n });\n }\n\n /** Ask the app-server protocol for the model catalog (no tokens spent). */\n listModels(): Promise<EngineModel[]> {\n return new Promise<EngineModel[]>((resolve, reject) => {\n const child = spawn(this.executable, [\"app-server\"], { env: this.env, stdio: [\"pipe\", \"pipe\", \"pipe\"] });\n let stderr = \"\";\n let settled = false;\n const finish = (fn: () => void) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n killTree(child);\n fn();\n };\n const timer = setTimeout(() => finish(() => reject(new ProviderError(this.id, \"timed out listing models via app-server\"))), 15_000);\n timer.unref?.();\n child.stderr.on(\"data\", (d: Buffer) => (stderr += d.toString()));\n child.on(\"error\", (err) => finish(() => reject(classifyProviderFailure(this.id, this.loginCommand, err))));\n child.on(\"close\", () =>\n finish(() => reject(classifyProviderFailure(this.id, this.loginCommand, new Error(stderr.trim() || \"app-server exited\")))),\n );\n const rl = readline.createInterface({ input: child.stdout });\n rl.on(\"line\", (line) => {\n let msg: { id?: number; result?: { data?: Array<Record<string, unknown>> }; error?: { message?: string } };\n try {\n msg = JSON.parse(line);\n } catch {\n return;\n }\n if (msg.id === 1) {\n child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", method: \"initialized\", params: {} })}\\n`);\n child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", id: 2, method: \"model/list\", params: {} })}\\n`);\n } else if (msg.id === 2) {\n if (msg.error) {\n finish(() => reject(classifyProviderFailure(this.id, this.loginCommand, new Error(msg.error?.message ?? \"model/list failed\"))));\n return;\n }\n const models = (msg.result?.data ?? [])\n .filter((m) => m[\"hidden\"] !== true)\n .map((m) => {\n const efforts = Array.isArray(m[\"supportedReasoningEfforts\"])\n ? (m[\"supportedReasoningEfforts\"] as Array<Record<string, unknown>>).flatMap((entry) =>\n typeof entry[\"reasoningEffort\"] === \"string\"\n ? [{\n id: entry[\"reasoningEffort\"],\n ...(typeof entry[\"description\"] === \"string\" ? { description: entry[\"description\"] } : {}),\n }]\n : [],\n )\n : [];\n const tiers = Array.isArray(m[\"serviceTiers\"])\n ? (m[\"serviceTiers\"] as Array<Record<string, unknown>>).flatMap((entry) =>\n typeof entry[\"id\"] === \"string\"\n ? [{\n id: entry[\"id\"],\n display_name: typeof entry[\"name\"] === \"string\" ? entry[\"name\"] : entry[\"id\"],\n ...(typeof entry[\"description\"] === \"string\" ? { description: entry[\"description\"] } : {}),\n }]\n : [],\n )\n : [];\n return {\n id: String(m[\"id\"] ?? m[\"model\"]),\n display_name: String(m[\"displayName\"] ?? m[\"id\"] ?? m[\"model\"]),\n ...(typeof m[\"description\"] === \"string\" ? { description: m[\"description\"] as string } : {}),\n ...(efforts.length > 0 ? { reasoning_efforts: efforts } : {}),\n ...(typeof m[\"defaultReasoningEffort\"] === \"string\"\n ? { default_reasoning_effort: m[\"defaultReasoningEffort\"] }\n : {}),\n ...(Array.isArray(m[\"inputModalities\"])\n ? { input_modalities: m[\"inputModalities\"].filter((value): value is string => typeof value === \"string\") }\n : {}),\n ...(m[\"supportsPersonality\"] === true ? { supports_personality: true } : {}),\n ...(typeof m[\"multiAgentVersion\"] === \"string\" ? { multi_agent: m[\"multiAgentVersion\"] } : {}),\n ...(tiers.length > 0 ? { service_tiers: tiers } : {}),\n ...(typeof m[\"defaultServiceTier\"] === \"string\"\n ? { default_service_tier: m[\"defaultServiceTier\"] }\n : {}),\n ...(m[\"isDefault\"] === true ? { is_default: true } : {}),\n };\n });\n finish(() => resolve(models));\n }\n });\n child.stdin.write(\n `${JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"initialize\",\n params: { clientInfo: { name: \"yagami\", title: \"yagami\", version: VERSION } },\n })}\\n`,\n );\n });\n }\n\n async version(): Promise<string | undefined> {\n try {\n const out = spawnSync(this.executable, [\"--version\"], { encoding: \"utf8\", timeout: 10_000 });\n return out.stdout?.trim().split(\"\\n\")[0] || undefined;\n } catch {\n return undefined;\n }\n }\n}\n\nfunction mapCodexUsage(u: Record<string, number>): Usage {\n return {\n input_tokens: u[\"input_tokens\"] ?? 0,\n output_tokens: u[\"output_tokens\"] ?? 0,\n cache_read_input_tokens: u[\"cached_input_tokens\"] ?? 0,\n cache_creation_input_tokens: u[\"cache_write_input_tokens\"] ?? 0,\n };\n}\n\nconst EXT_BY_MIME: Record<string, string> = {\n \"image/png\": \".png\",\n \"image/jpeg\": \".jpg\",\n \"image/gif\": \".gif\",\n \"image/webp\": \".webp\",\n};\n\n/** Codex takes images as files: materialize base64 blocks into a temp dir. */\nexport function writeTempImages(media: ContentBlockParam[]): { paths: string[]; cleanup: () => void } {\n const images = media.filter((b) => b.type === \"image\");\n if (images.length === 0) return { paths: [], cleanup: () => {} };\n const dir = fs.mkdtempSync(path.join(os.tmpdir(), \"yagami-img-\"));\n const paths: string[] = [];\n images.forEach((block, i) => {\n const source = block[\"source\"] as { type?: string; data?: string; media_type?: string } | undefined;\n if (source?.type !== \"base64\" || typeof source.data !== \"string\") {\n fs.rmSync(dir, { recursive: true, force: true });\n throw new ProviderError(\"codex\", \"only base64 image sources are supported (URL images are not fetched)\");\n }\n const file = path.join(dir, `image-${i}${EXT_BY_MIME[source.media_type ?? \"\"] ?? \".png\"}`);\n fs.writeFileSync(file, Buffer.from(source.data, \"base64\"));\n paths.push(file);\n });\n return { paths, cleanup: () => fs.rmSync(dir, { recursive: true, force: true }) };\n}\n","import { spawn, type ChildProcess } from \"node:child_process\";\nimport * as readline from \"node:readline\";\nimport { AuthRequiredError, classifyProviderFailure, looksLikeAuthFailure, ProviderError } from \"../errors.js\";\nimport { declineInput, elicitationRequest, elicitationResponse } from \"../interaction.js\";\nimport type {\n AgentEvent,\n ProviderSession,\n ProviderSessionOptions,\n SessionPermissionDecision,\n SessionPermissionRequest,\n SessionInputField,\n SessionInputRequest,\n SessionInputResponse,\n SessionPlanStatus,\n} from \"../provider.js\";\nimport type { ContentBlockParam, Usage } from \"../types.js\";\nimport { writeTempImages } from \"./codex.js\";\nimport { killTree } from \"./process.js\";\nimport { AsyncQueue } from \"./queue.js\";\nimport { VERSION } from \"../../version.js\";\n\n/**\n * A live, interactive Codex session over `codex app-server` — the same\n * engine the Codex TUI runs on, warm across turns. Nothing is overridden\n * unless asked: approval policy, sandbox, and instructions all come from the\n * user's own `~/.codex/config.toml`, and approval requests are forwarded to\n * the host's permission handler exactly as the TUI would prompt.\n *\n * Protocol: JSON-RPC over stdio, thread/turn API (`thread/start`,\n * `turn/start`, item notifications, server-initiated approval requests).\n */\n\ninterface CodexSessionConfig {\n executable: string;\n env: NodeJS.ProcessEnv;\n loginCommand: string;\n options: ProviderSessionOptions;\n}\n\ninterface RpcMessage {\n id?: number | string;\n method?: string;\n params?: Record<string, unknown>;\n result?: Record<string, unknown>;\n error?: { code?: number; message?: string };\n}\n\ntype Pending = { resolve: (v: Record<string, unknown>) => void; reject: (e: Error) => void };\n\n/** Codex native overrides accepted via ProviderSessionOptions.native. */\ninterface CodexNative {\n sandbox?: string;\n approvalPolicy?: string;\n config?: Record<string, unknown>;\n}\n\nexport class CodexAgentSession implements ProviderSession {\n readonly provider = \"codex\";\n\n private child: ChildProcess | undefined;\n private nextId = 1;\n private readonly pending = new Map<number, Pending>();\n private threadId: string | undefined;\n private currentTurnId: string | undefined;\n private queue: AsyncQueue<AgentEvent> | null = null;\n private lastUsage: Usage | undefined;\n private opening: Promise<void> | undefined;\n private closed = false;\n private sending = false;\n private turnAbort: AbortController | undefined;\n private readonly reasoningEmitted = new Map<string, number>();\n private readonly incoming = new Map<number | string, AbortController>();\n /** Item text already emitted as deltas, so item/completed only fills gaps. */\n private readonly emitted = new Map<string, number>();\n\n constructor(private readonly config: CodexSessionConfig) {}\n\n get id(): string | undefined {\n return this.threadId;\n }\n\n private fail(err: Error): void {\n this.turnAbort?.abort();\n for (const [, p] of this.pending) p.reject(err);\n this.pending.clear();\n this.queue?.fail(err);\n this.queue = null;\n }\n\n private classify(err: unknown): Error {\n const message = err instanceof Error ? err.message : String(err);\n if (looksLikeAuthFailure(message)) {\n return new AuthRequiredError(\"codex\", this.config.loginCommand, message.slice(0, 200));\n }\n return classifyProviderFailure(\"codex\", this.config.loginCommand, err);\n }\n\n private request(method: string, params: unknown): Promise<Record<string, unknown>> {\n const child = this.child;\n if (!child?.stdin?.writable) return Promise.reject(new ProviderError(\"codex\", \"app-server is not running\"));\n const id = this.nextId++;\n const promise = new Promise<Record<string, unknown>>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n });\n child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", id, method, params })}\\n`);\n return promise;\n }\n\n private respond(id: number | string, result: unknown): void {\n if (this.incoming.get(id)?.signal.aborted) return;\n this.child?.stdin?.write(`${JSON.stringify({ jsonrpc: \"2.0\", id, result })}\\n`);\n }\n\n private notify(method: string, params: unknown): void {\n this.child?.stdin?.write(`${JSON.stringify({ jsonrpc: \"2.0\", method, params })}\\n`);\n }\n\n private ensureOpen(): Promise<void> {\n this.opening ??= this.open();\n return this.opening;\n }\n\n private async open(): Promise<void> {\n const { executable, env, options } = this.config;\n const child = spawn(executable, [\"app-server\"], {\n cwd: options.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n this.child = child;\n let stderr = \"\";\n child.stderr?.on(\"data\", (d: Buffer) => {\n stderr += d.toString();\n if (stderr.length > 16_000) stderr = stderr.slice(-8_000);\n });\n child.on(\"error\", (err) => this.fail(this.classify(err)));\n child.on(\"exit\", (code) => {\n if (this.closed) return;\n this.fail(this.classify(new Error(`codex app-server exited with code ${code}${stderr ? `: ${stderr.trim().slice(-400)}` : \"\"}`)));\n });\n const rl = readline.createInterface({ input: child.stdout! });\n rl.on(\"line\", (line) => {\n let msg: RpcMessage;\n try {\n msg = JSON.parse(line) as RpcMessage;\n } catch {\n return;\n }\n this.dispatch(msg);\n });\n\n await this.request(\"initialize\", {\n clientInfo: { name: this.config.options.appName ?? \"yagami\", title: this.config.options.appName ?? \"yagami\", version: VERSION },\n capabilities: { experimentalApi: true, requestAttestation: false },\n });\n this.notify(\"initialized\", {});\n\n const native = (options.native ?? {}) as CodexNative;\n const overrides = {\n cwd: options.cwd,\n ...(options.model ? { model: options.model } : {}),\n ...(native.approvalPolicy ? { approvalPolicy: native.approvalPolicy } : {}),\n ...(native.sandbox ? { sandbox: native.sandbox } : {}),\n ...(native.config ? { config: native.config } : {}),\n ...(options.systemPrompt ? { developerInstructions: options.systemPrompt } : {}),\n };\n if (options.resume && (options.fork || options.forkAt)) {\n const forked = await this.request(\"thread/fork\", {\n threadId: options.resume,\n ...(options.forkAt ? { lastTurnId: options.forkAt } : {}),\n ...overrides,\n });\n this.threadId = (forked[\"thread\"] as { id?: string } | undefined)?.id;\n if (!this.threadId) throw new ProviderError(\"codex\", \"thread/fork returned no thread id\");\n return;\n }\n if (options.resume) {\n // A failed resume must never erase the caller's conversation by\n // quietly starting an empty thread (network and auth errors included).\n const resumed = await this.request(\"thread/resume\", { threadId: options.resume, ...overrides });\n this.threadId = (resumed[\"thread\"] as { id?: string } | undefined)?.id ?? options.resume;\n return;\n }\n const started = await this.request(\"thread/start\", overrides);\n this.threadId = (started[\"thread\"] as { id?: string } | undefined)?.id;\n if (!this.threadId) throw new ProviderError(\"codex\", \"thread/start returned no thread id\");\n }\n\n // ── inbound traffic ────────────────────────────────────────────────\n\n private dispatch(msg: RpcMessage): void {\n // responses to our requests\n if (msg.method === undefined && msg.id !== undefined) {\n const pending = this.pending.get(msg.id as number);\n if (!pending) return;\n this.pending.delete(msg.id as number);\n if (msg.error) pending.reject(this.classify(new Error(msg.error.message ?? \"codex error\")));\n else pending.resolve(msg.result ?? {});\n return;\n }\n if (!msg.method) return;\n // server-initiated requests (approvals and friends) carry an id\n if (msg.id !== undefined) {\n const id = msg.id;\n const controller = new AbortController();\n const parent = this.turnAbort?.signal;\n const cancel = () => controller.abort();\n if (parent?.aborted) controller.abort();\n else parent?.addEventListener(\"abort\", cancel, { once: true });\n this.incoming.set(id, controller);\n void this.handleServerRequest(msg.method, id, msg.params ?? {}, controller.signal).finally(() => {\n parent?.removeEventListener(\"abort\", cancel);\n this.incoming.delete(id);\n });\n return;\n }\n this.handleNotification(msg.method, msg.params ?? {});\n }\n\n private push(event: AgentEvent): void {\n this.queue?.push(event);\n }\n\n private handleNotification(method: string, params: Record<string, unknown>): void {\n if (params[\"threadId\"] !== undefined && params[\"threadId\"] !== this.threadId) return;\n if (this.currentTurnId && typeof params[\"turnId\"] === \"string\" && params[\"turnId\"] !== this.currentTurnId) return;\n switch (method) {\n case \"serverRequest/resolved\": {\n const requestId = params[\"requestId\"];\n if (typeof requestId === \"string\" || typeof requestId === \"number\") this.incoming.get(requestId)?.abort();\n break;\n }\n case \"item/agentMessage/delta\": {\n const itemId = params[\"itemId\"] as string;\n const delta = params[\"delta\"] as string;\n this.emitted.set(itemId, (this.emitted.get(itemId) ?? 0) + delta.length);\n this.push({ type: \"text\", text: delta });\n break;\n }\n case \"item/reasoning/summaryTextDelta\": {\n const delta = params[\"delta\"];\n if (typeof delta !== \"string\") break;\n const key = `${String(params[\"itemId\"])}:${String(params[\"summaryIndex\"] ?? 0)}`;\n this.reasoningEmitted.set(key, (this.reasoningEmitted.get(key) ?? 0) + delta.length);\n this.push({ type: \"thinking\", text: delta });\n break;\n }\n case \"item/started\":\n case \"item/completed\": {\n this.handleItem(params[\"item\"] as Record<string, unknown>, method === \"item/completed\");\n break;\n }\n case \"thread/tokenUsage/updated\": {\n const usage = params[\"tokenUsage\"] as { last?: Record<string, number> } | undefined;\n const last = usage?.last;\n if (last) {\n this.lastUsage = {\n input_tokens: last[\"inputTokens\"] ?? 0,\n output_tokens: last[\"outputTokens\"] ?? 0,\n cache_read_input_tokens: last[\"cachedInputTokens\"] ?? 0,\n cache_creation_input_tokens: last[\"cacheWriteInputTokens\"] ?? 0,\n };\n }\n break;\n }\n case \"turn/plan/updated\": {\n const steps = Array.isArray(params[\"plan\"]) ? params[\"plan\"] : [];\n this.push({\n type: \"plan\",\n plan: {\n ...(typeof params[\"explanation\"] === \"string\" ? { explanation: params[\"explanation\"] } : {}),\n entries: steps.flatMap((value) => {\n const step = value as Record<string, unknown>;\n if (typeof step[\"step\"] !== \"string\") return [];\n return [{\n content: step[\"step\"],\n status: codexPlanStatus(step[\"status\"]),\n }];\n }),\n },\n });\n break;\n }\n case \"turn/completed\": {\n const turn = params[\"turn\"] as { status?: string; error?: { message?: string } | null };\n const turnId = (params[\"turn\"] as { id?: string } | undefined)?.id;\n if (this.currentTurnId && turnId && turnId !== this.currentTurnId) break;\n const queue = this.queue;\n this.queue = null;\n this.currentTurnId = undefined;\n this.turnAbort?.abort();\n if (!queue) break;\n if (turn.status === \"failed\") {\n queue.fail(this.classify(new Error(turn.error?.message ?? \"turn failed\")));\n } else {\n queue.push({\n type: \"done\",\n ...(this.lastUsage ? { usage: this.lastUsage } : {}),\n stopReason: turn.status === \"interrupted\" ? \"interrupted\" : \"end_turn\",\n });\n queue.end();\n }\n break;\n }\n case \"error\": {\n // non-fatal server chatter; the turn's fate rides turn/completed\n this.push({ type: \"raw\", provider: \"codex\", payload: { method, params } });\n break;\n }\n default:\n break;\n }\n }\n\n /** Normalize thread items into tool_call / thinking events. */\n private handleItem(item: Record<string, unknown> | undefined, completed: boolean): void {\n if (!item) return;\n const id = String(item[\"id\"] ?? \"\");\n switch (item[\"type\"]) {\n case \"agentMessage\": {\n if (!completed) break;\n // fill in whatever the deltas didn't cover (non-streaming paths)\n const text = String(item[\"text\"] ?? \"\");\n const seen = this.emitted.get(id) ?? 0;\n if (text.length > seen) this.push({ type: \"text\", text: text.slice(seen) });\n this.emitted.delete(id);\n break;\n }\n case \"reasoning\": {\n if (!completed) break;\n const summaries = (item[\"summary\"] as string[] | undefined) ?? [];\n summaries.forEach((summary, index) => {\n const key = `${id}:${index}`;\n const seen = this.reasoningEmitted.get(key) ?? 0;\n if (summary.length > seen) this.push({ type: \"thinking\", text: summary.slice(seen) });\n this.reasoningEmitted.delete(key);\n });\n break;\n }\n case \"commandExecution\": {\n const failed = item[\"status\"] === \"failed\" || item[\"status\"] === \"declined\";\n this.push({\n type: \"tool_call\",\n id,\n name: \"shell\",\n status: completed ? (failed ? \"failed\" : \"completed\") : \"started\",\n title: String(item[\"command\"] ?? \"command\"),\n kind: \"execute\",\n input: { command: item[\"command\"], cwd: item[\"cwd\"] },\n ...(completed ? { output: { output: item[\"aggregatedOutput\"], exitCode: item[\"exitCode\"] } } : {}),\n });\n break;\n }\n case \"fileChange\": {\n const changes = (item[\"changes\"] as Array<{ path?: string }> | undefined) ?? [];\n const failed = item[\"status\"] === \"failed\" || item[\"status\"] === \"declined\";\n this.push({\n type: \"tool_call\",\n id,\n name: \"apply_patch\",\n status: completed ? (failed ? \"failed\" : \"completed\") : \"started\",\n title: changes.map((c) => c.path).filter(Boolean).join(\", \") || \"file changes\",\n kind: \"edit\",\n input: { changes },\n });\n break;\n }\n case \"mcpToolCall\": {\n this.push({\n type: \"tool_call\",\n id,\n name: `${String(item[\"server\"] ?? \"mcp\")}.${String(item[\"tool\"] ?? \"tool\")}`,\n status: completed ? (item[\"status\"] === \"failed\" ? \"failed\" : \"completed\") : \"started\",\n kind: \"other\",\n input: item[\"arguments\"],\n });\n break;\n }\n case \"webSearch\": {\n this.push({\n type: \"tool_call\",\n id,\n name: \"web_search\",\n status: completed ? \"completed\" : \"started\",\n kind: \"fetch\",\n input: { query: item[\"query\"] },\n });\n break;\n }\n case \"dynamicToolCall\": {\n const failed = item[\"status\"] === \"failed\" || item[\"success\"] === false;\n const namespace = typeof item[\"namespace\"] === \"string\" ? `${item[\"namespace\"]}.` : \"\";\n this.push({\n type: \"tool_call\",\n id,\n name: `${namespace}${String(item[\"tool\"] ?? \"tool\")}`,\n status: completed ? (failed ? \"failed\" : \"completed\") : \"started\",\n kind: \"other\",\n input: item[\"arguments\"],\n ...(completed ? { output: item[\"contentItems\"] } : {}),\n });\n break;\n }\n case \"collabAgentToolCall\": {\n const status = item[\"status\"];\n const failed = status === \"failed\" || status === \"interrupted\";\n const tool = collabToolName(item[\"tool\"]);\n this.push({\n type: \"tool_call\",\n id,\n name: tool,\n status: completed ? (failed ? \"failed\" : \"completed\") : \"started\",\n title: typeof item[\"prompt\"] === \"string\" && item[\"prompt\"] ? item[\"prompt\"] : tool,\n kind: \"other\",\n input: {\n prompt: item[\"prompt\"],\n model: item[\"model\"],\n effort: item[\"reasoningEffort\"],\n receiverThreadIds: item[\"receiverThreadIds\"],\n },\n ...(completed ? { output: item[\"agentsStates\"] } : {}),\n });\n break;\n }\n case \"imageView\": {\n this.push({\n type: \"tool_call\",\n id,\n name: \"read_file\",\n status: completed ? \"completed\" : \"started\",\n title: String(item[\"path\"] ?? \"image\"),\n kind: \"read\",\n input: { path: item[\"path\"] },\n });\n break;\n }\n case \"plan\":\n if (completed && typeof item[\"text\"] === \"string\") {\n this.push({ type: \"plan\", plan: { id, markdown: item[\"text\"] } });\n }\n break;\n case \"userMessage\":\n break;\n default:\n this.push({ type: \"raw\", provider: \"codex\", payload: item });\n break;\n }\n }\n\n // ── approvals: forwarded to the host, answered like the TUI would ──\n\n private async decide(request: SessionPermissionRequest, signal?: AbortSignal): Promise<SessionPermissionDecision> {\n if (signal?.aborted) return \"deny\";\n try {\n const decision = await this.config.options.permissions.decide(request, signal);\n this.push({ type: \"permission\", request, decision });\n return decision;\n } catch {\n return \"deny\";\n }\n }\n\n private async handleServerRequest(method: string, id: number | string, params: Record<string, unknown>, signal: AbortSignal): Promise<void> {\n switch (method) {\n case \"item/commandExecution/requestApproval\": {\n const decision = await this.decide({\n provider: \"codex\",\n ...(this.threadId ? { sessionId: this.threadId } : {}),\n tool: \"shell\",\n kind: \"execute\",\n title: String(params[\"command\"] ?? \"command\"),\n input: { command: params[\"command\"], cwd: params[\"cwd\"], reason: params[\"reason\"] },\n raw: params,\n }, signal);\n this.respond(id, {\n decision: decision === \"allow\" ? \"accept\" : decision === \"allow_always\" ? \"acceptForSession\" : \"decline\",\n });\n break;\n }\n case \"item/fileChange/requestApproval\": {\n const decision = await this.decide({\n provider: \"codex\",\n ...(this.threadId ? { sessionId: this.threadId } : {}),\n tool: \"apply_patch\",\n kind: \"edit\",\n title: String(params[\"reason\"] ?? \"apply file changes\"),\n input: { reason: params[\"reason\"], grantRoot: params[\"grantRoot\"] },\n raw: params,\n }, signal);\n this.respond(id, {\n decision: decision === \"allow\" ? \"accept\" : decision === \"allow_always\" ? \"acceptForSession\" : \"decline\",\n });\n break;\n }\n case \"item/permissions/requestApproval\": {\n const requested = params[\"permissions\"] as Record<string, unknown> | undefined;\n const decision = await this.decide({\n provider: \"codex\",\n ...(this.threadId ? { sessionId: this.threadId } : {}),\n tool: \"permissions\",\n kind: \"other\",\n title: String(params[\"reason\"] ?? \"extra permissions\"),\n input: requested,\n raw: params,\n }, signal);\n const granted = decision === \"allow\" || decision === \"allow_always\";\n this.respond(id, {\n permissions: granted ? { network: requested?.[\"network\"] ?? undefined, fileSystem: requested?.[\"fileSystem\"] ?? undefined } : {},\n scope: decision === \"allow_always\" ? \"session\" : \"turn\",\n });\n break;\n }\n // legacy approval shapes, still sent by some codepaths\n case \"execCommandApproval\":\n case \"applyPatchApproval\": {\n const decision = await this.decide({\n provider: \"codex\",\n ...(this.threadId ? { sessionId: this.threadId } : {}),\n tool: method === \"execCommandApproval\" ? \"shell\" : \"apply_patch\",\n kind: method === \"execCommandApproval\" ? \"execute\" : \"edit\",\n title: String(params[\"command\"] ?? params[\"reason\"] ?? \"approval\"),\n input: params,\n raw: params,\n }, signal);\n this.respond(id, {\n decision:\n decision === \"allow\"\n ? \"approved\"\n : decision === \"allow_always\"\n ? \"approved_for_session\"\n : { denied: { rejection: \"denied by the user\" } },\n });\n break;\n }\n case \"item/tool/requestUserInput\": {\n const response = await this.input(codexQuestionRequest(this.threadId, params), signal);\n const values = response.action === \"accept\" ? response.values ?? {} : {};\n this.respond(id, {\n answers: Object.fromEntries(\n Object.entries(values).map(([key, value]) => [\n key,\n { answers: (Array.isArray(value) ? value : [value]).map(String) },\n ]),\n ),\n });\n break;\n }\n case \"mcpServer/elicitation/request\": {\n const response = await this.input(elicitationRequest(\"codex\", this.threadId, params), signal);\n this.respond(id, { ...elicitationResponse(response), _meta: null });\n break;\n }\n case \"currentTime/read\": {\n this.respond(id, { currentTimeAt: Math.floor(Date.now() / 1000) });\n break;\n }\n default: {\n // unknown server request — decline rather than hang the turn\n this.child?.stdin?.write(\n `${JSON.stringify({ jsonrpc: \"2.0\", id, error: { code: -32601, message: `unsupported request: ${method}` } })}\\n`,\n );\n break;\n }\n }\n }\n\n private async input(request: SessionInputRequest, signal?: AbortSignal): Promise<SessionInputResponse> {\n const handler = this.config.options.input;\n if (!handler) return declineInput();\n try {\n if (signal?.aborted) return { action: \"cancel\" };\n return await handler.respond(request, signal);\n } catch {\n return { action: \"cancel\" };\n }\n }\n\n // ── the ProviderSession surface ────────────────────────────────────\n\n async *send(input: string | ContentBlockParam[]): AsyncGenerator<AgentEvent, void, undefined> {\n if (this.closed) throw new ProviderError(\"codex\", \"session is closed\");\n if (this.sending) throw new ProviderError(\"codex\", \"a turn is already running\");\n // Claim the turn before the first await: two cold sends otherwise both\n // pass the guard and replace each other's event queue after initialize.\n this.sending = true;\n const controller = new AbortController();\n this.turnAbort = controller;\n let cleanup = () => {};\n const queue = new AsyncQueue<AgentEvent>();\n try {\n await this.ensureOpen();\n if (controller.signal.aborted) {\n yield { type: \"done\", stopReason: \"interrupted\" };\n return;\n }\n const blocks = typeof input === \"string\" ? [{ type: \"text\", text: input } as ContentBlockParam] : input;\n const images = writeTempImages(blocks);\n cleanup = images.cleanup;\n const items: Array<Record<string, unknown>> = [];\n for (const block of blocks) {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n items.push({ type: \"text\", text: block.text, text_elements: [] });\n }\n }\n for (const p of images.paths) items.push({ type: \"localImage\", path: p });\n if (items.length === 0) items.push({ type: \"text\", text: \"\", text_elements: [] });\n\n this.queue = queue;\n this.lastUsage = undefined;\n this.emitted.clear();\n this.reasoningEmitted.clear();\n const result = await this.request(\"turn/start\", {\n threadId: this.threadId,\n input: items,\n ...(this.config.options.effort ? { effort: this.config.options.effort } : {}),\n });\n const turnId = (result[\"turn\"] as { id?: string } | undefined)?.id;\n // A short turn may finish before the RPC continuation runs.\n if (this.queue === queue) this.currentTurnId = turnId;\n if (controller.signal.aborted && this.currentTurnId) await this.interrupt();\n yield { type: \"session\", sessionId: this.threadId! };\n if (turnId) yield { type: \"turn\", id: turnId };\n for await (const event of queue) yield event;\n } finally {\n cleanup();\n controller.abort();\n // A caller that stops reading the generator also stops the model.\n if (this.queue === queue) await this.interrupt();\n if (this.queue === queue) this.queue = null;\n this.currentTurnId = undefined;\n this.turnAbort = undefined;\n this.sending = false;\n }\n }\n\n async interrupt(): Promise<void> {\n // Send cancellation before releasing waiting host handlers, so a late\n // answer cannot complete the turn ahead of the interruption.\n const request = this.threadId && this.currentTurnId\n ? this.request(\"turn/interrupt\", { threadId: this.threadId, turnId: this.currentTurnId }).catch(() => {})\n : Promise.resolve();\n this.turnAbort?.abort();\n await request;\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.fail(new ProviderError(\"codex\", \"session closed\"));\n killTree(this.child);\n this.child = undefined;\n }\n}\n\nfunction collabToolName(value: unknown): string {\n const names: Record<string, string> = {\n spawnAgent: \"spawn_agent\",\n sendInput: \"send_input\",\n resumeAgent: \"resume_agent\",\n closeAgent: \"close_agent\",\n sendMessage: \"send_message\",\n followupTask: \"followup_task\",\n interruptAgent: \"interrupt_agent\",\n listAgents: \"list_agents\",\n };\n return names[String(value)] ?? String(value ?? \"agent\");\n}\n\nfunction codexPlanStatus(value: unknown): SessionPlanStatus {\n return value === \"completed\" ? \"completed\" : value === \"inProgress\" || value === \"in_progress\" ? \"in_progress\" : \"pending\";\n}\n\nfunction codexQuestionRequest(sessionId: string | undefined, raw: Record<string, unknown>): SessionInputRequest {\n const questions = Array.isArray(raw[\"questions\"]) ? raw[\"questions\"] : [];\n const fields: SessionInputField[] = questions.flatMap((value) => {\n const question = value as Record<string, unknown>;\n if (typeof question[\"id\"] !== \"string\" || typeof question[\"question\"] !== \"string\") return [];\n const choices = Array.isArray(question[\"options\"])\n ? question[\"options\"].flatMap((option) => {\n const item = option as Record<string, unknown>;\n if (typeof item[\"label\"] !== \"string\") return [];\n return [{\n value: item[\"label\"],\n label: item[\"label\"],\n ...(typeof item[\"description\"] === \"string\" ? { description: item[\"description\"] } : {}),\n }];\n })\n : [];\n return [{\n id: question[\"id\"],\n label: question[\"question\"],\n ...(typeof question[\"header\"] === \"string\" ? { description: question[\"header\"] } : {}),\n type: choices.length > 0 ? \"select\" : \"string\",\n required: true,\n secret: question[\"isSecret\"] === true,\n allowOther: question[\"isOther\"] === true,\n ...(choices.length > 0 ? { options: choices } : {}),\n }];\n });\n return {\n provider: \"codex\",\n ...(sessionId ? { sessionId } : {}),\n kind: \"questions\",\n message: fields.length === 1 ? fields[0]!.label : \"Input requested\",\n fields,\n blocking: raw[\"isBlocking\"] !== false,\n raw,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport * as readline from \"node:readline\";\nimport { killTree } from \"./process.js\";\nimport { AsyncQueue } from \"./queue.js\";\n\nexport interface SpawnJsonlOptions {\n command: string;\n args: string[];\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n signal?: AbortSignal;\n /** Text written to the child's stdin before it is closed. */\n stdin?: string;\n}\n\nexport class ProcessExitError extends Error {\n constructor(\n readonly exitCode: number | null,\n readonly stderr: string,\n ) {\n super(`process exited with code ${exitCode}${stderr ? `: ${stderr.trim().split(\"\\n\").slice(-3).join(\" | \")}` : \"\"}`);\n this.name = \"ProcessExitError\";\n }\n}\n\n/**\n * Spawn a CLI that prints one JSON object per stdout line and iterate the\n * parsed objects. Non-JSON lines are skipped. A non-zero exit throws\n * ProcessExitError carrying the stderr tail; aborting the signal kills the\n * child and ends the iteration quietly. So does a consumer that stops\n * iterating early — the process has nobody left to answer, so it goes.\n */\nexport function spawnJsonl(options: SpawnJsonlOptions): AsyncIterable<unknown> {\n const queue = new AsyncQueue<unknown>();\n const child = spawn(options.command, options.args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [options.stdin !== undefined ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n });\n let stderr = \"\";\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n if (stderr.length > 16_000) stderr = stderr.slice(-8_000);\n });\n const rl = readline.createInterface({ input: child.stdout!, crlfDelay: Infinity });\n rl.on(\"line\", (line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"{\")) return;\n try {\n queue.push(JSON.parse(trimmed));\n } catch {\n // partial or non-JSON output — ignore\n }\n });\n const onAbort = () => {\n killTree(child);\n queue.end();\n };\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n queue.onReturn = () => {\n options.signal?.removeEventListener(\"abort\", onAbort);\n killTree(child);\n };\n child.on(\"error\", (err) => queue.fail(err));\n child.on(\"close\", (code) => {\n queue.onReturn = undefined;\n options.signal?.removeEventListener(\"abort\", onAbort);\n if (options.signal?.aborted) return queue.end();\n if (code !== 0) queue.fail(new ProcessExitError(code, stderr));\n else queue.end();\n });\n if (options.stdin !== undefined) {\n child.stdin?.end(options.stdin);\n }\n return queue;\n}\n","import { findExecutable } from \"../executable.js\";\nimport { ProviderNotInstalledError } from \"../errors.js\";\nimport type { Provider } from \"../provider.js\";\nimport { AcpProvider } from \"./acp.js\";\nimport { ClaudeProvider } from \"./claude.js\";\nimport { CodexProvider, type CodexSandboxMode } from \"./codex.js\";\n\nexport type ProviderKind = \"claude\" | \"codex\" | \"acp\";\n\n/** A harness yagami knows how to launch out of the box. */\nexport interface ProviderPreset {\n id: string;\n label: string;\n kind: ProviderKind;\n command: string;\n args: string[];\n loginCommand: string;\n installHint: string;\n}\n\n/**\n * Built-in catalog. Native drivers for Claude Code and Codex; everything\n * else speaks the Agent Client Protocol, with launch commands taken from\n * the ACP registry (cdn.agentclientprotocol.com/registry). Login commands\n * are best-effort hints.\n */\nexport const PROVIDER_PRESETS: readonly ProviderPreset[] = [\n { id: \"claude\", label: \"Claude Code\", kind: \"claude\", command: \"claude\", args: [], loginCommand: \"claude (then /login)\", installHint: \"npm i -g @anthropic-ai/claude-code\" },\n { id: \"codex\", label: \"Codex CLI\", kind: \"codex\", command: \"codex\", args: [], loginCommand: \"codex login\", installHint: \"npm i -g @openai/codex\" },\n { id: \"opencode\", label: \"OpenCode\", kind: \"acp\", command: \"opencode\", args: [\"acp\"], loginCommand: \"opencode auth login\", installHint: \"curl -fsSL https://opencode.ai/install | bash\" },\n { id: \"gemini\", label: \"Gemini CLI\", kind: \"acp\", command: \"gemini\", args: [\"--acp\"], loginCommand: \"gemini (then /auth)\", installHint: \"npm i -g @google/gemini-cli\" },\n { id: \"copilot\", label: \"GitHub Copilot CLI\", kind: \"acp\", command: \"copilot\", args: [\"--acp\"], loginCommand: \"copilot (then /login)\", installHint: \"npm i -g @github/copilot\" },\n { id: \"qwen\", label: \"Qwen Code\", kind: \"acp\", command: \"qwen\", args: [\"--acp\"], loginCommand: \"qwen (then /auth)\", installHint: \"npm i -g @qwen-code/qwen-code\" },\n { id: \"cursor\", label: \"Cursor Agent\", kind: \"acp\", command: \"cursor-agent\", args: [\"acp\"], loginCommand: \"cursor-agent login\", installHint: \"curl https://cursor.com/install -fsS | bash\" },\n { id: \"goose\", label: \"Goose\", kind: \"acp\", command: \"goose\", args: [\"acp\"], loginCommand: \"goose configure\", installHint: \"brew install block-goose-cli\" },\n { id: \"kimi\", label: \"Kimi CLI\", kind: \"acp\", command: \"kimi\", args: [\"acp\"], loginCommand: \"kimi login\", installHint: \"see github.com/MoonshotAI/kimi-cli\" },\n { id: \"kilo\", label: \"Kilo\", kind: \"acp\", command: \"kilo\", args: [\"acp\"], loginCommand: \"kilo login\", installHint: \"npm i -g @kilocode/cli\" },\n { id: \"cline\", label: \"Cline\", kind: \"acp\", command: \"cline\", args: [\"--acp\"], loginCommand: \"cline auth\", installHint: \"npm i -g cline\" },\n { id: \"auggie\", label: \"Auggie\", kind: \"acp\", command: \"auggie\", args: [\"--acp\"], loginCommand: \"auggie login\", installHint: \"npm i -g @augmentcode/auggie\" },\n { id: \"amp\", label: \"Amp\", kind: \"acp\", command: \"amp-acp\", args: [], loginCommand: \"amp login\", installHint: \"see ampcode.com\" },\n { id: \"grok\", label: \"Grok Build\", kind: \"acp\", command: \"grok\", args: [\"agent\", \"stdio\"], loginCommand: \"grok login\", installHint: \"npm i -g @xai-official/grok\" },\n { id: \"droid\", label: \"Factory Droid\", kind: \"acp\", command: \"droid\", args: [\"exec\", \"--output-format\", \"acp-daemon\"], loginCommand: \"droid login\", installHint: \"curl -fsSL https://app.factory.ai/cli | sh\" },\n { id: \"codex-acp\", label: \"Codex (ACP adapter)\", kind: \"acp\", command: \"codex-acp\", args: [], loginCommand: \"codex login\", installHint: \"npm i -g @agentclientprotocol/codex-acp\" },\n { id: \"claude-acp\", label: \"Claude (ACP adapter)\", kind: \"acp\", command: \"claude-agent-acp\", args: [], loginCommand: \"claude (then /login)\", installHint: \"npm i -g @agentclientprotocol/claude-agent-acp\" },\n];\n\n/** Per-provider settings from config.json (`providers.<id>`). */\nexport interface ProviderConfigEntry {\n /** Explicit executable path. */\n path?: string;\n /** Launch command for custom ACP agents (and overrides for presets). */\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n label?: string;\n /** Claude only: CLAUDE_CONFIG_DIR isolation. */\n configDir?: string;\n /** Codex only: sandbox for completion turns. */\n sandbox?: CodexSandboxMode;\n /** ACP only: id of the model config option (default \"model\"). */\n modelConfigId?: string;\n loginCommand?: string;\n /** Set false to skip this preset even if installed. */\n enabled?: boolean;\n}\n\nexport interface ProviderCommonOptions {\n workDir?: string;\n appName?: string;\n}\n\nexport function presetFor(id: string): ProviderPreset | undefined {\n return PROVIDER_PRESETS.find((p) => p.id === id);\n}\n\n/** Instantiate one provider by id from a preset and/or config entry. */\nexport function createProvider(id: string, entry: ProviderConfigEntry = {}, common: ProviderCommonOptions = {}): Provider {\n const preset = presetFor(id);\n const kind: ProviderKind = preset?.kind ?? \"acp\";\n if (kind === \"claude\") {\n return new ClaudeProvider({\n ...(entry.path ? { path: entry.path } : {}),\n ...(entry.configDir ? { configDir: entry.configDir } : {}),\n ...common,\n });\n }\n if (kind === \"codex\") {\n return new CodexProvider({\n ...(entry.path ? { path: entry.path } : {}),\n ...(entry.sandbox ? { sandbox: entry.sandbox } : {}),\n ...(entry.env ? { env: entry.env } : {}),\n ...(common.workDir ? { workDir: common.workDir } : {}),\n });\n }\n const command = entry.command ?? preset?.command;\n if (!command) {\n throw new ProviderNotInstalledError(id, `Add providers.${id}.command (an ACP agent launch command) to config.json.`, \"unknown provider with no command\");\n }\n return new AcpProvider({\n id,\n label: entry.label ?? preset?.label ?? id,\n command,\n args: entry.args ?? preset?.args ?? [],\n ...(entry.path ? { path: entry.path } : {}),\n ...(entry.env ? { env: entry.env } : {}),\n ...(entry.modelConfigId ? { modelConfigId: entry.modelConfigId } : {}),\n loginCommand: entry.loginCommand ?? preset?.loginCommand ?? `${command} (sign in per its docs)`,\n installHint: preset?.installHint ?? `Install \\`${command}\\`.`,\n ...common,\n });\n}\n\nexport interface LoadedProviders {\n providers: Map<string, Provider>;\n /** Providers that couldn't be constructed, with the reason (usually not installed). */\n unavailable: Map<string, string>;\n}\n\n/**\n * Build every provider that is installed on this machine: all presets plus\n * any custom entries in config. Missing CLIs are recorded, not fatal.\n */\nexport function loadProviders(\n config: Record<string, ProviderConfigEntry> = {},\n common: ProviderCommonOptions = {},\n): LoadedProviders {\n const ids = new Set<string>([...PROVIDER_PRESETS.map((p) => p.id), ...Object.keys(config)]);\n const providers = new Map<string, Provider>();\n const unavailable = new Map<string, string>();\n for (const id of ids) {\n const entry = config[id] ?? {};\n if (entry.enabled === false) {\n unavailable.set(id, \"disabled in config\");\n continue;\n }\n try {\n providers.set(id, createProvider(id, entry, common));\n } catch (err) {\n unavailable.set(id, err instanceof Error ? err.message : String(err));\n }\n }\n return { providers, unavailable };\n}\n\nexport interface DetectedProvider {\n id: string;\n label: string;\n kind: ProviderKind;\n installed: boolean;\n path?: string;\n loginCommand: string;\n installHint: string;\n}\n\n/** Which known harnesses exist on this machine (cheap: no processes spawned). */\nexport function detectProviders(config: Record<string, ProviderConfigEntry> = {}): DetectedProvider[] {\n const ids = new Set<string>([...PROVIDER_PRESETS.map((p) => p.id), ...Object.keys(config)]);\n return [...ids].map((id) => {\n const preset = presetFor(id);\n const entry = config[id] ?? {};\n const command = entry.command ?? preset?.command ?? id;\n const path = findExecutable(command, entry.path ? { explicit: entry.path } : {});\n return {\n id,\n label: entry.label ?? preset?.label ?? id,\n kind: preset?.kind ?? \"acp\",\n installed: path !== undefined && entry.enabled !== false,\n ...(path ? { path } : {}),\n loginCommand: entry.loginCommand ?? preset?.loginCommand ?? `${command} (sign in per its docs)`,\n installHint: preset?.installHint ?? `Install \\`${command}\\`.`,\n };\n });\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nexport interface SessionCacheOptions {\n maxEntries?: number;\n /** JSON file to persist the cache across restarts (best-effort). */\n persistPath?: string;\n}\n\n/**\n * LRU map from conversation-prefix hash to Claude Code session id.\n * Session transcripts themselves live in ~/.claude; this only remembers\n * which session corresponds to which conversation prefix.\n */\nexport class SessionCache {\n private readonly map = new Map<string, string>();\n private readonly maxEntries: number;\n private readonly persistPath: string | undefined;\n private persistTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(options: SessionCacheOptions = {}) {\n this.maxEntries = options.maxEntries ?? 1000;\n this.persistPath = options.persistPath;\n this.load();\n }\n\n get size(): number {\n return this.map.size;\n }\n\n get(key: string): string | undefined {\n const value = this.map.get(key);\n if (value !== undefined) {\n this.map.delete(key);\n this.map.set(key, value);\n }\n return value;\n }\n\n /** Drop a mapping, e.g. when its session turns out to be gone. */\n delete(key: string): void {\n if (this.map.delete(key)) this.schedulePersist();\n }\n\n set(key: string, sessionId: string): void {\n if (this.map.has(key)) this.map.delete(key);\n this.map.set(key, sessionId);\n while (this.map.size > this.maxEntries) {\n const oldest = this.map.keys().next().value;\n if (oldest === undefined) break;\n this.map.delete(oldest);\n }\n this.schedulePersist();\n }\n\n private load(): void {\n if (!this.persistPath) return;\n try {\n const raw = JSON.parse(fs.readFileSync(this.persistPath, \"utf8\")) as {\n entries?: Array<[string, string]>;\n };\n for (const [key, value] of raw.entries ?? []) {\n if (typeof key === \"string\" && typeof value === \"string\") this.map.set(key, value);\n }\n } catch {\n // missing or corrupt cache file — start empty\n }\n }\n\n private schedulePersist(): void {\n if (!this.persistPath) return;\n if (this.persistTimer) clearTimeout(this.persistTimer);\n this.persistTimer = setTimeout(() => this.persistNow(), 200);\n this.persistTimer.unref?.();\n }\n\n persistNow(): void {\n if (!this.persistPath) return;\n if (this.persistTimer) {\n clearTimeout(this.persistTimer);\n this.persistTimer = null;\n }\n try {\n fs.mkdirSync(path.dirname(this.persistPath), { recursive: true });\n fs.writeFileSync(\n this.persistPath,\n JSON.stringify({ version: 1, entries: [...this.map] }),\n { mode: 0o600 },\n );\n } catch {\n // persistence is best-effort; the cache still works in memory\n }\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { ProviderError, ProviderNotInstalledError, toApiError } from \"./errors.js\";\nimport type { EngineModel } from \"./models.js\";\nimport { parseModelRef, qualifiedModel, type Provider, type TurnEvent, type TurnRequest } from \"./provider.js\";\nimport { loadProviders, type ProviderConfigEntry } from \"./providers/registry.js\";\nimport { SessionCache } from \"./sessionCache.js\";\nimport { SseSynthesizer } from \"./sse.js\";\nimport {\n flattenConversation,\n normalizeRequest,\n prefillDirective,\n PrefillStripper,\n prefixKey,\n type NormalizedRequest,\n} from \"./transcript.js\";\nimport { ApiError, type ContentBlock, type MessagesRequest, type MessagesResponse, type SseEvent } from \"./types.js\";\n\nexport type { EngineModel } from \"./models.js\";\n\nconst EFFORT_LEVELS: ReadonlySet<string> = new Set([\"low\", \"medium\", \"high\", \"xhigh\", \"max\"]);\nconst THINKING_TYPES: ReadonlySet<string> = new Set([\"enabled\", \"disabled\", \"adaptive\"]);\n\nexport interface EngineOptions {\n /** Explicit provider instances (library mode). Overrides config-driven loading. */\n providers?: Provider[];\n /** Per-provider settings (`providers.<id>` in config.json). */\n providerConfig?: Record<string, ProviderConfigEntry>;\n /** Provider used for bare model ids (default: claude if installed, else the first available). */\n defaultProvider?: string;\n /** @deprecated Use providerConfig.claude.path. */\n claudePath?: string;\n /** @deprecated Use providerConfig.claude.configDir. */\n claudeConfigDir?: string;\n /** Working directory for completion turns (inert — tools are disabled/sandboxed). */\n workDir?: string;\n /** Model used when a request omits `model` (may be `provider:model`). */\n defaultModel?: string;\n sessionCache?: SessionCache;\n /** Reported to the CLIs as the client application name. */\n appName?: string;\n}\n\nexport interface CompleteResult {\n response: MessagesResponse;\n costUsd?: number;\n sessionId?: string;\n provider: string;\n ignored: string[];\n}\n\nexport interface StreamStart {\n ignored: string[];\n provider: string;\n events: AsyncGenerator<SseEvent, void, undefined>;\n}\n\n/** Metadata about a finished streaming turn, reported via `onResult`. */\nexport interface StreamResultInfo {\n costUsd?: number;\n sessionId?: string;\n}\n\nexport interface StreamOptions {\n signal?: AbortSignal;\n /** Called once when a streamed turn completes successfully. */\n onResult?: (info: StreamResultInfo) => void;\n}\n\ninterface PreparedTurn {\n provider: Provider;\n turn: TurnRequest;\n norm: NormalizedRequest;\n /** Model id to report back (qualified unless it's the default provider's). */\n requestedModel: string;\n ignored: string[];\n /** Cache key the resume came from — set only when resuming a session. */\n resumeKey?: string;\n}\n\n/**\n * Translates Anthropic Messages API requests into turns on whichever\n * signed-in coding harness the model id names — Claude Code by default,\n * `codex:…`, `opencode:…`, `gemini:…` and friends on request.\n */\nexport class YagamiEngine {\n readonly providers: Map<string, Provider>;\n readonly unavailable: Map<string, string>;\n readonly defaultProviderId: string;\n private readonly defaultModel: string | undefined;\n private readonly cache: SessionCache;\n private readonly modelsPromises = new Map<string, Promise<EngineModel[]>>();\n\n constructor(options: EngineOptions = {}) {\n const workDir = options.workDir ?? path.join(os.tmpdir(), \"yagami-workspace\");\n fs.mkdirSync(workDir, { recursive: true });\n this.defaultModel = options.defaultModel;\n this.cache = options.sessionCache ?? new SessionCache();\n\n if (options.providers) {\n this.providers = new Map(options.providers.map((p) => [p.id, p]));\n this.unavailable = new Map();\n } else {\n const config: Record<string, ProviderConfigEntry> = { ...options.providerConfig };\n if (options.claudePath || options.claudeConfigDir) {\n config[\"claude\"] = {\n ...config[\"claude\"],\n ...(options.claudePath ? { path: options.claudePath } : {}),\n ...(options.claudeConfigDir ? { configDir: options.claudeConfigDir } : {}),\n };\n }\n const loaded = loadProviders(config, { workDir, ...(options.appName ? { appName: options.appName } : {}) });\n this.providers = loaded.providers;\n this.unavailable = loaded.unavailable;\n }\n\n const wanted = options.defaultProvider ?? (this.providers.has(\"claude\") ? \"claude\" : [...this.providers.keys()][0]);\n if (!wanted || !this.providers.has(wanted)) {\n const reason = wanted ? this.unavailable.get(wanted) : \"no supported coding-agent CLI was found on this machine\";\n throw new ProviderNotInstalledError(wanted ?? \"(none)\", reason ?? \"not installed\");\n }\n this.defaultProviderId = wanted;\n }\n\n get defaultProvider(): Provider {\n return this.providers.get(this.defaultProviderId)!;\n }\n\n /** Executable of the default provider. */\n get executable(): string {\n return this.defaultProvider.executable;\n }\n\n /** @deprecated Use `executable`. */\n get claudePath(): string {\n return this.executable;\n }\n\n get providerIds(): string[] {\n return [...this.providers.keys()];\n }\n\n /** Route a request's model id to a provider and its native model. */\n resolve(model: string | undefined): { provider: Provider; model?: string } {\n const ref = parseModelRef(model ?? this.defaultModel, this.providers.keys());\n if (ref.providerId && !this.providers.has(ref.providerId)) {\n throw new ApiError(503, \"api_error\", `provider \"${ref.providerId}\" is not available: ${this.unavailable.get(ref.providerId) ?? \"not installed\"}`);\n }\n const provider = this.providers.get(ref.providerId ?? this.defaultProviderId)!;\n return ref.model ? { provider, model: ref.model } : { provider };\n }\n\n /**\n * Models across every available provider. The default provider's ids are\n * listed bare as well as qualified; others only as `provider:model`.\n * Providers whose probe fails are skipped (their error is not cached).\n */\n async listModels(): Promise<EngineModel[]> {\n const out: EngineModel[] = [];\n const entries = await Promise.all(\n [...this.providers.entries()].map(async ([id, provider]) => {\n try {\n return [id, await this.providerModels(id, provider)] as const;\n } catch {\n return [id, []] as const;\n }\n }),\n );\n for (const [id, models] of entries) {\n for (const m of models) {\n if (id === this.defaultProviderId) out.push({ ...m, provider: id });\n out.push({ ...m, id: qualifiedModel(id, m.id), provider: id });\n }\n }\n return out;\n }\n\n private providerModels(id: string, provider: Provider): Promise<EngineModel[]> {\n let promise = this.modelsPromises.get(id);\n if (!promise) {\n promise = provider.listModels().catch((err) => {\n this.modelsPromises.delete(id);\n throw err;\n });\n this.modelsPromises.set(id, promise);\n }\n return promise;\n }\n\n private prepare(req: MessagesRequest, opts: { skipResume?: boolean } = {}): PreparedTurn {\n const norm = normalizeRequest(req);\n const { provider, model } = this.resolve(req.model);\n const caps = provider.capabilities;\n const ignored = [...norm.ignored];\n\n if (req.thinking != null) {\n if (!THINKING_TYPES.has(String(req.thinking.type))) {\n throw new ApiError(400, \"invalid_request_error\", `invalid \\`thinking.type\\`: ${String(req.thinking.type)}`);\n }\n if (!caps.thinking) ignored.push(\"thinking\");\n }\n if (req.effort != null) {\n if (typeof req.effort !== \"string\" || !EFFORT_LEVELS.has(req.effort)) {\n throw new ApiError(400, \"invalid_request_error\", `invalid \\`effort\\`: ${String(req.effort)}`);\n }\n if (!caps.effort) ignored.push(\"effort\");\n }\n\n const last = norm.messages[norm.messages.length - 1]!;\n const lastMedia = last.media ?? [];\n if (lastMedia.some((b) => b.type === \"image\") && !caps.images) {\n throw new ApiError(400, \"invalid_request_error\", `provider \"${provider.id}\" does not accept image blocks`);\n }\n if (lastMedia.some((b) => b.type === \"document\") && !caps.documents) {\n throw new ApiError(400, \"invalid_request_error\", `provider \"${provider.id}\" does not accept document blocks`);\n }\n\n let promptText = norm.lastUserText;\n let resume: string | undefined;\n let resumeKey: string | undefined;\n if (norm.messages.length > 1) {\n const history = norm.messages.slice(0, -1);\n if (caps.resume && !opts.skipResume) {\n resumeKey = prefixKey(norm.system, history, provider.id);\n resume = this.cache.get(resumeKey);\n // Without fork support a resumed session is spent: the mapping must\n // not be reused by a sibling branch, which would corrupt both.\n if (resume && !caps.fork) this.cache.delete(resumeKey);\n }\n if (!resume) {\n // Media in the history can't be replayed as text; only a live cached\n // session (which already holds those blocks) can continue from here.\n if (history.some((m) => m.media && m.media.length > 0)) {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n \"conversation history contains image/document blocks and no cached session matches this prefix; yagami can only replay text history. Continue such conversations against the server that produced them.\",\n );\n }\n promptText = flattenConversation(norm.messages);\n }\n }\n if (norm.prefill) promptText = `${promptText}\\n\\n${prefillDirective(norm.prefill)}`;\n if (norm.system !== undefined && !caps.systemPrompt) {\n promptText = `<system>\\n${norm.system}\\n</system>\\n\\n${promptText}`;\n }\n\n if (norm.serverTools && !caps.serverTools) {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n `provider \"${provider.id}\" cannot run server tools (${norm.serverTools.join(\", \")}). ` +\n `Answering without them would silently drop the lookup you asked for, so the ` +\n `request is refused instead. Use the claude provider, or drop \\`tools\\`.`,\n );\n }\n\n const turn: TurnRequest = {\n prompt: promptText,\n ...(lastMedia.length > 0 ? { media: lastMedia } : {}),\n ...(norm.system !== undefined && caps.systemPrompt ? { system: norm.system } : {}),\n ...(model ? { model } : {}),\n ...(resume ? { resume } : {}),\n ...(req.thinking != null && caps.thinking ? { thinking: req.thinking } : {}),\n ...(typeof req.effort === \"string\" && caps.effort ? { effort: req.effort } : {}),\n ...(norm.serverTools ? { serverTools: norm.serverTools } : {}),\n };\n const requestedModel = model\n ? provider.id === this.defaultProviderId\n ? model\n : qualifiedModel(provider.id, model)\n : provider.id;\n\n return { provider, turn, norm, requestedModel, ignored, ...(resume && resumeKey ? { resumeKey } : {}) };\n }\n\n /**\n * A failed resumed attempt usually means the cached session no longer\n * exists. Drop the stale mapping and re-prepare from scratch — the\n * transcript-replay path. Undefined when falling back is impossible.\n */\n private prepareResumeFallback(req: MessagesRequest, failed: PreparedTurn): PreparedTurn | undefined {\n if (!failed.resumeKey) return undefined;\n this.cache.delete(failed.resumeKey);\n try {\n return this.prepare(req, { skipResume: true });\n } catch {\n return undefined;\n }\n }\n\n private storeSession(prepared: PreparedTurn, continuation: string, sessionId: string | undefined): void {\n const { norm, provider } = prepared;\n // Clients replay prefill + continuation as one assistant message, so the\n // stored prefix must record the full text, not just what we returned.\n const fullText = (norm.prefill ?? \"\") + continuation;\n if (!sessionId || !fullText || !provider.capabilities.resume) return;\n const played = [...norm.messages, { role: \"assistant\" as const, text: fullText }];\n this.cache.set(prefixKey(norm.system, played, provider.id), sessionId);\n }\n\n async complete(req: MessagesRequest): Promise<CompleteResult> {\n const prepared = this.prepare(req);\n try {\n return await this.attemptComplete(prepared);\n } catch (err) {\n const fallback = this.prepareResumeFallback(req, prepared);\n if (!fallback) throw toApiError(err);\n try {\n return await this.attemptComplete(fallback);\n } catch (err2) {\n throw toApiError(err2);\n }\n }\n }\n\n private async attemptComplete(prepared: PreparedTurn): Promise<CompleteResult> {\n const { provider, turn, norm, requestedModel, ignored } = prepared;\n const stripper = norm.prefill ? new PrefillStripper(norm.prefill) : undefined;\n let sessionId: string | undefined;\n let text = \"\";\n let thinking = \"\";\n let done: Extract<TurnEvent, { type: \"done\" }> | undefined;\n\n for await (const ev of provider.run(turn)) {\n if (ev.type === \"session\") sessionId = ev.sessionId;\n else if (ev.type === \"text\") text += stripper ? stripper.push(ev.text) : ev.text;\n else if (ev.type === \"thinking\") thinking += ev.text;\n else done = ev;\n }\n if (stripper) text += stripper.flush();\n if (!done) throw new ProviderError(provider.id, \"turn ended without a result\");\n\n this.storeSession(prepared, text, sessionId);\n\n const content: ContentBlock[] = [\n ...(thinking ? [{ type: \"thinking\", thinking, signature: \"\" }] : []),\n { type: \"text\", text },\n ];\n const response: MessagesResponse = {\n id: `msg_${randomUUID().replace(/-/g, \"\")}`,\n type: \"message\",\n role: \"assistant\",\n model: done.model ?? requestedModel,\n content,\n stop_reason: done.stopReason ?? \"end_turn\",\n stop_sequence: null,\n usage: done.usage,\n };\n return {\n response,\n ...(done.costUsd !== undefined ? { costUsd: done.costUsd } : {}),\n ...(sessionId ? { sessionId } : {}),\n provider: provider.id,\n ignored,\n };\n }\n\n /**\n * Validates synchronously (throws ApiError), then returns a lazy generator\n * of Anthropic-style SSE events.\n */\n stream(req: MessagesRequest, streamOptions: StreamOptions = {}): StreamStart {\n const prepared = this.prepare(req);\n return {\n ignored: prepared.ignored,\n provider: prepared.provider.id,\n events: this.runStream(req, prepared, streamOptions),\n };\n }\n\n private async *runStream(\n req: MessagesRequest,\n prepared: PreparedTurn,\n streamOptions: StreamOptions,\n ): AsyncGenerator<SseEvent, void, undefined> {\n const { signal } = streamOptions;\n let emitted = false;\n try {\n for await (const ev of this.attemptStream(prepared, streamOptions)) {\n emitted = true;\n yield ev;\n }\n return;\n } catch (err) {\n if (signal?.aborted) return;\n // A resumed session that died before emitting anything can be retried\n // transparently against a fresh session (transcript replay).\n const fallback = emitted ? undefined : this.prepareResumeFallback(req, prepared);\n if (!fallback) {\n yield { event: \"error\", data: toApiError(err).toBody() };\n return;\n }\n try {\n yield* this.attemptStream(fallback, streamOptions);\n } catch (err2) {\n if (!signal?.aborted) yield { event: \"error\", data: toApiError(err2).toBody() };\n }\n }\n }\n\n private async *attemptStream(\n prepared: PreparedTurn,\n streamOptions: StreamOptions,\n ): AsyncGenerator<SseEvent, void, undefined> {\n const { provider, turn, norm, requestedModel } = prepared;\n const { signal } = streamOptions;\n const stripper = norm.prefill ? new PrefillStripper(norm.prefill) : undefined;\n const sse = new SseSynthesizer(`msg_${randomUUID().replace(/-/g, \"\")}`, requestedModel);\n let sessionId: string | undefined;\n let text = \"\";\n let done: Extract<TurnEvent, { type: \"done\" }> | undefined;\n // The envelope is sent with the first content event, not up front, so a\n // resumed session that dies before producing anything can still be\n // retried transparently (nothing has reached the client yet).\n let started = false;\n const start = (): SseEvent[] => {\n if (started) return [];\n started = true;\n return sse.start();\n };\n\n for await (const ev of provider.run({ ...turn, ...(signal ? { signal } : {}) })) {\n if (ev.type === \"session\") {\n sessionId = ev.sessionId;\n } else if (ev.type === \"text\") {\n const out = stripper ? stripper.push(ev.text) : ev.text;\n text += out;\n yield* start();\n yield* sse.text(out);\n } else if (ev.type === \"thinking\") {\n yield* start();\n yield* sse.thinking(ev.text);\n } else {\n done = ev;\n }\n }\n if (signal?.aborted) return;\n if (!done) throw new ProviderError(provider.id, \"turn ended without a result\");\n yield* start();\n if (stripper) {\n const held = stripper.flush();\n text += held;\n yield* sse.text(held);\n }\n yield* sse.finish(done.usage, done.stopReason ?? \"end_turn\");\n\n this.storeSession(prepared, text, sessionId);\n streamOptions.onResult?.({\n ...(done.costUsd !== undefined ? { costUsd: done.costUsd } : {}),\n ...(sessionId ? { sessionId } : {}),\n });\n }\n}\n","import type { SseEvent, Usage } from \"./types.js\";\n\n/**\n * Builds a valid Anthropic SSE event sequence from normalized provider\n * events: message_start → content blocks (thinking and/or text, each with\n * start/deltas/stop) → message_delta → message_stop.\n */\nexport class SseSynthesizer {\n private index = -1;\n private open: \"text\" | \"thinking\" | null = null;\n private startedBlocks = 0;\n\n constructor(\n private readonly id: string,\n private readonly model: string,\n ) {}\n\n start(): SseEvent[] {\n return [\n {\n event: \"message_start\",\n data: {\n type: \"message_start\",\n message: {\n id: this.id,\n type: \"message\",\n role: \"assistant\",\n model: this.model,\n content: [],\n stop_reason: null,\n stop_sequence: null,\n usage: { input_tokens: 0, output_tokens: 0 },\n },\n },\n },\n ];\n }\n\n thinking(text: string): SseEvent[] {\n if (text.length === 0) return [];\n const out = this.ensure(\"thinking\");\n out.push({\n event: \"content_block_delta\",\n data: { type: \"content_block_delta\", index: this.index, delta: { type: \"thinking_delta\", thinking: text } },\n });\n return out;\n }\n\n text(text: string): SseEvent[] {\n if (text.length === 0) return [];\n const out = this.ensure(\"text\");\n out.push({\n event: \"content_block_delta\",\n data: { type: \"content_block_delta\", index: this.index, delta: { type: \"text_delta\", text } },\n });\n return out;\n }\n\n finish(usage: Usage, stopReason = \"end_turn\"): SseEvent[] {\n const out: SseEvent[] = [];\n // Always deliver at least one (possibly empty) text block so clients\n // that index content[0] never see a bare message.\n if (this.startedBlocks === 0) out.push(...this.ensure(\"text\"));\n out.push(...this.closeOpen());\n out.push({\n event: \"message_delta\",\n data: {\n type: \"message_delta\",\n delta: { stop_reason: stopReason, stop_sequence: null },\n usage: { input_tokens: usage.input_tokens, output_tokens: usage.output_tokens },\n },\n });\n out.push({ event: \"message_stop\", data: { type: \"message_stop\" } });\n return out;\n }\n\n private ensure(kind: \"text\" | \"thinking\"): SseEvent[] {\n if (this.open === kind) return [];\n const out = this.closeOpen();\n this.index += 1;\n this.startedBlocks += 1;\n this.open = kind;\n out.push({\n event: \"content_block_start\",\n data: {\n type: \"content_block_start\",\n index: this.index,\n content_block: kind === \"text\" ? { type: \"text\", text: \"\" } : { type: \"thinking\", thinking: \"\" },\n },\n });\n return out;\n }\n\n private closeOpen(): SseEvent[] {\n if (this.open === null) return [];\n this.open = null;\n return [{ event: \"content_block_stop\", data: { type: \"content_block_stop\", index: this.index } }];\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { resolveServerTools } from \"./serverTools.js\";\nimport {\n ApiError,\n type MessagesRequest,\n type SystemParam,\n type ContentBlockParam,\n} from \"./types.js\";\n\nexport interface NormalizedMessage {\n role: \"user\" | \"assistant\";\n text: string;\n /** Image/document blocks (user messages only), passed through to the engine. */\n media?: ContentBlockParam[];\n}\n\nexport interface NormalizedRequest {\n system?: string;\n /** The conversation ending in the final user message (prefill removed). */\n messages: NormalizedMessage[];\n lastUserText: string;\n /** Trailing assistant message text: the reply must continue from here. */\n prefill?: string;\n /** Accepted-but-ignored request params, surfaced via a response header. */\n ignored: string[];\n /** Anthropic server tools the caller enabled, as CLI tool names. */\n serverTools?: string[];\n}\n\n/** Params the engine cannot honor but that shouldn't fail the request. */\nconst IGNORABLE_PARAMS = [\n \"max_tokens\",\n \"temperature\",\n \"top_p\",\n \"top_k\",\n \"stop_sequences\",\n \"metadata\",\n \"service_tier\",\n] as const;\n\nexport function extractSystemText(system: SystemParam | undefined): string | undefined {\n if (system == null) return undefined;\n if (typeof system === \"string\") return system.length > 0 ? system : undefined;\n if (!Array.isArray(system)) {\n throw new ApiError(400, \"invalid_request_error\", \"`system` must be a string or an array of text blocks\");\n }\n const parts: string[] = [];\n for (const block of system) {\n if (block?.type !== \"text\" || typeof block.text !== \"string\") {\n throw new ApiError(400, \"invalid_request_error\", \"yagami only supports text blocks in `system`\");\n }\n parts.push(block.text);\n }\n const joined = parts.join(\"\\n\\n\");\n return joined.length > 0 ? joined : undefined;\n}\n\n/** Block types (besides text) accepted in user messages and forwarded raw. */\nconst USER_MEDIA_TYPES: ReadonlySet<string> = new Set([\"image\", \"document\"]);\n\nfunction contentToParts(\n content: string | ContentBlockParam[],\n role: string,\n): { text: string; media: ContentBlockParam[] } {\n if (typeof content === \"string\") return { text: content, media: [] };\n if (!Array.isArray(content)) {\n throw new ApiError(400, \"invalid_request_error\", `message content for role \"${role}\" must be a string or an array of blocks`);\n }\n const parts: string[] = [];\n const media: ContentBlockParam[] = [];\n for (const block of content) {\n if (block?.type === \"text\" && typeof block[\"text\"] === \"string\") {\n parts.push(block[\"text\"] as string);\n } else if (role === \"assistant\" && (block?.type === \"thinking\" || block?.type === \"redacted_thinking\")) {\n // Clients echo thinking blocks back verbatim; they carry nothing the\n // replayed transcript needs, so they are dropped rather than rejected.\n continue;\n } else if (role === \"user\" && USER_MEDIA_TYPES.has(String(block?.type))) {\n if (block[\"source\"] == null || typeof block[\"source\"] !== \"object\") {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n `\"${block.type}\" blocks must carry a \\`source\\` object`,\n );\n }\n media.push(block);\n } else {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n role === \"user\"\n ? `unsupported content block type \"${String(block?.type)}\" (user messages may contain text, image, and document blocks; tool_use/tool_result are not supported)`\n : `assistant messages may only contain \"text\" blocks (got \"${String(block?.type)}\")`,\n );\n }\n }\n return { text: parts.join(\"\\n\"), media };\n}\n\nexport function normalizeRequest(req: MessagesRequest): NormalizedRequest {\n if (req == null || typeof req !== \"object\") {\n throw new ApiError(400, \"invalid_request_error\", \"request body must be a JSON object\");\n }\n const serverTools = resolveServerTools(req.tools, req.tool_choice);\n if (!Array.isArray(req.messages) || req.messages.length === 0) {\n throw new ApiError(400, \"invalid_request_error\", \"`messages` must be a non-empty array\");\n }\n\n let messages: NormalizedMessage[] = req.messages.map((m, i) => {\n if (m?.role !== \"user\" && m?.role !== \"assistant\") {\n throw new ApiError(400, \"invalid_request_error\", `messages[${i}].role must be \"user\" or \"assistant\"`);\n }\n const { text, media } = contentToParts(m.content, m.role);\n return media.length > 0 ? { role: m.role, text, media } : { role: m.role, text };\n });\n\n // A trailing assistant message is prefill: the reply continues from it.\n let prefill: string | undefined;\n if (messages[messages.length - 1]!.role === \"assistant\") {\n prefill = messages[messages.length - 1]!.text;\n messages = messages.slice(0, -1);\n if (prefill.length === 0) {\n throw new ApiError(400, \"invalid_request_error\", \"assistant prefill must contain non-empty text\");\n }\n if (messages.length === 0 || messages[messages.length - 1]!.role !== \"user\") {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n \"assistant prefill must directly follow a user message\",\n );\n }\n }\n\n const last = messages[messages.length - 1]!;\n if (last.role !== \"user\") {\n throw new ApiError(400, \"invalid_request_error\", \"the final message must have role \\\"user\\\"\");\n }\n\n const ignored = IGNORABLE_PARAMS.filter((p) => req[p] != null);\n\n return {\n system: extractSystemText(req.system),\n messages,\n lastUserText: last.text,\n ...(prefill !== undefined ? { prefill } : {}),\n ignored: [...ignored],\n ...(serverTools ? { serverTools } : {}),\n };\n}\n\n/**\n * Instruction appended to the outgoing prompt when the request ends with an\n * assistant prefill. The engine can't literally seed the assistant turn, so\n * the model is told to continue from the prefill text instead.\n */\nexport function prefillDirective(prefill: string): string {\n return [\n \"<assistant-prefill>\",\n prefill,\n \"</assistant-prefill>\",\n \"\",\n \"Your reply has already been started with the exact text inside <assistant-prefill>.\",\n \"Continue seamlessly from where it stops. Output ONLY the continuation — do not\",\n \"repeat any part of the prefill and do not acknowledge these instructions.\",\n ].join(\"\\n\");\n}\n\n/**\n * Removes an accidentally repeated prefill from the front of the reply,\n * incrementally, so it works on stream deltas as well as whole responses.\n * Holds text back only until the \"did the model repeat the prefill?\"\n * question is settled, then passes everything through untouched.\n */\nexport class PrefillStripper {\n private buffer = \"\";\n private settled = false;\n\n constructor(private readonly prefill: string) {}\n\n /** True while text is being held back pending the repeat/no-repeat call. */\n get pending(): boolean {\n return !this.settled && this.buffer.length > 0;\n }\n\n /** Feed a chunk of reply text; returns the text safe to emit now. */\n push(chunk: string): string {\n if (this.settled) return chunk;\n this.buffer += chunk;\n if (this.buffer.length <= this.prefill.length) {\n if (this.prefill.startsWith(this.buffer)) return \"\"; // still ambiguous — hold\n this.settled = true;\n const out = this.buffer;\n this.buffer = \"\";\n return out;\n }\n this.settled = true;\n const out = this.buffer.startsWith(this.prefill)\n ? this.buffer.slice(this.prefill.length)\n : this.buffer;\n this.buffer = \"\";\n return out;\n }\n\n /** Emit whatever is still held once the reply has ended. */\n flush(): string {\n if (this.settled) return \"\";\n this.settled = true;\n // Held text is a prefix of the prefill: a full match is a bare repeat\n // (empty continuation); a partial one is emitted rather than dropped.\n const out = this.buffer === this.prefill ? \"\" : this.buffer;\n this.buffer = \"\";\n return out;\n }\n}\n\n/**\n * Cache key for \"this exact conversation prefix has already been played\n * through a Claude Code session\". Matching a prefix lets the engine resume\n * that session instead of replaying history.\n */\nexport function prefixKey(system: string | undefined, messages: NormalizedMessage[], provider = \"claude\"): string {\n // Scoped per provider: a Claude session id means nothing to Codex. Media\n // identity is folded in as a digest.\n const payload = JSON.stringify([\n provider,\n system ?? \"\",\n messages.map((m) =>\n m.media && m.media.length > 0\n ? [m.role, m.text, createHash(\"sha256\").update(JSON.stringify(m.media)).digest(\"hex\")]\n : [m.role, m.text],\n ),\n ]);\n return createHash(\"sha256\").update(payload).digest(\"hex\");\n}\n\n/**\n * Fallback for histories no cached session matches: render the whole\n * conversation into a single prompt for a fresh session.\n */\nexport function flattenConversation(messages: NormalizedMessage[]): string {\n const history = messages.slice(0, -1);\n const last = messages[messages.length - 1]!;\n const lines = history.map((m) => `${m.role === \"user\" ? \"User\" : \"Assistant\"}: ${m.text}`);\n return [\n \"<conversation-history>\",\n \"This is the conversation so far between the user (User) and you (Assistant):\",\n ...lines,\n \"</conversation-history>\",\n \"\",\n \"Continue that conversation naturally. Respond to the user's latest message:\",\n \"\",\n last.text,\n ].join(\"\\n\");\n}\n","import { ApiError } from \"./types.js\";\n\n/**\n * Anthropic **server tools** — the ones that execute on the provider's side\n * rather than being handed back to the client as `tool_use` blocks.\n *\n * Everything else about yagami stays completions-only: it still never emits a\n * `tool_use` block or asks the caller to run anything. But a caller that says\n * \"you may search the web\" is not asking for a client tool loop, it is asking\n * the engine to go look something up before answering — and the backing CLIs\n * already have exactly those tools. Declining that made yagami unusable for\n * any research-shaped request, which was a gap rather than a design choice.\n *\n * Custom (client-executed) tools remain unsupported, and still fail loudly.\n */\n\n/** Claude Code's name for each Anthropic server tool type. */\nconst SERVER_TOOLS: Record<string, string> = {\n web_search: \"WebSearch\",\n web_fetch: \"WebFetch\",\n};\n\n/** Tool `type` strings are versioned (`web_search_20260209`); the prefix is the identity. */\nexport function serverToolFor(type: unknown): string | undefined {\n if (typeof type !== \"string\") return undefined;\n for (const [prefix, tool] of Object.entries(SERVER_TOOLS)) {\n if (type === prefix || type.startsWith(`${prefix}_`)) return tool;\n }\n return undefined;\n}\n\n/**\n * Resolve a request's `tools` array to the CLI tool names to enable.\n *\n * Returns `undefined` when no tools were requested. Throws on custom tools,\n * which genuinely cannot work here — there is no round trip to run them on.\n */\nexport function resolveServerTools(tools: unknown, toolChoice?: unknown): string[] | undefined {\n if (tools == null) {\n if (toolChoice != null) {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n \"`tool_choice` was given without `tools`.\",\n );\n }\n return undefined;\n }\n if (!Array.isArray(tools)) {\n throw new ApiError(400, \"invalid_request_error\", \"`tools` must be an array\");\n }\n if (tools.length === 0) return undefined;\n\n const resolved = new Set<string>();\n for (const tool of tools) {\n const entry = tool as { type?: unknown; name?: unknown };\n const mapped = serverToolFor(entry?.type);\n if (!mapped) {\n const label =\n typeof entry?.name === \"string\"\n ? `\"${entry.name}\"`\n : `type \"${String(entry?.type)}\"`;\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n `yagami supports Anthropic server tools (${Object.keys(SERVER_TOOLS).join(\", \")}) ` +\n `but not custom tools: ${label} would have to be executed by you, and this endpoint ` +\n `never emits tool_use blocks. Drop it, or ask for the result as text/JSON instead.`,\n );\n }\n resolved.add(mapped);\n }\n\n // `tool_choice` picks between client tools; with server tools there is\n // nothing to force, so anything but `auto`/`none` is meaningless here.\n const choice = (toolChoice as { type?: unknown } | undefined)?.type;\n if (choice != null && choice !== \"auto\" && choice !== \"none\") {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n `\\`tool_choice.type\\` must be \"auto\" or \"none\" with server tools (got \"${String(choice)}\"): ` +\n `server tools run on the engine's side and cannot be forced.`,\n );\n }\n if (choice === \"none\") return undefined;\n\n return [...resolved];\n}\n","/**\n * The engine-relevant slice of the host's yagami config\n * (~/.config/yagami/config.json + YAGAMI_* env) — what library mode reads so\n * an embedded `Yagami` client automatically matches the `yagami` binary on\n * the same machine: same providers, same paths, same defaults. Server-only\n * fields (host, port, apiKeys) are ignored here on purpose.\n */\n\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ProviderConfigEntry } from \"./providers/registry.js\";\n\nexport function yagamiConfigDir(): string {\n return process.env[\"YAGAMI_CONFIG_DIR\"] ?? path.join(os.homedir(), \".config\", \"yagami\");\n}\n\n/** Engine options derivable from the host machine's yagami config. */\nexport interface HostEngineConfig {\n defaultProvider?: string;\n defaultModel?: string;\n providerConfig?: Record<string, ProviderConfigEntry>;\n claudePath?: string;\n claudeConfigDir?: string;\n}\n\nexport function loadHostEngineConfig(): HostEngineConfig {\n let file: Record<string, unknown> = {};\n try {\n file = JSON.parse(fs.readFileSync(path.join(yagamiConfigDir(), \"config.json\"), \"utf8\")) as Record<string, unknown>;\n } catch {\n // no config file — auto-detection alone is fine\n }\n const env = process.env;\n const defaultProvider = env[\"YAGAMI_PROVIDER\"] ?? (typeof file[\"defaultProvider\"] === \"string\" ? file[\"defaultProvider\"] : undefined);\n const defaultModel = env[\"YAGAMI_DEFAULT_MODEL\"] ?? (typeof file[\"defaultModel\"] === \"string\" ? file[\"defaultModel\"] : undefined);\n const claudePath = env[\"YAGAMI_CLAUDE_PATH\"] ?? (typeof file[\"claudePath\"] === \"string\" ? file[\"claudePath\"] : undefined);\n const claudeConfigDir = typeof file[\"claudeConfigDir\"] === \"string\" ? file[\"claudeConfigDir\"] : undefined;\n const providers = file[\"providers\"];\n return {\n ...(defaultProvider ? { defaultProvider } : {}),\n ...(defaultModel ? { defaultModel } : {}),\n ...(providers != null && typeof providers === \"object\" && !Array.isArray(providers)\n ? { providerConfig: providers as Record<string, ProviderConfigEntry> }\n : {}),\n ...(claudePath ? { claudePath } : {}),\n ...(claudeConfigDir ? { claudeConfigDir } : {}),\n };\n}\n","/**\n * OpenAI Chat Completions dialect: translation to and from the Anthropic\n * Messages shapes the engine speaks. Pure functions — used by both the HTTP\n * server (`POST /v1/chat/completions`) and the library client\n * (`yagami.chat.completions.create`).\n */\n\nimport { ApiError, type ContentBlockParam, type MessagesRequest, type MessagesResponse, type SseEvent, type Usage } from \"./types.js\";\nimport type { EngineModel } from \"./models.js\";\n\nexport interface ChatMessageParam {\n role: string;\n content?: string | null | Array<{ type: string; [key: string]: unknown }>;\n [key: string]: unknown;\n}\n\nexport interface ChatCompletionsRequest {\n model?: string;\n messages: ChatMessageParam[];\n stream?: boolean;\n stream_options?: { include_usage?: boolean };\n max_tokens?: number;\n max_completion_tokens?: number;\n temperature?: number;\n top_p?: number;\n stop?: string | string[];\n n?: number;\n reasoning_effort?: string;\n tools?: unknown;\n tool_choice?: unknown;\n functions?: unknown;\n function_call?: unknown;\n [key: string]: unknown;\n}\n\nexport interface ChatCompletionChoice {\n index: number;\n message: {\n role: \"assistant\";\n content: string;\n /** Thinking output (DeepSeek-style extension; no standard OpenAI field exists). */\n reasoning_content?: string;\n refusal: null;\n };\n finish_reason: string;\n logprobs: null;\n}\n\nexport interface ChatCompletion {\n id: string;\n object: \"chat.completion\";\n created: number;\n model: string;\n choices: ChatCompletionChoice[];\n usage: OpenAiUsage;\n}\n\nexport interface OpenAiUsage {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n}\n\nexport interface ChatCompletionChunk {\n id: string;\n object: \"chat.completion.chunk\";\n created: number;\n model: string;\n choices: Array<{\n index: number;\n delta: { role?: \"assistant\"; content?: string; reasoning_content?: string };\n finish_reason: string | null;\n }>;\n usage?: OpenAiUsage;\n}\n\nexport interface TranslatedChatRequest {\n req: MessagesRequest;\n /** OpenAI params yagami accepted but cannot honor (adds to x-yagami-ignored). */\n extraIgnored: string[];\n /** `stream_options.include_usage` — emit the trailing usage chunk. */\n includeUsage: boolean;\n}\n\n/** OpenAI-only params that are accepted and reported as ignored, never honored. */\nconst IGNORED_OPENAI_PARAMS = [\n \"presence_penalty\",\n \"frequency_penalty\",\n \"logit_bias\",\n \"logprobs\",\n \"top_logprobs\",\n \"seed\",\n \"user\",\n \"response_format\",\n \"prediction\",\n \"modalities\",\n \"audio\",\n \"store\",\n \"parallel_tool_calls\",\n \"web_search_options\",\n] as const;\n\nconst EFFORT_MAP: Record<string, string> = {\n minimal: \"low\",\n low: \"low\",\n medium: \"medium\",\n high: \"high\",\n xhigh: \"xhigh\",\n max: \"max\",\n};\n\n/** `data:image/png;base64,...` → Anthropic image source. */\nfunction imagePartToBlock(part: { [key: string]: unknown }): ContentBlockParam {\n const url = (part[\"image_url\"] as { url?: unknown } | undefined)?.[\"url\"];\n if (typeof url !== \"string\" || url.length === 0) {\n throw new ApiError(400, \"invalid_request_error\", \"`image_url` parts must carry an `image_url.url` string\");\n }\n const dataUrl = /^data:([^;,]+);base64,(.+)$/s.exec(url);\n if (dataUrl) {\n return { type: \"image\", source: { type: \"base64\", media_type: dataUrl[1], data: dataUrl[2] } };\n }\n if (/^https?:\\/\\//.test(url)) {\n return { type: \"image\", source: { type: \"url\", url } };\n }\n throw new ApiError(400, \"invalid_request_error\", \"`image_url.url` must be a data: URL or an http(s) URL\");\n}\n\nfunction partsToContent(\n parts: Array<{ type: string; [key: string]: unknown }>,\n role: string,\n): string | ContentBlockParam[] {\n const blocks: ContentBlockParam[] = [];\n for (const part of parts) {\n if (part?.type === \"text\" && typeof part[\"text\"] === \"string\") {\n blocks.push({ type: \"text\", text: part[\"text\"] });\n } else if (part?.type === \"image_url\" && role === \"user\") {\n blocks.push(imagePartToBlock(part));\n } else {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n `unsupported content part type \"${String(part?.type)}\" for role \"${role}\" (yagami supports \"text\", plus \"image_url\" in user messages)`,\n );\n }\n }\n return blocks.every((b) => b.type === \"text\") ? blocks.map((b) => b[\"text\"] as string).join(\"\\n\") : blocks;\n}\n\nfunction messageText(content: ChatMessageParam[\"content\"], role: string): string {\n if (content == null) return \"\";\n if (typeof content === \"string\") return content;\n const flattened = partsToContent(content, role);\n if (typeof flattened !== \"string\") {\n throw new ApiError(400, \"invalid_request_error\", `\"${role}\" messages may only contain text parts`);\n }\n return flattened;\n}\n\n/**\n * Translate an OpenAI Chat Completions request into the Anthropic Messages\n * request the engine runs. Function calling is rejected — nothing here ever\n * hands a tool call back to the caller. (Anthropic server tools, which run\n * inside the engine, are available on the Anthropic dialect.) Knobs no CLI\n * engine exposes are collected into `extraIgnored` instead of failing.\n */\nexport function chatToMessagesRequest(body: ChatCompletionsRequest): TranslatedChatRequest {\n if (body == null || typeof body !== \"object\") {\n throw new ApiError(400, \"invalid_request_error\", \"request body must be a JSON object\");\n }\n if (body.tools != null || body.tool_choice != null || body.functions != null || body.function_call != null) {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n \"yagami does not support OpenAI function calling: the backing engine never emits tool calls for you to execute. Anthropic **server** tools (web_search, web_fetch) do run — request them through the Anthropic dialect at /v1/messages.\",\n );\n }\n if (body.n != null && body.n !== 1) {\n throw new ApiError(400, \"invalid_request_error\", \"`n` must be 1 (yagami produces a single completion)\");\n }\n if (!Array.isArray(body.messages) || body.messages.length === 0) {\n throw new ApiError(400, \"invalid_request_error\", \"`messages` must be a non-empty array\");\n }\n\n const systemParts: string[] = [];\n const messages: MessagesRequest[\"messages\"] = [];\n for (const [i, m] of body.messages.entries()) {\n const role = m?.role;\n if (role === \"system\" || role === \"developer\") {\n systemParts.push(messageText(m.content, role));\n } else if (role === \"user\") {\n messages.push({ role: \"user\", content: Array.isArray(m.content) ? partsToContent(m.content, \"user\") : (m.content ?? \"\") });\n } else if (role === \"assistant\") {\n messages.push({ role: \"assistant\", content: messageText(m.content, \"assistant\") });\n } else if (role === \"tool\" || role === \"function\") {\n throw new ApiError(400, \"invalid_request_error\", \"yagami does not support tool/function messages (tool calling is disabled by design)\");\n } else {\n throw new ApiError(400, \"invalid_request_error\", `messages[${i}].role must be \"system\", \"developer\", \"user\", or \"assistant\"`);\n }\n }\n\n const extraIgnored = IGNORED_OPENAI_PARAMS.filter((p) => body[p] != null).map(String);\n\n let effort: string | undefined;\n if (body.reasoning_effort != null) {\n effort = EFFORT_MAP[String(body.reasoning_effort)];\n if (!effort) extraIgnored.push(\"reasoning_effort\");\n }\n\n const maxTokens = body.max_completion_tokens ?? body.max_tokens;\n const system = systemParts.filter((s) => s.length > 0).join(\"\\n\\n\");\n const req: MessagesRequest = {\n ...(body.model !== undefined ? { model: body.model } : {}),\n messages,\n ...(system.length > 0 ? { system } : {}),\n ...(maxTokens !== undefined ? { max_tokens: maxTokens } : {}),\n ...(body.temperature !== undefined ? { temperature: body.temperature } : {}),\n ...(body.top_p !== undefined ? { top_p: body.top_p } : {}),\n ...(body.stop != null ? { stop_sequences: Array.isArray(body.stop) ? body.stop : [body.stop] } : {}),\n ...(body.metadata != null ? { metadata: body.metadata as Record<string, unknown> } : {}),\n ...(body.service_tier != null ? { service_tier: String(body.service_tier) } : {}),\n ...(effort ? { effort } : {}),\n ...(body.stream === true ? { stream: true } : {}),\n };\n\n return { req, extraIgnored, includeUsage: body.stream_options?.include_usage === true };\n}\n\nfunction finishReason(stopReason: string | null): string {\n return stopReason === \"max_tokens\" ? \"length\" : \"stop\";\n}\n\nexport function toOpenAiUsage(usage: Usage): OpenAiUsage {\n return {\n prompt_tokens: usage.input_tokens,\n completion_tokens: usage.output_tokens,\n total_tokens: usage.input_tokens + usage.output_tokens,\n };\n}\n\n/** Anthropic Messages response → OpenAI chat.completion. */\nexport function toChatCompletion(resp: MessagesResponse): ChatCompletion {\n const text = resp.content.filter((b) => b.type === \"text\").map((b) => String(b[\"text\"] ?? \"\")).join(\"\");\n const thinking = resp.content.filter((b) => b.type === \"thinking\").map((b) => String(b[\"thinking\"] ?? \"\")).join(\"\");\n return {\n id: resp.id.replace(/^msg_/, \"chatcmpl_\"),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model: resp.model,\n choices: [\n {\n index: 0,\n message: { role: \"assistant\", content: text, ...(thinking ? { reasoning_content: thinking } : {}), refusal: null },\n finish_reason: finishReason(resp.stop_reason),\n logprobs: null,\n },\n ],\n usage: toOpenAiUsage(resp.usage),\n };\n}\n\n/** OpenAI-shaped error body (the OpenAI dialect's counterpart of ApiError.toBody). */\nexport function openAiErrorBody(err: ApiError): { error: { message: string; type: string; param: null; code: null } } {\n return { error: { message: err.message, type: err.type, param: null, code: null } };\n}\n\n/**\n * Re-emits an Anthropic SSE event sequence as OpenAI chat.completion.chunk\n * objects. Feed every engine event through `push`; the caller appends the\n * `[DONE]` sentinel (HTTP mode) unless `errored`.\n */\nexport class ChatChunkTranslator {\n private id = \"chatcmpl_stream\";\n private model = \"\";\n private created = Math.floor(Date.now() / 1000);\n private stopReason: string | null = null;\n private usage: Usage = { input_tokens: 0, output_tokens: 0 };\n /** Set when the engine reported an error mid-stream (no [DONE] after). */\n errored = false;\n\n constructor(private readonly includeUsage: boolean) {}\n\n private chunk(delta: ChatCompletionChunk[\"choices\"][number][\"delta\"], finish: string | null = null): ChatCompletionChunk {\n return {\n id: this.id,\n object: \"chat.completion.chunk\",\n created: this.created,\n model: this.model,\n choices: [{ index: 0, delta, finish_reason: finish }],\n };\n }\n\n /** Translate one engine SSE event into zero or more OpenAI chunk payloads. */\n push(ev: SseEvent): unknown[] {\n const data = ev.data as { [key: string]: unknown };\n switch (ev.event) {\n case \"message_start\": {\n const message = data[\"message\"] as { id?: string; model?: string } | undefined;\n if (message?.id) this.id = message.id.replace(/^msg_/, \"chatcmpl_\");\n if (message?.model) this.model = message.model;\n return [this.chunk({ role: \"assistant\", content: \"\" })];\n }\n case \"content_block_delta\": {\n const delta = data[\"delta\"] as { type?: string; text?: string; thinking?: string } | undefined;\n if (delta?.type === \"text_delta\" && delta.text) return [this.chunk({ content: delta.text })];\n if (delta?.type === \"thinking_delta\" && delta.thinking) return [this.chunk({ reasoning_content: delta.thinking })];\n return [];\n }\n case \"message_delta\": {\n const delta = data[\"delta\"] as { stop_reason?: string } | undefined;\n if (delta?.stop_reason) this.stopReason = delta.stop_reason;\n const usage = data[\"usage\"] as Usage | undefined;\n if (usage) this.usage = usage;\n return [];\n }\n case \"message_stop\": {\n const out: unknown[] = [this.chunk({}, finishReason(this.stopReason))];\n if (this.includeUsage) {\n out.push({\n id: this.id,\n object: \"chat.completion.chunk\",\n created: this.created,\n model: this.model,\n choices: [],\n usage: toOpenAiUsage(this.usage),\n });\n }\n return out;\n }\n case \"error\": {\n this.errored = true;\n const error = data[\"error\"] as { type?: string; message?: string } | undefined;\n return [{ error: { message: error?.message ?? \"stream error\", type: error?.type ?? \"api_error\", param: null, code: null } }];\n }\n default:\n return [];\n }\n }\n}\n\n/**\n * Model list body served by GET /v1/models: Anthropic fields and OpenAI\n * fields on the same objects, so both SDKs' `models.list()` parse it.\n */\nexport function modelListBody(models: EngineModel[]): {\n object: \"list\";\n data: Array<Record<string, unknown>>;\n has_more: false;\n first_id?: string;\n last_id?: string;\n} {\n const created = Math.floor(Date.now() / 1000);\n return {\n object: \"list\",\n data: models.map((m) => ({ type: \"model\", object: \"model\", created, owned_by: \"yagami\", ...m })),\n has_more: false,\n ...(models[0] ? { first_id: models[0].id } : {}),\n ...(models.length > 0 ? { last_id: models[models.length - 1]!.id } : {}),\n };\n}\n"],"mappings":"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","names":["spawnSync","fs","os","path","spawnSync","spawnSync","fs","os","path","spawnSync","spawn","spawnSync","fs","os","path","readline","spawn","readline","spawn","signal","spawn","readline","spawn","spawn","spawnSync","path","fs","path","fs","os","path","out","signal","fs","os","path"]}
|