@justin06lee/yagami 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -95
- package/dist/{chunk-M5UHR273.js → chunk-D2PNH6GV.js} +80 -20
- package/dist/chunk-D2PNH6GV.js.map +1 -0
- package/dist/{chunk-ASS6MJ7C.js → chunk-ZYHC7PXX.js} +887 -13
- package/dist/chunk-ZYHC7PXX.js.map +1 -0
- package/dist/cli.js +33 -8
- package/dist/cli.js.map +1 -1
- package/dist/{engine-pmCK3S7z.d.ts → hostConfig-HmZ3z297.d.ts} +114 -2
- package/dist/index.d.ts +207 -5
- package/dist/index.js +79 -3
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/server.js +4 -3
- package/package.json +2 -2
- package/dist/chunk-ASS6MJ7C.js.map +0 -1
- package/dist/chunk-M5UHR273.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
sessionCachePath,
|
|
14
14
|
startYagami,
|
|
15
15
|
writeServerState
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-D2PNH6GV.js";
|
|
17
17
|
import {
|
|
18
18
|
VERSION,
|
|
19
19
|
YagamiEngine,
|
|
20
20
|
createProvider,
|
|
21
21
|
detectProviders
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZYHC7PXX.js";
|
|
23
23
|
|
|
24
24
|
// src/cli.ts
|
|
25
25
|
import { spawn } from "child_process";
|
|
@@ -28,7 +28,7 @@ import * as path from "path";
|
|
|
28
28
|
import { Command } from "commander";
|
|
29
29
|
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
30
30
|
var program = new Command();
|
|
31
|
-
program.name("yagami").description("Anthropic-compatible API served by your signed-in
|
|
31
|
+
program.name("yagami").description("Anthropic- and OpenAI-compatible API served by your signed-in coding-agent CLIs").version(VERSION);
|
|
32
32
|
program.command("start", { isDefault: true }).description("start the yagami server").option("-p, --port <port>", "port to listen on").option("-H, --host <host>", "host to bind (default 127.0.0.1)").option("--claude <path>", "path to the claude executable").option("--provider <id>", "default provider for bare model ids (claude, codex, opencode, gemini, \u2026)").option("--cors", "enable permissive CORS (for browser clients)").option("--daemon", "run in the background (managed with `yagami stop`/`yagami status`)").option("--log <file>", "log file for --daemon mode (default ~/.config/yagami/yagami.log)").action(async (opts) => {
|
|
33
33
|
const fileConfig = loadFileConfig();
|
|
34
34
|
let freshKey;
|
|
@@ -78,17 +78,18 @@ program.command("start", { isDefault: true }).description("start the yagami serv
|
|
|
78
78
|
console.log(` config ${configFilePath()}`);
|
|
79
79
|
if (freshKey) {
|
|
80
80
|
console.log(` api key ${freshKey}`);
|
|
81
|
-
console.log(" (newly generated and saved \u2014
|
|
81
|
+
console.log(" (newly generated and saved \u2014 `yagami key` prints it again)");
|
|
82
82
|
} else {
|
|
83
|
-
console.log(` api keys ${running.config.apiKeys.map(maskKey).join(", ")}`);
|
|
83
|
+
console.log(` api keys ${running.config.apiKeys.map(maskKey).join(", ")} (\`yagami key\` prints them in full)`);
|
|
84
84
|
}
|
|
85
85
|
if (!["127.0.0.1", "localhost", "::1"].includes(running.config.host)) {
|
|
86
86
|
console.log(
|
|
87
87
|
` \u26A0 bound to ${running.config.host} \u2014 reachable beyond this machine. Only do this on a network you trust.`
|
|
88
88
|
);
|
|
89
89
|
}
|
|
90
|
-
console.log("\
|
|
91
|
-
console.log(` baseURL
|
|
90
|
+
console.log("\nConnect apps \u2014 either dialect, same key (`yagami key` prints ready-to-paste env exports):");
|
|
91
|
+
console.log(` Anthropic apps baseURL ${running.url} (ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY)`);
|
|
92
|
+
console.log(` OpenAI apps baseURL ${running.url}/v1 (OPENAI_BASE_URL / OPENAI_API_KEY)`);
|
|
92
93
|
} catch (err) {
|
|
93
94
|
console.error(`yagami: ${err instanceof Error ? err.message : String(err)}`);
|
|
94
95
|
process.exitCode = 1;
|
|
@@ -132,8 +133,9 @@ async function startDaemon(opts, freshKey) {
|
|
|
132
133
|
console.log(` log ${logPath}`);
|
|
133
134
|
if (freshKey) {
|
|
134
135
|
console.log(` key ${freshKey}`);
|
|
135
|
-
console.log(" (newly generated and saved \u2014
|
|
136
|
+
console.log(" (newly generated and saved \u2014 `yagami key` prints it again)");
|
|
136
137
|
}
|
|
138
|
+
console.log(" `yagami key` prints the URL, key, and env exports for client apps");
|
|
137
139
|
return;
|
|
138
140
|
}
|
|
139
141
|
await sleep(200);
|
|
@@ -194,6 +196,29 @@ program.command("keygen").description("generate an API key and add it to the con
|
|
|
194
196
|
console.log(key);
|
|
195
197
|
console.error(`saved to ${file} (${cfg.apiKeys.length} key${cfg.apiKeys.length === 1 ? "" : "s"} total)`);
|
|
196
198
|
});
|
|
199
|
+
program.command("key").description("print the server URL, API key, and ready-to-paste env exports for client apps").action(() => {
|
|
200
|
+
const cfg = loadConfig();
|
|
201
|
+
const state = readServerState();
|
|
202
|
+
const live = state !== void 0 && isProcessAlive(state.pid);
|
|
203
|
+
const url = live ? state.url : `http://${cfg.host}:${cfg.port}`;
|
|
204
|
+
if (cfg.apiKeys.length === 0) {
|
|
205
|
+
console.error("no API keys configured \u2014 run `yagami start` (generates one) or `yagami keygen`");
|
|
206
|
+
process.exitCode = 1;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const key = cfg.apiKeys[cfg.apiKeys.length - 1];
|
|
210
|
+
console.log(`url ${url}${live ? "" : " (server not running \u2014 this is where `yagami start` will listen)"}`);
|
|
211
|
+
console.log(`key ${key}`);
|
|
212
|
+
if (cfg.apiKeys.length > 1) {
|
|
213
|
+
console.log(` (newest of ${cfg.apiKeys.length} keys in ${configFilePath()})`);
|
|
214
|
+
}
|
|
215
|
+
console.log("\nAnthropic-dialect apps:");
|
|
216
|
+
console.log(` export ANTHROPIC_BASE_URL=${url}`);
|
|
217
|
+
console.log(` export ANTHROPIC_API_KEY=${key}`);
|
|
218
|
+
console.log("\nOpenAI-dialect apps:");
|
|
219
|
+
console.log(` export OPENAI_BASE_URL=${url}/v1`);
|
|
220
|
+
console.log(` export OPENAI_API_KEY=${key}`);
|
|
221
|
+
});
|
|
197
222
|
program.command("doctor").description("check which coding-agent CLIs yagami can drive and whether they work").option("--live", "send one real (tiny) completion through the default provider").option("--provider <id>", "provider to use for --live (default: config/claude)").action(async (opts) => {
|
|
198
223
|
let failed = false;
|
|
199
224
|
const cfg = loadConfig();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +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"]}
|
|
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- and OpenAI-compatible API served by your signed-in coding-agent CLIs\")\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 — `yagami key` prints it again)\");\n } else {\n console.log(` api keys ${running.config.apiKeys.map(maskKey).join(\", \")} (\\`yagami key\\` prints them in full)`);\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(\"\\nConnect apps — either dialect, same key (`yagami key` prints ready-to-paste env exports):\");\n console.log(` Anthropic apps baseURL ${running.url} (ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY)`);\n console.log(` OpenAI apps baseURL ${running.url}/v1 (OPENAI_BASE_URL / OPENAI_API_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 — `yagami key` prints it again)\");\n }\n console.log(\" `yagami key` prints the URL, key, and env exports for client apps\");\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(\"key\")\n .description(\"print the server URL, API key, and ready-to-paste env exports for client apps\")\n .action(() => {\n const cfg = loadConfig();\n const state = readServerState();\n const live = state !== undefined && isProcessAlive(state.pid);\n const url = live ? state.url : `http://${cfg.host}:${cfg.port}`;\n if (cfg.apiKeys.length === 0) {\n console.error(\"no API keys configured — run `yagami start` (generates one) or `yagami keygen`\");\n process.exitCode = 1;\n return;\n }\n const key = cfg.apiKeys[cfg.apiKeys.length - 1]!;\n console.log(`url ${url}${live ? \"\" : \" (server not running — this is where `yagami start` will listen)\"}`);\n console.log(`key ${key}`);\n if (cfg.apiKeys.length > 1) {\n console.log(` (newest of ${cfg.apiKeys.length} keys in ${configFilePath()})`);\n }\n console.log(\"\\nAnthropic-dialect apps:\");\n console.log(` export ANTHROPIC_BASE_URL=${url}`);\n console.log(` export ANTHROPIC_API_KEY=${key}`);\n console.log(\"\\nOpenAI-dialect apps:\");\n console.log(` export OPENAI_BASE_URL=${url}/v1`);\n console.log(` export OPENAI_API_KEY=${key}`);\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"]}
|
|
@@ -165,6 +165,92 @@ interface ModelRef {
|
|
|
165
165
|
*/
|
|
166
166
|
declare function parseModelRef(model: string | undefined, providerIds: Iterable<string>): ModelRef;
|
|
167
167
|
declare function qualifiedModel(providerId: string, model: string): string;
|
|
168
|
+
type SessionPermissionDecision = "allow" | "allow_always" | "deny" | "deny_always";
|
|
169
|
+
/** A harness asking the host whether a tool may run. */
|
|
170
|
+
interface SessionPermissionRequest {
|
|
171
|
+
provider: string;
|
|
172
|
+
sessionId?: string;
|
|
173
|
+
/** Tool name as the harness calls it (e.g. "Bash", "Edit", or an ACP title). */
|
|
174
|
+
tool: string;
|
|
175
|
+
/** Coarse category when known: read | edit | delete | execute | fetch | other … */
|
|
176
|
+
kind?: string;
|
|
177
|
+
title?: string;
|
|
178
|
+
input?: unknown;
|
|
179
|
+
/** Provider-native payload for hosts that want to go deep. */
|
|
180
|
+
raw?: unknown;
|
|
181
|
+
}
|
|
182
|
+
interface SessionPermissionHandler {
|
|
183
|
+
decide(req: SessionPermissionRequest, signal?: AbortSignal): Promise<SessionPermissionDecision>;
|
|
184
|
+
}
|
|
185
|
+
type AgentEvent = {
|
|
186
|
+
type: "session";
|
|
187
|
+
sessionId: string;
|
|
188
|
+
} | {
|
|
189
|
+
type: "text";
|
|
190
|
+
text: string;
|
|
191
|
+
} | {
|
|
192
|
+
type: "thinking";
|
|
193
|
+
text: string;
|
|
194
|
+
} | {
|
|
195
|
+
type: "tool_call";
|
|
196
|
+
id: string;
|
|
197
|
+
name: string;
|
|
198
|
+
status: "started" | "updated" | "completed" | "failed";
|
|
199
|
+
title?: string;
|
|
200
|
+
kind?: string;
|
|
201
|
+
input?: unknown;
|
|
202
|
+
output?: unknown;
|
|
203
|
+
} | {
|
|
204
|
+
type: "permission";
|
|
205
|
+
request: SessionPermissionRequest;
|
|
206
|
+
decision: SessionPermissionDecision;
|
|
207
|
+
} | {
|
|
208
|
+
type: "done";
|
|
209
|
+
usage?: Usage;
|
|
210
|
+
costUsd?: number;
|
|
211
|
+
stopReason?: string;
|
|
212
|
+
}
|
|
213
|
+
/** Anything the harness said that has no normalized shape. */
|
|
214
|
+
| {
|
|
215
|
+
type: "raw";
|
|
216
|
+
provider: string;
|
|
217
|
+
payload: unknown;
|
|
218
|
+
};
|
|
219
|
+
interface ProviderSessionOptions {
|
|
220
|
+
/** Project directory the agent works in. */
|
|
221
|
+
cwd: string;
|
|
222
|
+
model?: string;
|
|
223
|
+
/** Provider session id to continue. */
|
|
224
|
+
resume?: string;
|
|
225
|
+
/**
|
|
226
|
+
* "terminal" loads the same settings the interactive CLI would — user and
|
|
227
|
+
* project config, CLAUDE.md, skills, hooks, MCP servers. "isolated" loads
|
|
228
|
+
* none of it. Default "terminal", because that is the promise.
|
|
229
|
+
*/
|
|
230
|
+
parity?: "terminal" | "isolated";
|
|
231
|
+
permissions: SessionPermissionHandler;
|
|
232
|
+
appName?: string;
|
|
233
|
+
effort?: string;
|
|
234
|
+
thinking?: ThinkingParam;
|
|
235
|
+
/** Override the harness's interactive system prompt. */
|
|
236
|
+
systemPrompt?: string;
|
|
237
|
+
/** Provider-specific escape hatch (Claude: Agent SDK Options; Codex: { sandbox }; ACP: { mode }). */
|
|
238
|
+
native?: Record<string, unknown>;
|
|
239
|
+
}
|
|
240
|
+
/** One live conversation with a harness: send turns, get normalized events. */
|
|
241
|
+
interface ProviderSession {
|
|
242
|
+
readonly provider: string;
|
|
243
|
+
/** Provider session id once known (use it to resume later). */
|
|
244
|
+
readonly id: string | undefined;
|
|
245
|
+
send(input: string | ContentBlockParam[]): AsyncGenerator<AgentEvent, void, undefined>;
|
|
246
|
+
interrupt(): Promise<void>;
|
|
247
|
+
close(): Promise<void>;
|
|
248
|
+
}
|
|
249
|
+
/** Providers that can host agentic sessions implement this too. */
|
|
250
|
+
interface SessionProvider extends Provider {
|
|
251
|
+
openSession(options: ProviderSessionOptions): ProviderSession;
|
|
252
|
+
}
|
|
253
|
+
declare function isSessionProvider(p: Provider): p is SessionProvider;
|
|
168
254
|
|
|
169
255
|
type CodexSandboxMode = "read-only" | "workspace-write" | "danger-full-access";
|
|
170
256
|
interface CodexProviderOptions {
|
|
@@ -177,7 +263,7 @@ interface CodexProviderOptions {
|
|
|
177
263
|
env?: Record<string, string>;
|
|
178
264
|
}
|
|
179
265
|
/** OpenAI Codex CLI via `codex exec --json`, signed in with the user's ChatGPT account. */
|
|
180
|
-
declare class CodexProvider implements
|
|
266
|
+
declare class CodexProvider implements SessionProvider {
|
|
181
267
|
readonly id = "codex";
|
|
182
268
|
readonly label = "Codex CLI";
|
|
183
269
|
readonly executable: string;
|
|
@@ -190,6 +276,13 @@ declare class CodexProvider implements Provider {
|
|
|
190
276
|
/** Build the `codex exec` argument list for a turn (exported for tests). */
|
|
191
277
|
buildArgs(req: TurnRequest, imagePaths: string[]): string[];
|
|
192
278
|
run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined>;
|
|
279
|
+
/**
|
|
280
|
+
* A live, interactive Codex session (`codex app-server` — the TUI's own
|
|
281
|
+
* engine): streamed tool events, the user's config.toml verbatim, and
|
|
282
|
+
* approval requests forwarded to the host's permission handler. The
|
|
283
|
+
* completion-turn `run()` path above stays for API-style callers.
|
|
284
|
+
*/
|
|
285
|
+
openSession(options: ProviderSessionOptions): ProviderSession;
|
|
193
286
|
/** Ask the app-server protocol for the model catalog (no tokens spent). */
|
|
194
287
|
listModels(): Promise<EngineModel[]>;
|
|
195
288
|
version(): Promise<string | undefined>;
|
|
@@ -378,4 +471,23 @@ declare class YagamiEngine {
|
|
|
378
471
|
private attemptStream;
|
|
379
472
|
}
|
|
380
473
|
|
|
381
|
-
|
|
474
|
+
/**
|
|
475
|
+
* The engine-relevant slice of the host's yagami config
|
|
476
|
+
* (~/.config/yagami/config.json + YAGAMI_* env) — what library mode reads so
|
|
477
|
+
* an embedded `Yagami` client automatically matches the `yagami` binary on
|
|
478
|
+
* the same machine: same providers, same paths, same defaults. Server-only
|
|
479
|
+
* fields (host, port, apiKeys) are ignored here on purpose.
|
|
480
|
+
*/
|
|
481
|
+
|
|
482
|
+
declare function yagamiConfigDir(): string;
|
|
483
|
+
/** Engine options derivable from the host machine's yagami config. */
|
|
484
|
+
interface HostEngineConfig {
|
|
485
|
+
defaultProvider?: string;
|
|
486
|
+
defaultModel?: string;
|
|
487
|
+
providerConfig?: Record<string, ProviderConfigEntry>;
|
|
488
|
+
claudePath?: string;
|
|
489
|
+
claudeConfigDir?: string;
|
|
490
|
+
}
|
|
491
|
+
declare function loadHostEngineConfig(): HostEngineConfig;
|
|
492
|
+
|
|
493
|
+
export { ApiError as A, type StreamResultInfo as B, CodexProvider as C, type DetectedProvider as D, type EngineModel as E, type StreamStart as F, type SystemParam as G, type HostEngineConfig as H, createProvider as I, detectProviders as J, isSessionProvider as K, type LoadedProviders as L, type MessagesRequest as M, loadHostEngineConfig as N, loadProviders as O, type Provider as P, parseModelRef as Q, presetFor as R, type SseEvent as S, type TurnRequest as T, type Usage as U, qualifiedModel as V, yagamiConfigDir as W, YagamiEngine as Y, type MessagesResponse as a, type EngineOptions as b, type ProviderCapabilities as c, type TurnEvent as d, type SessionProvider as e, type ProviderSessionOptions as f, type ProviderSession as g, type AgentEvent as h, type ApiErrorType as i, type CodexProviderOptions as j, type CodexSandboxMode as k, type CompleteResult as l, type ContentBlock as m, type ContentBlockParam as n, type MessageParam as o, type ModelRef as p, PROVIDER_PRESETS as q, type ProviderConfigEntry as r, type ProviderKind as s, type ProviderPreset as t, SessionCache as u, type SessionCacheOptions as v, type SessionPermissionDecision as w, type SessionPermissionHandler as x, type SessionPermissionRequest as y, type StreamOptions as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,204 @@
|
|
|
1
|
-
import { A as ApiError, P as Provider,
|
|
2
|
-
export {
|
|
1
|
+
import { S as SseEvent, M as MessagesRequest, E as EngineModel, A as ApiError, a as MessagesResponse, Y as YagamiEngine, b as EngineOptions, P as Provider, c as ProviderCapabilities, T as TurnRequest, d as TurnEvent, e as SessionProvider, f as ProviderSessionOptions, g as ProviderSession } from './hostConfig-HmZ3z297.js';
|
|
2
|
+
export { h as AgentEvent, i as ApiErrorType, C as CodexProvider, j as CodexProviderOptions, k as CodexSandboxMode, l as CompleteResult, m as ContentBlock, n as ContentBlockParam, D as DetectedProvider, H as HostEngineConfig, L as LoadedProviders, o as MessageParam, p as ModelRef, q as PROVIDER_PRESETS, r as ProviderConfigEntry, s as ProviderKind, t as ProviderPreset, u as SessionCache, v as SessionCacheOptions, w as SessionPermissionDecision, x as SessionPermissionHandler, y as SessionPermissionRequest, z as StreamOptions, B as StreamResultInfo, F as StreamStart, G as SystemParam, U as Usage, I as createProvider, J as detectProviders, K as isSessionProvider, N as loadHostEngineConfig, O as loadProviders, Q as parseModelRef, R as presetFor, V as qualifiedModel, W as yagamiConfigDir } from './hostConfig-HmZ3z297.js';
|
|
3
3
|
import { Options, SDKUserMessage, Query, SettingSource, PermissionUpdate, CanUseTool, PermissionResult, SDKMessage } from '@anthropic-ai/claude-agent-sdk';
|
|
4
4
|
export { Options as AgentOptions, CanUseTool, PermissionMode, Query, SDKMessage, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
|
|
5
5
|
import { ClientSideConnection, InitializeResponse, SessionNotification, RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* OpenAI Chat Completions dialect: translation to and from the Anthropic
|
|
9
|
+
* Messages shapes the engine speaks. Pure functions — used by both the HTTP
|
|
10
|
+
* server (`POST /v1/chat/completions`) and the library client
|
|
11
|
+
* (`yagami.chat.completions.create`).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
interface ChatMessageParam {
|
|
15
|
+
role: string;
|
|
16
|
+
content?: string | null | Array<{
|
|
17
|
+
type: string;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}>;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
interface ChatCompletionsRequest {
|
|
23
|
+
model?: string;
|
|
24
|
+
messages: ChatMessageParam[];
|
|
25
|
+
stream?: boolean;
|
|
26
|
+
stream_options?: {
|
|
27
|
+
include_usage?: boolean;
|
|
28
|
+
};
|
|
29
|
+
max_tokens?: number;
|
|
30
|
+
max_completion_tokens?: number;
|
|
31
|
+
temperature?: number;
|
|
32
|
+
top_p?: number;
|
|
33
|
+
stop?: string | string[];
|
|
34
|
+
n?: number;
|
|
35
|
+
reasoning_effort?: string;
|
|
36
|
+
tools?: unknown;
|
|
37
|
+
tool_choice?: unknown;
|
|
38
|
+
functions?: unknown;
|
|
39
|
+
function_call?: unknown;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
interface ChatCompletionChoice {
|
|
43
|
+
index: number;
|
|
44
|
+
message: {
|
|
45
|
+
role: "assistant";
|
|
46
|
+
content: string;
|
|
47
|
+
/** Thinking output (DeepSeek-style extension; no standard OpenAI field exists). */
|
|
48
|
+
reasoning_content?: string;
|
|
49
|
+
refusal: null;
|
|
50
|
+
};
|
|
51
|
+
finish_reason: string;
|
|
52
|
+
logprobs: null;
|
|
53
|
+
}
|
|
54
|
+
interface ChatCompletion {
|
|
55
|
+
id: string;
|
|
56
|
+
object: "chat.completion";
|
|
57
|
+
created: number;
|
|
58
|
+
model: string;
|
|
59
|
+
choices: ChatCompletionChoice[];
|
|
60
|
+
usage: OpenAiUsage;
|
|
61
|
+
}
|
|
62
|
+
interface OpenAiUsage {
|
|
63
|
+
prompt_tokens: number;
|
|
64
|
+
completion_tokens: number;
|
|
65
|
+
total_tokens: number;
|
|
66
|
+
}
|
|
67
|
+
interface ChatCompletionChunk {
|
|
68
|
+
id: string;
|
|
69
|
+
object: "chat.completion.chunk";
|
|
70
|
+
created: number;
|
|
71
|
+
model: string;
|
|
72
|
+
choices: Array<{
|
|
73
|
+
index: number;
|
|
74
|
+
delta: {
|
|
75
|
+
role?: "assistant";
|
|
76
|
+
content?: string;
|
|
77
|
+
reasoning_content?: string;
|
|
78
|
+
};
|
|
79
|
+
finish_reason: string | null;
|
|
80
|
+
}>;
|
|
81
|
+
usage?: OpenAiUsage;
|
|
82
|
+
}
|
|
83
|
+
interface TranslatedChatRequest {
|
|
84
|
+
req: MessagesRequest;
|
|
85
|
+
/** OpenAI params yagami accepted but cannot honor (adds to x-yagami-ignored). */
|
|
86
|
+
extraIgnored: string[];
|
|
87
|
+
/** `stream_options.include_usage` — emit the trailing usage chunk. */
|
|
88
|
+
includeUsage: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Translate an OpenAI Chat Completions request into the Anthropic Messages
|
|
92
|
+
* request the engine runs. Tool calling is rejected (yagami is
|
|
93
|
+
* completions-only by design); knobs no CLI engine exposes are collected
|
|
94
|
+
* into `extraIgnored` instead of failing the request.
|
|
95
|
+
*/
|
|
96
|
+
declare function chatToMessagesRequest(body: ChatCompletionsRequest): TranslatedChatRequest;
|
|
97
|
+
/** Anthropic Messages response → OpenAI chat.completion. */
|
|
98
|
+
declare function toChatCompletion(resp: MessagesResponse): ChatCompletion;
|
|
99
|
+
/** OpenAI-shaped error body (the OpenAI dialect's counterpart of ApiError.toBody). */
|
|
100
|
+
declare function openAiErrorBody(err: ApiError): {
|
|
101
|
+
error: {
|
|
102
|
+
message: string;
|
|
103
|
+
type: string;
|
|
104
|
+
param: null;
|
|
105
|
+
code: null;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Re-emits an Anthropic SSE event sequence as OpenAI chat.completion.chunk
|
|
110
|
+
* objects. Feed every engine event through `push`; the caller appends the
|
|
111
|
+
* `[DONE]` sentinel (HTTP mode) unless `errored`.
|
|
112
|
+
*/
|
|
113
|
+
declare class ChatChunkTranslator {
|
|
114
|
+
private readonly includeUsage;
|
|
115
|
+
private id;
|
|
116
|
+
private model;
|
|
117
|
+
private created;
|
|
118
|
+
private stopReason;
|
|
119
|
+
private usage;
|
|
120
|
+
/** Set when the engine reported an error mid-stream (no [DONE] after). */
|
|
121
|
+
errored: boolean;
|
|
122
|
+
constructor(includeUsage: boolean);
|
|
123
|
+
private chunk;
|
|
124
|
+
/** Translate one engine SSE event into zero or more OpenAI chunk payloads. */
|
|
125
|
+
push(ev: SseEvent): unknown[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Model list body served by GET /v1/models: Anthropic fields and OpenAI
|
|
129
|
+
* fields on the same objects, so both SDKs' `models.list()` parse it.
|
|
130
|
+
*/
|
|
131
|
+
declare function modelListBody(models: EngineModel[]): {
|
|
132
|
+
object: "list";
|
|
133
|
+
data: Array<Record<string, unknown>>;
|
|
134
|
+
has_more: false;
|
|
135
|
+
first_id?: string;
|
|
136
|
+
last_id?: string;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* `Yagami` — the zero-config library client. `new Yagami()` needs no URL and
|
|
141
|
+
* no API key: it finds the coding-agent CLIs already installed and signed in
|
|
142
|
+
* on this machine (the same T3-Code trick the server does) and mirrors the
|
|
143
|
+
* Anthropic and OpenAI SDK surfaces on top of them, so an app written
|
|
144
|
+
* against either SDK shape drops in with nothing to configure.
|
|
145
|
+
*
|
|
146
|
+
* By default it also reads the host's yagami config
|
|
147
|
+
* (~/.config/yagami/config.json), so an embedded client and the `yagami`
|
|
148
|
+
* binary on the same machine agree on providers, paths, and defaults.
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
interface YagamiOptions extends EngineOptions {
|
|
152
|
+
/**
|
|
153
|
+
* Merge the host machine's yagami config (providers, defaults) under any
|
|
154
|
+
* explicit options, so library and binary stay in sync. Default true;
|
|
155
|
+
* ignored when explicit `providers` instances are passed.
|
|
156
|
+
*/
|
|
157
|
+
syncHostConfig?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/** An Anthropic stream event's payload (`message_start`, `content_block_delta`, …). */
|
|
160
|
+
interface MessageStreamEvent {
|
|
161
|
+
type: string;
|
|
162
|
+
[key: string]: unknown;
|
|
163
|
+
}
|
|
164
|
+
interface YagamiMessages {
|
|
165
|
+
/** Anthropic-SDK-shaped: non-stream resolves to the message; `stream: true` yields stream events. */
|
|
166
|
+
create(req: MessagesRequest & {
|
|
167
|
+
stream: true;
|
|
168
|
+
}): AsyncGenerator<MessageStreamEvent, void, undefined>;
|
|
169
|
+
create(req: MessagesRequest & {
|
|
170
|
+
stream?: false | undefined;
|
|
171
|
+
}): Promise<MessagesResponse>;
|
|
172
|
+
/** Always-streaming variant (the SDK's `messages.stream`). */
|
|
173
|
+
stream(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined>;
|
|
174
|
+
}
|
|
175
|
+
interface YagamiChatCompletions {
|
|
176
|
+
/** OpenAI-SDK-shaped: non-stream resolves to a chat.completion; `stream: true` yields chunks. */
|
|
177
|
+
create(req: ChatCompletionsRequest & {
|
|
178
|
+
stream: true;
|
|
179
|
+
}): AsyncGenerator<ChatCompletionChunk, void, undefined>;
|
|
180
|
+
create(req: ChatCompletionsRequest & {
|
|
181
|
+
stream?: false | undefined;
|
|
182
|
+
}): Promise<ChatCompletion>;
|
|
183
|
+
}
|
|
184
|
+
declare class Yagami {
|
|
185
|
+
/** The underlying engine, for anything beyond the SDK-shaped surface. */
|
|
186
|
+
readonly engine: YagamiEngine;
|
|
187
|
+
constructor(options?: YagamiOptions);
|
|
188
|
+
readonly messages: YagamiMessages;
|
|
189
|
+
readonly chat: {
|
|
190
|
+
completions: YagamiChatCompletions;
|
|
191
|
+
};
|
|
192
|
+
readonly models: {
|
|
193
|
+
/** Both SDK shapes at once (Anthropic + OpenAI model-list fields). */
|
|
194
|
+
list: () => Promise<ReturnType<typeof modelListBody>>;
|
|
195
|
+
/** The engine's raw model list. */
|
|
196
|
+
raw: () => Promise<EngineModel[]>;
|
|
197
|
+
};
|
|
198
|
+
private streamMessageEvents;
|
|
199
|
+
private streamChatChunks;
|
|
200
|
+
}
|
|
201
|
+
|
|
7
202
|
interface ClaudeSessionOptions {
|
|
8
203
|
/** Path to the `claude` binary. Auto-resolved when omitted. */
|
|
9
204
|
claudePath?: string;
|
|
@@ -276,7 +471,7 @@ interface AcpProviderOptions {
|
|
|
276
471
|
* Gemini CLI, Copilot, Cursor, Qwen Code, Kimi, Goose, and anything in the
|
|
277
472
|
* ACP registry. One adapter, many harnesses.
|
|
278
473
|
*/
|
|
279
|
-
declare class AcpProvider implements
|
|
474
|
+
declare class AcpProvider implements SessionProvider {
|
|
280
475
|
readonly id: string;
|
|
281
476
|
readonly label: string;
|
|
282
477
|
readonly executable: string;
|
|
@@ -292,6 +487,13 @@ declare class AcpProvider implements Provider {
|
|
|
292
487
|
private spawnConnection;
|
|
293
488
|
private classify;
|
|
294
489
|
run(req: TurnRequest): AsyncGenerator<TurnEvent, void, undefined>;
|
|
490
|
+
/**
|
|
491
|
+
* A live, interactive ACP session: the agent runs warm in the project
|
|
492
|
+
* directory with ITS OWN defaults — no plan-mode hardening, no forced
|
|
493
|
+
* config. Tool calls stream as normalized events and permission requests
|
|
494
|
+
* go to the host's handler, exactly as the agent's own client would ask.
|
|
495
|
+
*/
|
|
496
|
+
openSession(options: ProviderSessionOptions): ProviderSession;
|
|
295
497
|
private selectModel;
|
|
296
498
|
listModels(): Promise<EngineModel[]>;
|
|
297
499
|
/**
|
|
@@ -323,6 +525,6 @@ declare function resolveExecutable(providerId: string, name: string, installHint
|
|
|
323
525
|
*/
|
|
324
526
|
declare function resolveClaudeExecutable(explicit?: string): string;
|
|
325
527
|
|
|
326
|
-
declare const VERSION = "0.
|
|
528
|
+
declare const VERSION = "0.5.0";
|
|
327
529
|
|
|
328
|
-
export { type AcpConnection, AcpProvider, type AcpProviderOptions, AgentSession, type AgentSessionOptions, ApiError, AuthRequiredError, ClaudeProvider, type ClaudeProviderOptions, type ClaudeSessionOptions, EngineModel, type Parity, PermissionAdapter, type PermissionAdapterOptions, type PermissionDecision, type PermissionHandler, type PermissionRequest, Provider, ProviderCapabilities, ProviderError, ProviderNotInstalledError, TurnEvent, TurnRequest, VERSION, type VersionSkew, YagamiError, claudeCodeSession, findExecutable, resolveClaudeExecutable, resolveExecutable, settingSourcesFor, startAgentSession, toApiError };
|
|
530
|
+
export { type AcpConnection, AcpProvider, type AcpProviderOptions, AgentSession, type AgentSessionOptions, ApiError, AuthRequiredError, ChatChunkTranslator, type ChatCompletion, type ChatCompletionChunk, type ChatCompletionsRequest, type ChatMessageParam, ClaudeProvider, type ClaudeProviderOptions, type ClaudeSessionOptions, EngineModel, EngineOptions, type MessageStreamEvent, MessagesRequest, MessagesResponse, type OpenAiUsage, type Parity, PermissionAdapter, type PermissionAdapterOptions, type PermissionDecision, type PermissionHandler, type PermissionRequest, Provider, ProviderCapabilities, ProviderError, ProviderNotInstalledError, ProviderSession, ProviderSessionOptions, SessionProvider, SseEvent, type TranslatedChatRequest, TurnEvent, TurnRequest, VERSION, type VersionSkew, Yagami, type YagamiChatCompletions, YagamiEngine, YagamiError, type YagamiMessages, type YagamiOptions, chatToMessagesRequest, claudeCodeSession, findExecutable, modelListBody, openAiErrorBody, resolveClaudeExecutable, resolveExecutable, settingSourcesFor, startAgentSession, toApiError, toChatCompletion };
|