@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
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { Command } from \"commander\";\nimport { YagamiEngine } from \"./core/engine.js\";\nimport { ClaudeProvider } from \"./core/providers/claude.js\";\nimport { createProvider, detectProviders } from \"./core/providers/registry.js\";\nimport { startYagami } from \"./server.js\";\nimport {\n clearServerState,\n configFilePath,\n generateApiKey,\n isProcessAlive,\n loadConfig,\n loadFileConfig,\n logFilePath,\n maskKey,\n readServerState,\n saveConfig,\n sessionCachePath,\n writeServerState,\n} from \"./server/config.js\";\nimport { VERSION } from \"./version.js\";\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst program = new Command();\n\nprogram\n .name(\"yagami\")\n .description(\"Anthropic-compatible API served by your signed-in Claude Code CLI\")\n .version(VERSION);\n\ninterface StartFlags {\n port?: string;\n host?: string;\n claude?: string;\n provider?: string;\n cors?: boolean;\n daemon?: boolean;\n log?: string;\n}\n\nprogram\n .command(\"start\", { isDefault: true })\n .description(\"start the yagami server\")\n .option(\"-p, --port <port>\", \"port to listen on\")\n .option(\"-H, --host <host>\", \"host to bind (default 127.0.0.1)\")\n .option(\"--claude <path>\", \"path to the claude executable\")\n .option(\"--provider <id>\", \"default provider for bare model ids (claude, codex, opencode, gemini, …)\")\n .option(\"--cors\", \"enable permissive CORS (for browser clients)\")\n .option(\"--daemon\", \"run in the background (managed with `yagami stop`/`yagami status`)\")\n .option(\"--log <file>\", \"log file for --daemon mode (default ~/.config/yagami/yagami.log)\")\n .action(async (opts: StartFlags) => {\n // First run: generate a key automatically so the endpoint is never open.\n const fileConfig = loadFileConfig();\n let freshKey: string | undefined;\n if (fileConfig.apiKeys.length === 0 && !process.env[\"YAGAMI_API_KEY\"]) {\n freshKey = generateApiKey();\n fileConfig.apiKeys.push(freshKey);\n saveConfig(fileConfig);\n }\n\n if (opts.daemon) {\n await startDaemon(opts, freshKey);\n return;\n }\n\n try {\n const running = await startYagami({\n port: opts.port !== undefined ? Number(opts.port) : undefined,\n host: opts.host,\n claudePath: opts.claude,\n defaultProvider: opts.provider,\n cors: opts.cors,\n });\n\n writeServerState({\n pid: process.pid,\n host: running.config.host,\n port: running.config.port,\n url: running.url,\n startedAt: new Date().toISOString(),\n version: VERSION,\n ...(process.env[\"YAGAMI_LOG_FILE\"] ? { log: process.env[\"YAGAMI_LOG_FILE\"] } : {}),\n });\n const shutdown = () => {\n running.sessionCache.persistNow();\n clearServerState(process.pid);\n void running.close().finally(() => process.exit(0));\n // Don't hang on a stuck in-flight response.\n setTimeout(() => process.exit(0), 3000).unref?.();\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n const engine = running.engine;\n const version = await engine.defaultProvider.version();\n const others = engine.providerIds.filter((id) => id !== engine.defaultProviderId);\n console.log(`yagami v${VERSION}`);\n console.log(` listening ${running.url}`);\n console.log(` provider ${engine.defaultProviderId} — ${engine.executable}${version ? ` (${version})` : \"\"}`);\n console.log(\n ` also ${others.length > 0 ? `${others.join(\", \")} (use model \"<provider>:<model>\")` : \"no other harness CLIs found — see `yagami doctor`\"}`,\n );\n console.log(` config ${configFilePath()}`);\n if (freshKey) {\n console.log(` api key ${freshKey}`);\n console.log(\" (newly generated and saved — copy it now, it is shown in full only once)\");\n } else {\n console.log(` api keys ${running.config.apiKeys.map(maskKey).join(\", \")}`);\n }\n if (![\"127.0.0.1\", \"localhost\", \"::1\"].includes(running.config.host)) {\n console.log(\n ` ⚠ bound to ${running.config.host} — reachable beyond this machine. Only do this on a network you trust.`,\n );\n }\n console.log(\"\\nPoint any Anthropic SDK at it:\");\n console.log(` baseURL: \"${running.url}\" apiKey: <your yagami key>`);\n } catch (err) {\n console.error(`yagami: ${err instanceof Error ? err.message : String(err)}`);\n process.exitCode = 1;\n }\n });\n\nasync function startDaemon(opts: StartFlags, freshKey: string | undefined): Promise<void> {\n const existing = readServerState();\n if (existing && isProcessAlive(existing.pid)) {\n console.error(`yagami is already running (pid ${existing.pid}, ${existing.url}) — \\`yagami stop\\` first`);\n process.exitCode = 1;\n return;\n }\n clearServerState();\n\n const logPath = opts.log ? path.resolve(opts.log) : logFilePath();\n fs.mkdirSync(path.dirname(logPath), { recursive: true });\n const fd = fs.openSync(logPath, \"a\");\n const args = [process.argv[1]!, \"start\"];\n if (opts.port !== undefined) args.push(\"-p\", opts.port);\n if (opts.host !== undefined) args.push(\"-H\", opts.host);\n if (opts.claude !== undefined) args.push(\"--claude\", opts.claude);\n if (opts.provider !== undefined) args.push(\"--provider\", opts.provider);\n if (opts.cors) args.push(\"--cors\");\n\n const child = spawn(process.execPath, args, {\n detached: true,\n stdio: [\"ignore\", fd, fd],\n env: { ...process.env, YAGAMI_LOG_FILE: logPath },\n });\n fs.closeSync(fd);\n let exitCode: number | null | undefined;\n child.on(\"exit\", (code) => {\n exitCode = code;\n });\n child.unref();\n\n const deadline = Date.now() + 15_000;\n while (Date.now() < deadline && exitCode === undefined) {\n const state = readServerState();\n if (state && state.pid === child.pid) {\n console.log(`yagami v${VERSION} running in the background`);\n console.log(` pid ${child.pid}`);\n console.log(` url ${state.url}`);\n console.log(` log ${logPath}`);\n if (freshKey) {\n console.log(` key ${freshKey}`);\n console.log(\" (newly generated and saved — copy it now, it is shown in full only once)\");\n }\n return;\n }\n await sleep(200);\n }\n console.error(\n exitCode !== undefined\n ? `yagami exited immediately (code ${exitCode}) — see ${logPath}`\n : `yagami did not report ready within 15s — see ${logPath}`,\n );\n process.exitCode = 1;\n}\n\nprogram\n .command(\"stop\")\n .description(\"stop a running yagami server\")\n .action(async () => {\n const state = readServerState();\n if (!state || !isProcessAlive(state.pid)) {\n if (state) clearServerState();\n console.log(\"yagami is not running\");\n return;\n }\n process.kill(state.pid, \"SIGTERM\");\n const deadline = Date.now() + 5_000;\n while (Date.now() < deadline) {\n if (!isProcessAlive(state.pid)) {\n clearServerState();\n console.log(`stopped yagami (pid ${state.pid})`);\n return;\n }\n await sleep(100);\n }\n console.error(`yagami (pid ${state.pid}) did not exit within 5s`);\n process.exitCode = 1;\n });\n\nprogram\n .command(\"status\")\n .description(\"show whether yagami is running, plus request/cost totals\")\n .action(async () => {\n const state = readServerState();\n if (!state || !isProcessAlive(state.pid)) {\n if (state) clearServerState();\n console.log(\"yagami is not running\");\n process.exitCode = 1;\n return;\n }\n console.log(`yagami running (pid ${state.pid})`);\n console.log(` url ${state.url}`);\n console.log(` since ${state.startedAt}`);\n if (state.log) console.log(` log ${state.log}`);\n try {\n const res = await fetch(`${state.url}/healthz`, { signal: AbortSignal.timeout(3000) });\n const body = (await res.json()) as {\n version?: string;\n claude?: string;\n requests?: number;\n total_cost_usd?: number;\n };\n console.log(` version ${body.version ?? \"?\"}`);\n console.log(` claude ${body.claude ?? \"?\"}`);\n console.log(` requests ${body.requests ?? 0}`);\n console.log(` cost $${(body.total_cost_usd ?? 0).toFixed(4)} (would-be API cost since start)`);\n } catch {\n console.log(` healthz unreachable — process is alive but ${state.url} is not answering`);\n }\n });\n\nprogram\n .command(\"keygen\")\n .description(\"generate an API key and add it to the config\")\n .action(() => {\n const cfg = loadFileConfig();\n const key = generateApiKey();\n cfg.apiKeys.push(key);\n const file = saveConfig(cfg);\n console.log(key);\n console.error(`saved to ${file} (${cfg.apiKeys.length} key${cfg.apiKeys.length === 1 ? \"\" : \"s\"} total)`);\n });\n\nprogram\n .command(\"doctor\")\n .description(\"check which coding-agent CLIs yagami can drive and whether they work\")\n .option(\"--live\", \"send one real (tiny) completion through the default provider\")\n .option(\"--provider <id>\", \"provider to use for --live (default: config/claude)\")\n .action(async (opts: { live?: boolean; provider?: string }) => {\n let failed = false;\n const cfg = loadConfig();\n const providerConfig = { ...cfg.providers };\n if (cfg.claudePath || cfg.claudeConfigDir) {\n providerConfig[\"claude\"] = {\n ...providerConfig[\"claude\"],\n ...(cfg.claudePath ? { path: cfg.claudePath } : {}),\n ...(cfg.claudeConfigDir ? { configDir: cfg.claudeConfigDir } : {}),\n };\n }\n const defaultProvider = opts.provider ?? cfg.defaultProvider ?? \"claude\";\n\n console.log(`node ${process.version}`);\n console.log(`config ${configFilePath()}${fs.existsSync(configFilePath()) ? \"\" : \" (not created yet)\"}`);\n console.log(`api keys ${cfg.apiKeys.length === 0 ? \"none — run `yagami keygen`\" : cfg.apiKeys.map(maskKey).join(\", \")}`);\n console.log(`bind ${cfg.host}:${cfg.port}`);\n console.log(`sessions ${sessionCachePath()}${fs.existsSync(sessionCachePath()) ? \"\" : \" (empty)\"}`);\n const state = readServerState();\n console.log(\n `server ${state && isProcessAlive(state.pid) ? `running (pid ${state.pid}, ${state.url})` : \"not running\"}`,\n );\n\n console.log(\"\\nproviders (model ids route as \\\"<provider>:<model>\\\"; bare ids go to the default)\");\n const detected = detectProviders(providerConfig);\n const installed = detected.filter((d) => d.installed);\n for (const d of detected) {\n const marker = d.id === defaultProvider ? \"*\" : \" \";\n if (!d.installed) {\n if (presetIsNiche(d.id)) continue; // keep the list readable\n console.log(` ${marker} ${d.id.padEnd(11)} not installed — ${d.installHint}`);\n continue;\n }\n let version: string | undefined;\n try {\n version = await createProvider(d.id, providerConfig[d.id] ?? {}, {}).version();\n } catch (err) {\n version = `✗ ${err instanceof Error ? err.message : String(err)}`;\n }\n console.log(` ${marker} ${d.id.padEnd(11)} ${d.path}${version ? ` (${version})` : \"\"}`);\n }\n const hidden = detected.filter((d) => !d.installed && presetIsNiche(d.id)).length;\n if (hidden > 0) console.log(` … ${hidden} more ACP presets not installed (see README for the full list)`);\n if (!installed.some((d) => d.id === defaultProvider)) {\n failed = true;\n console.log(` ✗ default provider \"${defaultProvider}\" is not installed`);\n }\n\n if (installed.some((d) => d.id === \"claude\")) {\n try {\n const claude = createProvider(\"claude\", providerConfig[\"claude\"] ?? {}, {}) as ClaudeProvider;\n const skew = await claude.versionSkew();\n if (skew) {\n console.log(`\\nagent sdk ${skew.sdkVersion} ↔ claude ${skew.binaryVersion} — ${skew.inSync ? \"in sync\" : `⚠ ${skew.note}`}`);\n }\n } catch {\n // skew check is advisory\n }\n }\n\n if (opts.live && !failed) {\n console.log(`\\nlive check: sending one tiny completion through ${defaultProvider}…`);\n try {\n const engine = new YagamiEngine({ providerConfig, defaultProvider, ...(cfg.defaultModel ? { defaultModel: cfg.defaultModel } : {}) });\n const started = Date.now();\n const result = await engine.complete({\n messages: [{ role: \"user\", content: \"Reply with exactly: pong\" }],\n max_tokens: 32,\n });\n const text = result.response.content\n .filter((b) => b.type === \"text\")\n .map((b) => b[\"text\"])\n .join(\"\");\n console.log(` reply ${JSON.stringify(text)}`);\n console.log(` model ${result.response.model}`);\n console.log(` latency ${((Date.now() - started) / 1000).toFixed(1)}s`);\n if (result.costUsd !== undefined) console.log(` cost $${result.costUsd.toFixed(6)}`);\n } catch (err) {\n failed = true;\n console.log(` ✗ ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (failed) process.exitCode = 1;\n });\n\n/** Presets most people won't have; hidden from doctor unless installed. */\nfunction presetIsNiche(id: string): boolean {\n return ![\"claude\", \"codex\", \"opencode\", \"gemini\", \"copilot\", \"cursor\", \"qwen\", \"goose\", \"kimi\"].includes(id);\n}\n\nprogram\n .command(\"models\")\n .description(\"list models across every installed provider (ids are ready to paste into requests)\")\n .option(\"--provider <id>\", \"only this provider\")\n .action(async (opts: { provider?: string }) => {\n const cfg = loadConfig();\n try {\n const engine = new YagamiEngine({\n ...(cfg.providers ? { providerConfig: cfg.providers } : {}),\n ...(cfg.defaultProvider ? { defaultProvider: cfg.defaultProvider } : {}),\n });\n const models = await engine.listModels();\n const byProvider = new Map<string, typeof models>();\n for (const m of models) {\n if (opts.provider && m.provider !== opts.provider) continue;\n if (!m.id.includes(\":\")) continue; // print the qualified form once\n const list = byProvider.get(m.provider ?? \"?\") ?? [];\n list.push(m);\n byProvider.set(m.provider ?? \"?\", list);\n }\n for (const [provider, list] of byProvider) {\n console.log(`${provider}${provider === engine.defaultProviderId ? \" (default — bare ids work too)\" : \"\"}`);\n for (const m of list) {\n console.log(` ${m.id.padEnd(40)} ${m.display_name}${m.resolved_model ? ` → ${m.resolved_model}` : \"\"}`);\n }\n }\n if (byProvider.size === 0) console.log(\"no models reported — run `yagami doctor`\");\n } catch (err) {\n console.error(`yagami: ${err instanceof Error ? err.message : String(err)}`);\n process.exitCode = 1;\n }\n });\n\nawait program.parseAsync(process.argv);\n"],"mappings":"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","names":["resolve"]}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/** A model a provider reports as available. */
|
|
2
|
+
interface EngineModel {
|
|
3
|
+
id: string;
|
|
4
|
+
display_name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
/** Canonical wire id an alias resolves to (e.g. "sonnet" → "claude-sonnet-5"). */
|
|
7
|
+
resolved_model?: string;
|
|
8
|
+
/** Provider that serves this model (set by the engine when aggregating). */
|
|
9
|
+
provider?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Anthropic Messages API shapes (the subset yagami implements) and the error
|
|
14
|
+
* type shared across the engine and the HTTP layer.
|
|
15
|
+
*/
|
|
16
|
+
type ApiErrorType = "invalid_request_error" | "authentication_error" | "permission_error" | "not_found_error" | "rate_limit_error" | "api_error" | "overloaded_error";
|
|
17
|
+
declare class ApiError extends Error {
|
|
18
|
+
readonly status: number;
|
|
19
|
+
readonly type: ApiErrorType;
|
|
20
|
+
constructor(status: number, type: ApiErrorType, message: string);
|
|
21
|
+
toBody(): {
|
|
22
|
+
type: "error";
|
|
23
|
+
error: {
|
|
24
|
+
type: ApiErrorType;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
interface ContentBlockParam {
|
|
30
|
+
type: string;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
interface TextBlockParam extends ContentBlockParam {
|
|
34
|
+
type: "text";
|
|
35
|
+
text: string;
|
|
36
|
+
}
|
|
37
|
+
type SystemParam = string | TextBlockParam[];
|
|
38
|
+
interface MessageParam {
|
|
39
|
+
role: "user" | "assistant";
|
|
40
|
+
content: string | ContentBlockParam[];
|
|
41
|
+
}
|
|
42
|
+
interface ThinkingParam {
|
|
43
|
+
type: "enabled" | "disabled" | "adaptive" | string;
|
|
44
|
+
budget_tokens?: number;
|
|
45
|
+
}
|
|
46
|
+
interface MessagesRequest {
|
|
47
|
+
model?: string;
|
|
48
|
+
messages: MessageParam[];
|
|
49
|
+
system?: SystemParam;
|
|
50
|
+
max_tokens?: number;
|
|
51
|
+
stream?: boolean;
|
|
52
|
+
temperature?: number;
|
|
53
|
+
top_p?: number;
|
|
54
|
+
top_k?: number;
|
|
55
|
+
stop_sequences?: string[];
|
|
56
|
+
metadata?: Record<string, unknown>;
|
|
57
|
+
service_tier?: string;
|
|
58
|
+
thinking?: ThinkingParam;
|
|
59
|
+
tools?: unknown;
|
|
60
|
+
tool_choice?: unknown;
|
|
61
|
+
/** yagami extension: Claude Code reasoning effort for this request. */
|
|
62
|
+
effort?: string;
|
|
63
|
+
[key: string]: unknown;
|
|
64
|
+
}
|
|
65
|
+
interface Usage {
|
|
66
|
+
input_tokens: number;
|
|
67
|
+
output_tokens: number;
|
|
68
|
+
cache_creation_input_tokens?: number;
|
|
69
|
+
cache_read_input_tokens?: number;
|
|
70
|
+
}
|
|
71
|
+
interface ContentBlock {
|
|
72
|
+
type: string;
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
}
|
|
75
|
+
interface MessagesResponse {
|
|
76
|
+
id: string;
|
|
77
|
+
type: "message";
|
|
78
|
+
role: "assistant";
|
|
79
|
+
model: string;
|
|
80
|
+
content: ContentBlock[];
|
|
81
|
+
stop_reason: string | null;
|
|
82
|
+
stop_sequence: string | null;
|
|
83
|
+
usage: Usage;
|
|
84
|
+
}
|
|
85
|
+
/** One server-sent event, pre-serialization. */
|
|
86
|
+
interface SseEvent {
|
|
87
|
+
event: string;
|
|
88
|
+
data: unknown;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** What a provider can natively honor; the engine emulates or rejects the rest. */
|
|
92
|
+
interface ProviderCapabilities {
|
|
93
|
+
/** Can continue a previous session by id (otherwise history is replayed as text). */
|
|
94
|
+
resume: boolean;
|
|
95
|
+
/** Resuming leaves the original session intact (branches are safe). */
|
|
96
|
+
fork: boolean;
|
|
97
|
+
images: boolean;
|
|
98
|
+
documents: boolean;
|
|
99
|
+
systemPrompt: boolean;
|
|
100
|
+
thinking: boolean;
|
|
101
|
+
effort: boolean;
|
|
102
|
+
/** Token-level deltas or whole chunks per message part. */
|
|
103
|
+
streaming: "tokens" | "chunks";
|
|
104
|
+
}
|
|
105
|
+
/** One completion turn, already normalized by the engine. */
|
|
106
|
+
interface TurnRequest {
|
|
107
|
+
/** Full prompt text (history already flattened, prefill directive appended). */
|
|
108
|
+
prompt: string;
|
|
109
|
+
/** Image/document blocks (Anthropic shape) attached to the prompt. */
|
|
110
|
+
media?: ContentBlockParam[];
|
|
111
|
+
system?: string;
|
|
112
|
+
/** Provider-native model id; undefined means the provider's own default. */
|
|
113
|
+
model?: string;
|
|
114
|
+
/** Provider session id to continue. */
|
|
115
|
+
resume?: string;
|
|
116
|
+
thinking?: ThinkingParam;
|
|
117
|
+
effort?: string;
|
|
118
|
+
signal?: AbortSignal;
|
|
119
|
+
}
|
|
120
|
+
type TurnEvent = {
|
|
121
|
+
type: "session";
|
|
122
|
+
sessionId: string;
|
|
123
|
+
} | {
|
|
124
|
+
type: "text";
|
|
125
|
+
text: string;
|
|
126
|
+
} | {
|
|
127
|
+
type: "thinking";
|
|
128
|
+
text: string;
|
|
129
|
+
} | {
|
|
130
|
+
type: "done";
|
|
131
|
+
usage: Usage;
|
|
132
|
+
costUsd?: number;
|
|
133
|
+
model?: string;
|
|
134
|
+
stopReason?: string;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* A coding-agent harness yagami can drive: a signed-in CLI on this machine,
|
|
138
|
+
* wrapped so the engine can run sandboxed completion turns through it.
|
|
139
|
+
*/
|
|
140
|
+
interface Provider {
|
|
141
|
+
readonly id: string;
|
|
142
|
+
readonly label: string;
|
|
143
|
+
/** Resolved path of the CLI binary (for diagnostics). */
|
|
144
|
+
readonly executable: string;
|
|
145
|
+
readonly capabilities: ProviderCapabilities;
|
|
146
|
+
/** Shell command that signs the CLI in, for error messages. */
|
|
147
|
+
readonly loginCommand: string;
|
|
148
|
+
/** Run one sandboxed completion turn. Throws typed errors on failure. */
|
|
149
|
+
run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined>;
|
|
150
|
+
/** Models the CLI reports as available (may spawn a short-lived process). */
|
|
151
|
+
listModels(): Promise<EngineModel[]>;
|
|
152
|
+
/** CLI version string, if it can be determined. */
|
|
153
|
+
version(): Promise<string | undefined>;
|
|
154
|
+
}
|
|
155
|
+
interface ModelRef {
|
|
156
|
+
providerId?: string;
|
|
157
|
+
model?: string;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Split a request's `model` into provider + native model. `"codex:gpt-5"`
|
|
161
|
+
* routes to codex; a bare provider id (`"codex"`) means that provider's
|
|
162
|
+
* default model; anything else is a model for the default provider. The
|
|
163
|
+
* split happens only at the first colon and only when the prefix names a
|
|
164
|
+
* known provider, so ids like `"ollama/llama3:8b"` stay intact.
|
|
165
|
+
*/
|
|
166
|
+
declare function parseModelRef(model: string | undefined, providerIds: Iterable<string>): ModelRef;
|
|
167
|
+
declare function qualifiedModel(providerId: string, model: string): string;
|
|
168
|
+
|
|
169
|
+
type CodexSandboxMode = "read-only" | "workspace-write" | "danger-full-access";
|
|
170
|
+
interface CodexProviderOptions {
|
|
171
|
+
/** Path to the `codex` binary. Auto-resolved when omitted. */
|
|
172
|
+
path?: string;
|
|
173
|
+
/** Working directory for completion turns. */
|
|
174
|
+
workDir?: string;
|
|
175
|
+
/** Sandbox for completion turns (default read-only). */
|
|
176
|
+
sandbox?: CodexSandboxMode;
|
|
177
|
+
env?: Record<string, string>;
|
|
178
|
+
}
|
|
179
|
+
/** OpenAI Codex CLI via `codex exec --json`, signed in with the user's ChatGPT account. */
|
|
180
|
+
declare class CodexProvider implements Provider {
|
|
181
|
+
readonly id = "codex";
|
|
182
|
+
readonly label = "Codex CLI";
|
|
183
|
+
readonly executable: string;
|
|
184
|
+
readonly loginCommand = "codex login";
|
|
185
|
+
readonly capabilities: ProviderCapabilities;
|
|
186
|
+
private readonly workDir;
|
|
187
|
+
private readonly sandbox;
|
|
188
|
+
private readonly env;
|
|
189
|
+
constructor(options?: CodexProviderOptions);
|
|
190
|
+
/** Build the `codex exec` argument list for a turn (exported for tests). */
|
|
191
|
+
buildArgs(req: TurnRequest, imagePaths: string[]): string[];
|
|
192
|
+
run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined>;
|
|
193
|
+
/** Ask the app-server protocol for the model catalog (no tokens spent). */
|
|
194
|
+
listModels(): Promise<EngineModel[]>;
|
|
195
|
+
version(): Promise<string | undefined>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
type ProviderKind = "claude" | "codex" | "acp";
|
|
199
|
+
/** A harness yagami knows how to launch out of the box. */
|
|
200
|
+
interface ProviderPreset {
|
|
201
|
+
id: string;
|
|
202
|
+
label: string;
|
|
203
|
+
kind: ProviderKind;
|
|
204
|
+
command: string;
|
|
205
|
+
args: string[];
|
|
206
|
+
loginCommand: string;
|
|
207
|
+
installHint: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Built-in catalog. Native drivers for Claude Code and Codex; everything
|
|
211
|
+
* else speaks the Agent Client Protocol, with launch commands taken from
|
|
212
|
+
* the ACP registry (cdn.agentclientprotocol.com/registry). Login commands
|
|
213
|
+
* are best-effort hints.
|
|
214
|
+
*/
|
|
215
|
+
declare const PROVIDER_PRESETS: readonly ProviderPreset[];
|
|
216
|
+
/** Per-provider settings from config.json (`providers.<id>`). */
|
|
217
|
+
interface ProviderConfigEntry {
|
|
218
|
+
/** Explicit executable path. */
|
|
219
|
+
path?: string;
|
|
220
|
+
/** Launch command for custom ACP agents (and overrides for presets). */
|
|
221
|
+
command?: string;
|
|
222
|
+
args?: string[];
|
|
223
|
+
env?: Record<string, string>;
|
|
224
|
+
label?: string;
|
|
225
|
+
/** Claude only: CLAUDE_CONFIG_DIR isolation. */
|
|
226
|
+
configDir?: string;
|
|
227
|
+
/** Codex only: sandbox for completion turns. */
|
|
228
|
+
sandbox?: CodexSandboxMode;
|
|
229
|
+
/** ACP only: id of the model config option (default "model"). */
|
|
230
|
+
modelConfigId?: string;
|
|
231
|
+
loginCommand?: string;
|
|
232
|
+
/** Set false to skip this preset even if installed. */
|
|
233
|
+
enabled?: boolean;
|
|
234
|
+
}
|
|
235
|
+
interface ProviderCommonOptions {
|
|
236
|
+
workDir?: string;
|
|
237
|
+
appName?: string;
|
|
238
|
+
}
|
|
239
|
+
declare function presetFor(id: string): ProviderPreset | undefined;
|
|
240
|
+
/** Instantiate one provider by id from a preset and/or config entry. */
|
|
241
|
+
declare function createProvider(id: string, entry?: ProviderConfigEntry, common?: ProviderCommonOptions): Provider;
|
|
242
|
+
interface LoadedProviders {
|
|
243
|
+
providers: Map<string, Provider>;
|
|
244
|
+
/** Providers that couldn't be constructed, with the reason (usually not installed). */
|
|
245
|
+
unavailable: Map<string, string>;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Build every provider that is installed on this machine: all presets plus
|
|
249
|
+
* any custom entries in config. Missing CLIs are recorded, not fatal.
|
|
250
|
+
*/
|
|
251
|
+
declare function loadProviders(config?: Record<string, ProviderConfigEntry>, common?: ProviderCommonOptions): LoadedProviders;
|
|
252
|
+
interface DetectedProvider {
|
|
253
|
+
id: string;
|
|
254
|
+
label: string;
|
|
255
|
+
kind: ProviderKind;
|
|
256
|
+
installed: boolean;
|
|
257
|
+
path?: string;
|
|
258
|
+
loginCommand: string;
|
|
259
|
+
installHint: string;
|
|
260
|
+
}
|
|
261
|
+
/** Which known harnesses exist on this machine (cheap: no processes spawned). */
|
|
262
|
+
declare function detectProviders(config?: Record<string, ProviderConfigEntry>): DetectedProvider[];
|
|
263
|
+
|
|
264
|
+
interface SessionCacheOptions {
|
|
265
|
+
maxEntries?: number;
|
|
266
|
+
/** JSON file to persist the cache across restarts (best-effort). */
|
|
267
|
+
persistPath?: string;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* LRU map from conversation-prefix hash to Claude Code session id.
|
|
271
|
+
* Session transcripts themselves live in ~/.claude; this only remembers
|
|
272
|
+
* which session corresponds to which conversation prefix.
|
|
273
|
+
*/
|
|
274
|
+
declare class SessionCache {
|
|
275
|
+
private readonly map;
|
|
276
|
+
private readonly maxEntries;
|
|
277
|
+
private readonly persistPath;
|
|
278
|
+
private persistTimer;
|
|
279
|
+
constructor(options?: SessionCacheOptions);
|
|
280
|
+
get size(): number;
|
|
281
|
+
get(key: string): string | undefined;
|
|
282
|
+
/** Drop a mapping, e.g. when its session turns out to be gone. */
|
|
283
|
+
delete(key: string): void;
|
|
284
|
+
set(key: string, sessionId: string): void;
|
|
285
|
+
private load;
|
|
286
|
+
private schedulePersist;
|
|
287
|
+
persistNow(): void;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
interface EngineOptions {
|
|
291
|
+
/** Explicit provider instances (library mode). Overrides config-driven loading. */
|
|
292
|
+
providers?: Provider[];
|
|
293
|
+
/** Per-provider settings (`providers.<id>` in config.json). */
|
|
294
|
+
providerConfig?: Record<string, ProviderConfigEntry>;
|
|
295
|
+
/** Provider used for bare model ids (default: claude if installed, else the first available). */
|
|
296
|
+
defaultProvider?: string;
|
|
297
|
+
/** @deprecated Use providerConfig.claude.path. */
|
|
298
|
+
claudePath?: string;
|
|
299
|
+
/** @deprecated Use providerConfig.claude.configDir. */
|
|
300
|
+
claudeConfigDir?: string;
|
|
301
|
+
/** Working directory for completion turns (inert — tools are disabled/sandboxed). */
|
|
302
|
+
workDir?: string;
|
|
303
|
+
/** Model used when a request omits `model` (may be `provider:model`). */
|
|
304
|
+
defaultModel?: string;
|
|
305
|
+
sessionCache?: SessionCache;
|
|
306
|
+
/** Reported to the CLIs as the client application name. */
|
|
307
|
+
appName?: string;
|
|
308
|
+
}
|
|
309
|
+
interface CompleteResult {
|
|
310
|
+
response: MessagesResponse;
|
|
311
|
+
costUsd?: number;
|
|
312
|
+
sessionId?: string;
|
|
313
|
+
provider: string;
|
|
314
|
+
ignored: string[];
|
|
315
|
+
}
|
|
316
|
+
interface StreamStart {
|
|
317
|
+
ignored: string[];
|
|
318
|
+
provider: string;
|
|
319
|
+
events: AsyncGenerator<SseEvent, void, undefined>;
|
|
320
|
+
}
|
|
321
|
+
/** Metadata about a finished streaming turn, reported via `onResult`. */
|
|
322
|
+
interface StreamResultInfo {
|
|
323
|
+
costUsd?: number;
|
|
324
|
+
sessionId?: string;
|
|
325
|
+
}
|
|
326
|
+
interface StreamOptions {
|
|
327
|
+
signal?: AbortSignal;
|
|
328
|
+
/** Called once when a streamed turn completes successfully. */
|
|
329
|
+
onResult?: (info: StreamResultInfo) => void;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Translates Anthropic Messages API requests into turns on whichever
|
|
333
|
+
* signed-in coding harness the model id names — Claude Code by default,
|
|
334
|
+
* `codex:…`, `opencode:…`, `gemini:…` and friends on request.
|
|
335
|
+
*/
|
|
336
|
+
declare class YagamiEngine {
|
|
337
|
+
readonly providers: Map<string, Provider>;
|
|
338
|
+
readonly unavailable: Map<string, string>;
|
|
339
|
+
readonly defaultProviderId: string;
|
|
340
|
+
private readonly defaultModel;
|
|
341
|
+
private readonly cache;
|
|
342
|
+
private readonly modelsPromises;
|
|
343
|
+
constructor(options?: EngineOptions);
|
|
344
|
+
get defaultProvider(): Provider;
|
|
345
|
+
/** Executable of the default provider. */
|
|
346
|
+
get executable(): string;
|
|
347
|
+
/** @deprecated Use `executable`. */
|
|
348
|
+
get claudePath(): string;
|
|
349
|
+
get providerIds(): string[];
|
|
350
|
+
/** Route a request's model id to a provider and its native model. */
|
|
351
|
+
resolve(model: string | undefined): {
|
|
352
|
+
provider: Provider;
|
|
353
|
+
model?: string;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Models across every available provider. The default provider's ids are
|
|
357
|
+
* listed bare as well as qualified; others only as `provider:model`.
|
|
358
|
+
* Providers whose probe fails are skipped (their error is not cached).
|
|
359
|
+
*/
|
|
360
|
+
listModels(): Promise<EngineModel[]>;
|
|
361
|
+
private providerModels;
|
|
362
|
+
private prepare;
|
|
363
|
+
/**
|
|
364
|
+
* A failed resumed attempt usually means the cached session no longer
|
|
365
|
+
* exists. Drop the stale mapping and re-prepare from scratch — the
|
|
366
|
+
* transcript-replay path. Undefined when falling back is impossible.
|
|
367
|
+
*/
|
|
368
|
+
private prepareResumeFallback;
|
|
369
|
+
private storeSession;
|
|
370
|
+
complete(req: MessagesRequest): Promise<CompleteResult>;
|
|
371
|
+
private attemptComplete;
|
|
372
|
+
/**
|
|
373
|
+
* Validates synchronously (throws ApiError), then returns a lazy generator
|
|
374
|
+
* of Anthropic-style SSE events.
|
|
375
|
+
*/
|
|
376
|
+
stream(req: MessagesRequest, streamOptions?: StreamOptions): StreamStart;
|
|
377
|
+
private runStream;
|
|
378
|
+
private attemptStream;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export { ApiError as A, presetFor as B, CodexProvider as C, type DetectedProvider as D, type EngineModel as E, qualifiedModel as F, type LoadedProviders as L, type MessageParam as M, type Provider as P, SessionCache as S, type TurnRequest as T, type Usage as U, YagamiEngine as Y, type ProviderCapabilities as a, type TurnEvent as b, type ApiErrorType as c, type CodexProviderOptions as d, type CodexSandboxMode as e, type CompleteResult as f, type ContentBlock as g, type ContentBlockParam as h, type EngineOptions as i, type MessagesRequest as j, type MessagesResponse as k, type ModelRef as l, PROVIDER_PRESETS as m, type ProviderConfigEntry as n, type ProviderKind as o, type ProviderPreset as p, type SessionCacheOptions as q, type SseEvent as r, type StreamOptions as s, type StreamResultInfo as t, type StreamStart as u, type SystemParam as v, createProvider as w, detectProviders as x, loadProviders as y, parseModelRef as z };
|