@justin06lee/yagami 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/dist/chunk-ASS6MJ7C.js +1821 -0
- package/dist/chunk-ASS6MJ7C.js.map +1 -0
- package/dist/chunk-M5UHR273.js +317 -0
- package/dist/chunk-M5UHR273.js.map +1 -0
- package/dist/cli.js +307 -0
- package/dist/cli.js.map +1 -0
- package/dist/engine-pmCK3S7z.d.ts +381 -0
- package/dist/index.d.ts +328 -0
- package/dist/index.js +259 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +85 -0
- package/dist/server.js +36 -0
- package/dist/server.js.map +1 -0
- package/package.json +78 -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/providers/queue.ts","../src/core/providers/claude.ts","../src/core/providers/codex.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"],"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\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 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 PermissionDecision = \"allow\" | \"allow_always\" | \"deny\" | \"deny_always\";\n\n/** A harness asking the host whether a tool may run. */\nexport interface PermissionRequest {\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 PermissionHandler {\n decide(req: PermissionRequest, signal?: AbortSignal): Promise<PermissionDecision>;\n}\n\nexport type AgentEvent =\n | { type: \"session\"; sessionId: 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: PermissionRequest; decision: PermissionDecision }\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 AgentSessionOptions {\n /** Project directory the agent works in. */\n cwd: string;\n model?: string;\n /** Provider session id to continue. */\n resume?: 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: PermissionHandler;\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\n/** One live conversation with a harness: send turns, get normalized events. */\nexport interface AgentSession {\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 openSession(options: AgentSessionOptions): AgentSession;\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.4.1\";\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 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 type { EngineModel } from \"../models.js\";\nimport type { Provider, ProviderCapabilities, TurnEvent, TurnRequest } from \"../provider.js\";\nimport type { ContentBlockParam, Usage } from \"../types.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}\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}\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 Provider {\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 };\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\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 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 sessionUpdate: (n) => {\n handlers.onUpdate?.(n);\n },\n }),\n stream,\n );\n let settled = false;\n child.on(\"error\", (err) => {\n if (settled) return;\n settled = true;\n reject(classifyProviderFailure(this.id, this.loginCommand, err));\n });\n child.on(\"exit\", (code) => {\n if (settled) return;\n settled = true;\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: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },\n })\n .then((init) => {\n if (settled) return;\n settled = true;\n resolve({\n agent,\n init,\n setHandlers: (h) => {\n handlers = h;\n },\n close: () => {\n child.kill(\"SIGTERM\");\n },\n });\n })\n .catch((err) => {\n if (settled) return;\n settled = true;\n child.kill(\"SIGTERM\");\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 };\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\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 req.signal?.addEventListener(\"abort\", onAbort, { once: true });\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 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 async listModels(): Promise<EngineModel[]> {\n const conn = await this.connectImpl(this.workDir);\n try {\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 return flattenSelectOptions(option).map((o) => ({\n id: o.value,\n display_name: o.name,\n ...(o.description ? { description: o.description } : {}),\n }));\n } finally {\n conn.close();\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\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","/**\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\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 this.ended = true;\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\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 };\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.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 }));\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 { Provider, ProviderCapabilities, TurnEvent, TurnRequest } from \"../provider.js\";\nimport type { ContentBlockParam, Usage } from \"../types.js\";\nimport { spawnJsonl } from \"./jsonl.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 Provider {\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 };\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 /** 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 child.kill(\"SIGTERM\");\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 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 }));\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 } from \"node:child_process\";\nimport * as readline from \"node:readline\";\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.\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 child.kill(\"SIGTERM\");\n queue.end();\n };\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"error\", (err) => queue.fail(err));\n child.on(\"close\", (code) => {\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 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 };\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 {\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}\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 if (req.tools != null || req.tool_choice != null) {\n throw new ApiError(\n 400,\n \"invalid_request_error\",\n \"yagami does not support `tools`/`tool_choice`: the backing engine runs as a pure completions endpoint and never executes or emits tool calls.\",\n );\n }\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 };\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"],"mappings":"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","names":["fs","os","path","spawnSync","fs","os","path","spawnSync","spawn","spawnSync","fs","os","path","readline","spawn","readline","spawn","spawn","spawnSync","path","fs","path","fs","os","path","out"]}
|