@armadra/agent 0.7.5 → 0.8.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/CHANGELOG.md +34 -0
- package/CHANGELOG.zh-CN.md +34 -0
- package/dist/agent/session-classifier.d.ts +2 -0
- package/dist/agent/session-classifier.js +24 -3
- package/dist/agent/session-extensions.d.ts +1 -0
- package/dist/agent/session-extensions.js +3 -0
- package/dist/agent/session-subagent.js +9 -2
- package/dist/agent/subagent-background.d.ts +5 -1
- package/dist/agent/subagent-background.js +13 -1
- package/dist/agent/subagent-fork.d.ts +10 -5
- package/dist/agent/subagent-fork.js +22 -6
- package/dist/agent/subagent-registry.d.ts +1 -1
- package/dist/agent/subagent-registry.js +1 -1
- package/dist/agents/catalog.d.ts +1 -0
- package/dist/ai/apis/chatgpt-backend.d.ts +3 -1
- package/dist/ai/apis/chatgpt-backend.js +10 -1
- package/dist/ai/apis/max-tokens.d.ts +4 -0
- package/dist/ai/apis/max-tokens.js +12 -1
- package/dist/ai/providers/enrich.d.ts +6 -2
- package/dist/ai/providers/enrich.js +13 -2
- package/dist/ai/providers/max-tokens-cache.d.ts +22 -0
- package/dist/ai/providers/max-tokens-cache.js +95 -0
- package/dist/ai/providers/registry.js +3 -3
- package/dist/bundle/ama.cjs +1250 -375
- package/dist/checkpoints/shadow-git.d.ts +5 -1
- package/dist/checkpoints/shadow-git.js +11 -2
- package/dist/cli/compose-providers.d.ts +1 -0
- package/dist/cli/compose-providers.js +3 -0
- package/dist/cli/compose-store.d.ts +6 -2
- package/dist/cli/compose-store.js +8 -4
- package/dist/cli/compose.js +2 -2
- package/dist/config/json-schema.js +1 -0
- package/dist/config/key-docs.js +1 -0
- package/dist/config/schema-w5.js +2 -0
- package/dist/config/settings-registry.js +1 -0
- package/dist/config/types-w5.d.ts +5 -0
- package/dist/drivers/acp/driver.d.ts +22 -1
- package/dist/drivers/acp/driver.js +59 -5
- package/dist/drivers/agents.js +3 -0
- package/dist/drivers/catalog.d.ts +2 -0
- package/dist/drivers/catalog.js +94 -4
- package/dist/drivers/native/claude-normalize.d.ts +8 -0
- package/dist/drivers/native/claude-normalize.js +27 -0
- package/dist/drivers/native/claude-stream.js +16 -1
- package/dist/drivers/native/codex-app-server.js +4 -2
- package/dist/drivers/native/oneshot.js +12 -2
- package/dist/drivers/native/pi-gate.d.ts +19 -0
- package/dist/drivers/native/pi-gate.js +39 -0
- package/dist/drivers/native/pi-rpc.d.ts +29 -0
- package/dist/drivers/native/pi-rpc.js +483 -0
- package/dist/drivers/runner.js +1 -0
- package/dist/drivers/types.d.ts +1 -1
- package/dist/i18n/catalog.d.ts +5 -0
- package/dist/i18n/messages/auth.d.ts +2 -0
- package/dist/i18n/messages/auth.js +2 -0
- package/dist/i18n/messages/config-keys.d.ts +2 -0
- package/dist/i18n/messages/config-keys.js +2 -0
- package/dist/i18n/messages/config.d.ts +2 -0
- package/dist/i18n/messages/drivers.d.ts +4 -0
- package/dist/i18n/messages/drivers.js +4 -0
- package/dist/i18n/messages/interactive.d.ts +2 -0
- package/dist/i18n/messages/interactive.js +2 -0
- package/dist/i18n/messages/session.js +2 -2
- package/dist/modes/interactive/agent-ui.js +7 -0
- package/dist/session/manager.d.ts +3 -1
- package/dist/session/manager.js +5 -0
- package/dist/session/offload.d.ts +10 -2
- package/dist/session/offload.js +27 -4
- package/dist/tools/background-jobs.d.ts +4 -4
- package/dist/tools/background-jobs.js +4 -4
- package/dist/tools/bash.d.ts +2 -1
- package/dist/tools/bash.js +4 -3
- package/dist/tools/task-ctl.js +2 -1
- package/dist/tools/task.d.ts +9 -0
- package/dist/tools/task.js +27 -1
- package/docs/agents.md +70 -14
- package/docs/en/permissions.md +1 -1
- package/docs/en/providers.md +11 -10
- package/docs/en/sessions.md +2 -1
- package/docs/permissions.md +1 -1
- package/docs/providers.md +16 -11
- package/docs/session-format.md +2 -1
- package/docs/sessions.md +2 -1
- package/package.json +1 -1
package/dist/bundle/ama.cjs
CHANGED
|
@@ -41,7 +41,7 @@ var AMA_VERSION;
|
|
|
41
41
|
var init_version = __esm({
|
|
42
42
|
"src/version.ts"() {
|
|
43
43
|
"use strict";
|
|
44
|
-
AMA_VERSION = true ? "0.
|
|
44
|
+
AMA_VERSION = true ? "0.8.0" : readPackageVersion();
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -1969,7 +1969,8 @@ var init_interactive = __esm({
|
|
|
1969
1969
|
backgroundExited: (jobId, code, command3) => `Background command ${jobId} exited (code ${code}): ${command3}`,
|
|
1970
1970
|
backgroundStopped: (jobId, command3) => `Background command ${jobId} stopped: ${command3}`,
|
|
1971
1971
|
compactionFailed: (error2) => `Compaction failed: ${error2}`,
|
|
1972
|
-
compactionCancelled: "Compaction cancelled"
|
|
1972
|
+
compactionCancelled: "Compaction cancelled",
|
|
1973
|
+
imageReadBackFailed: (id) => `Session image for entry ${id} could not be read back (file changed); it stays empty`
|
|
1973
1974
|
},
|
|
1974
1975
|
statusLine: {
|
|
1975
1976
|
usage: "Usage: /statusline [full|compact]",
|
|
@@ -2104,7 +2105,8 @@ var init_interactive = __esm({
|
|
|
2104
2105
|
backgroundExited: (jobId, code, command3) => `后台命令 ${jobId} 已退出(码 ${code}):${command3}`,
|
|
2105
2106
|
backgroundStopped: (jobId, command3) => `后台命令 ${jobId} 已停止:${command3}`,
|
|
2106
2107
|
compactionFailed: (error2) => `压缩失败:${error2}`,
|
|
2107
|
-
compactionCancelled: "压缩已取消"
|
|
2108
|
+
compactionCancelled: "压缩已取消",
|
|
2109
|
+
imageReadBackFailed: (id) => `会话文件已改变,条目 ${id} 的图片读不回,保留为空`
|
|
2108
2110
|
},
|
|
2109
2111
|
statusLine: {
|
|
2110
2112
|
usage: "用法:/statusline [full|compact]",
|
|
@@ -3814,6 +3816,7 @@ var init_config_keys = __esm({
|
|
|
3814
3816
|
"subagents.maxPending": "Queue limit; task fails beyond it",
|
|
3815
3817
|
"subagents.retainSessions": "Finished sub-sessions kept in memory (least recently used first out); others reopen from their session file when continued",
|
|
3816
3818
|
"subagents.defaultModel": "Default sub-session model provider/model[@channel]",
|
|
3819
|
+
"subagents.forkMaxContextRatio": "Fork sub-agents fall back to fresh when the parent's last request used more than this share of (window − compaction.reserveTokens); 0.05–0.95, default 0.5",
|
|
3817
3820
|
"subagents.background": "Whether task runs in the background by default: auto = background in the TUI / RPC / ACP and foreground with -p; always / never are fixed. The call argument and the agent type's background: override it; user, project and host level",
|
|
3818
3821
|
"subagents.autoBackgroundAfterMs": "Move a foreground task to the background after it has run this many milliseconds; 0 disables; user and project level",
|
|
3819
3822
|
models: "Model aliases and the model picker list; user level only (effective from wave 5 W5-G)",
|
|
@@ -3942,6 +3945,7 @@ var init_config_keys = __esm({
|
|
|
3942
3945
|
"subagents.maxPending": "排队上限,超出时 task 报错",
|
|
3943
3946
|
"subagents.retainSessions": "内存中保留的已结束子会话数(最久未用的先释放),其余续聊时从会话文件重开",
|
|
3944
3947
|
"subagents.defaultModel": "子会话缺省模型 provider/model[@channel]",
|
|
3948
|
+
"subagents.forkMaxContextRatio": "fork 子 Agent 的回落比例:父上一次请求超过(窗口 − compaction.reserveTokens)的这一比例时改为 fresh;0.05–0.95,缺省 0.5",
|
|
3945
3949
|
"subagents.background": "task 缺省是否后台:auto = TUI / RPC / ACP 下后台、-p 下前台;always / never 固定。调用参数与类型定义的 background: 优先;用户、项目、宿主级都认",
|
|
3946
3950
|
"subagents.autoBackgroundAfterMs": "前台任务运行超过该毫秒数自动转后台;0 关闭;用户、项目级都认",
|
|
3947
3951
|
models: "模型别名与模型选择器清单;只认用户级(第五波 W5-G 起生效)",
|
|
@@ -4237,6 +4241,7 @@ var init_drivers = __esm({
|
|
|
4237
4241
|
resumeUnsupported: (agent) => `${agent} cannot resume sessions; started a new one`,
|
|
4238
4242
|
resumeNotFound: (agent, id) => `${agent} cannot find session ${id}; started a new one`,
|
|
4239
4243
|
noMatchingMode: (agent, mode) => `${agent} has no "${mode}" mode; running in its own default mode (actions that need approval still come to you)`,
|
|
4244
|
+
noMatchingModel: (agent, model) => `${agent} does not offer model "${model}"; using its own default model`,
|
|
4240
4245
|
noImages: (agent) => `${agent} does not accept images; omitted`,
|
|
4241
4246
|
noImagesDriver: (agent) => `the ${agent} driver does not pass images yet; omitted`,
|
|
4242
4247
|
noImagesOneshot: (agent) => `${agent} one-shot mode does not pass images; omitted`,
|
|
@@ -4247,6 +4252,7 @@ var init_drivers = __esm({
|
|
|
4247
4252
|
error: (agent, message, retrying) => `${agent}: ${message}${retrying ? " (retrying)" : ""}`,
|
|
4248
4253
|
askedQuestion: (agent, tool) => `${agent} wants to ask you a question (${tool}); ama does not answer for you and asked it to put the question in its final reply`,
|
|
4249
4254
|
askedQuestionCodex: (agent) => `${agent} wants to ask you a question; ama does not answer for you — have it put the question in its final reply`,
|
|
4255
|
+
extensionDialog: (agent, title) => `${agent}: an extension asked for input (${title}); ama does not answer for you, cancelled`,
|
|
4250
4256
|
mcpElicitation: (agent) => `${agent}'s MCP server asked for input; ama does not answer for you, cancelled`
|
|
4251
4257
|
},
|
|
4252
4258
|
/** Hook 配置与输出的警告(给人看;回给模型的阻止理由固定英文)。 */
|
|
@@ -4296,6 +4302,7 @@ var init_drivers = __esm({
|
|
|
4296
4302
|
resumeUnsupported: (agent) => `${agent} 不支持续接会话,已新开`,
|
|
4297
4303
|
resumeNotFound: (agent, id) => `${agent} 找不到会话 ${id},已新开`,
|
|
4298
4304
|
noMatchingMode: (agent, mode) => `${agent} 没有「${mode}」模式,按它自己的缺省模式运行(需要授权的操作仍交给你)`,
|
|
4305
|
+
noMatchingModel: (agent, model) => `${agent} 没有模型「${model}」,按它自己的缺省模型运行`,
|
|
4299
4306
|
noImages: (agent) => `${agent} 不接受图片,已省略`,
|
|
4300
4307
|
noImagesDriver: (agent) => `${agent} 驱动暂不传图片,已省略`,
|
|
4301
4308
|
noImagesOneshot: (agent) => `${agent} 一次性模式不传图片,已省略`,
|
|
@@ -4306,6 +4313,7 @@ var init_drivers = __esm({
|
|
|
4306
4313
|
error: (agent, message, retrying) => `${agent}:${message}${retrying ? "(重试中)" : ""}`,
|
|
4307
4314
|
askedQuestion: (agent, tool) => `${agent} 想向你提问(${tool});ama 不代答,已请它把问题写进最终回复`,
|
|
4308
4315
|
askedQuestionCodex: (agent) => `${agent} 想向你提问;ama 不代答,请让它把问题写进最终回复`,
|
|
4316
|
+
extensionDialog: (agent, title) => `${agent}:扩展请求输入(${title});ama 不代答,已取消`,
|
|
4309
4317
|
mcpElicitation: (agent) => `${agent} 的 MCP 服务器请求输入;ama 不代答,已取消`
|
|
4310
4318
|
},
|
|
4311
4319
|
hooks: {
|
|
@@ -4439,7 +4447,7 @@ var init_session = __esm({
|
|
|
4439
4447
|
cwdIsHome: "the working directory is the home directory",
|
|
4440
4448
|
gitNotFound: "git not found",
|
|
4441
4449
|
tooManyFiles: (files, max) => `the working directory has ${plural(files, "file")} (limit ${max})`,
|
|
4442
|
-
tooSlow: (seconds2, max) => `
|
|
4450
|
+
tooSlow: (seconds2, max) => `snapshots took longer than ${max} s twice in a row (latest ${seconds2} s)`,
|
|
4443
4451
|
gitFailed: (command3, code, detail) => `git ${command3} failed (${code})${detail === "" ? "" : `: ${detail}`}`,
|
|
4444
4452
|
noShadowCommit: "the checkpoint has no shadow commit",
|
|
4445
4453
|
shadowCommitMissing: (commit) => `shadow commit ${commit} does not exist`,
|
|
@@ -4571,7 +4579,7 @@ var init_session = __esm({
|
|
|
4571
4579
|
cwdIsHome: "工作目录是家目录",
|
|
4572
4580
|
gitNotFound: "找不到 git",
|
|
4573
4581
|
tooManyFiles: (files, max) => `工作目录有 ${files} 个文件(上限 ${max})`,
|
|
4574
|
-
tooSlow: (seconds2, max) =>
|
|
4582
|
+
tooSlow: (seconds2, max) => `连续两次快照超过 ${max} 秒(最近一次 ${seconds2} 秒)`,
|
|
4575
4583
|
gitFailed: (command3, code, detail) => `git ${command3} 失败(${code})${detail === "" ? "" : `:${detail}`}`,
|
|
4576
4584
|
noShadowCommit: "检查点没有影子提交",
|
|
4577
4585
|
shadowCommitMissing: (commit) => `影子提交 ${commit} 不存在`,
|
|
@@ -5355,6 +5363,7 @@ Then paste the full URL from the address bar (http://127.0.0.1:…/auth/callback
|
|
|
5355
5363
|
},
|
|
5356
5364
|
request: {
|
|
5357
5365
|
notEligible: "this ChatGPT account cannot share plan usage with ama (403 subscription_sharing_user_not_eligible). Possible causes:\n 1. Plan: plan usage is shared with Plus / Pro only\n 2. Workspace account: Team / Enterprise / Edu workspaces may not offer it\n 3. Region restriction, or not yet rolled out during the preview (most likely when a Pro account still gets this error)\nYou can sign in the other way instead: ama auth login chatgpt --flavor codex",
|
|
5366
|
+
modelUnavailable: (model) => `${model} is not available to this ChatGPT account (400 from the codex backend). The backend's model list changes over time: run ama models discover chatgpt to refresh it, then pick a listed model with /model or --model`,
|
|
5358
5367
|
flavorMismatch: (current3, ref, pinned) => `signed in with ${current3}, but ${ref} pins the @${pinned} channel. Drop @${pinned} so the channel follows the sign-in, or run ama auth login chatgpt --flavor ${pinned}`
|
|
5359
5368
|
},
|
|
5360
5369
|
errors: {
|
|
@@ -5463,6 +5472,7 @@ Then paste the full URL from the address bar (http://127.0.0.1:…/auth/callback
|
|
|
5463
5472
|
},
|
|
5464
5473
|
request: {
|
|
5465
5474
|
notEligible: "这个 ChatGPT 账户不能把套餐额度共享给 ama(403 subscription_sharing_user_not_eligible)。可能的原因:\n 1. 账户套餐:额度共享只对 Plus / Pro 开放\n 2. 工作空间账户:Team / Enterprise / Edu 工作空间可能未开放\n 3. 地区受限,或预览期尚未开放(Pro 账户仍报此错时最可能是这一条)\n可以改用另一种登录方式:ama auth login chatgpt --flavor codex",
|
|
5475
|
+
modelUnavailable: (model) => `${model} 在这个 ChatGPT 账户下不可用(codex 后端回 400)。后端的模型表会变化:运行 ama models discover chatgpt 刷新,再用 /model 或 --model 选表里的模型`,
|
|
5466
5476
|
flavorMismatch: (current3, ref, pinned) => `当前以 ${current3} 方式登录,但 ${ref} 显式指定了 @${pinned} 渠道。去掉 @${pinned} 让渠道跟随登录方式,或运行 ama auth login chatgpt --flavor ${pinned}`
|
|
5467
5477
|
},
|
|
5468
5478
|
errors: {
|
|
@@ -6776,7 +6786,8 @@ function validateConfigW5(c, config) {
|
|
|
6776
6786
|
"defaultModel",
|
|
6777
6787
|
"background",
|
|
6778
6788
|
"autoBackgroundAfterMs",
|
|
6779
|
-
"retainSessions"
|
|
6789
|
+
"retainSessions",
|
|
6790
|
+
"forkMaxContextRatio"
|
|
6780
6791
|
],
|
|
6781
6792
|
(s2, p) => {
|
|
6782
6793
|
c.number(s2, "maxConcurrent", p, 1, 64);
|
|
@@ -6785,6 +6796,7 @@ function validateConfigW5(c, config) {
|
|
|
6785
6796
|
c.oneOf(s2, "background", p, SUBAGENT_BACKGROUND_MODES);
|
|
6786
6797
|
c.number(s2, "autoBackgroundAfterMs", p, 0);
|
|
6787
6798
|
c.number(s2, "retainSessions", p, 0);
|
|
6799
|
+
c.number(s2, "forkMaxContextRatio", p, 0.05, 0.95);
|
|
6788
6800
|
}
|
|
6789
6801
|
);
|
|
6790
6802
|
checkSection(c, config, "models", ["aliases", "enabled"], (s2, p) => {
|
|
@@ -12382,7 +12394,7 @@ function fillLimits(out, hit, sources) {
|
|
|
12382
12394
|
sources.maxTokens = "catalog-alias";
|
|
12383
12395
|
}
|
|
12384
12396
|
}
|
|
12385
|
-
function enrichEntry(entry, index2) {
|
|
12397
|
+
function enrichEntry(entry, index2, providerId) {
|
|
12386
12398
|
const { modelsDev, channels: _channels, catalog: _catalog, ...rest } = entry;
|
|
12387
12399
|
const sources = {};
|
|
12388
12400
|
for (const field2 of ENRICHABLE_FIELDS) {
|
|
@@ -12390,10 +12402,14 @@ function enrichEntry(entry, index2) {
|
|
|
12390
12402
|
}
|
|
12391
12403
|
const metadata = { sources, looked: false };
|
|
12392
12404
|
const out = { ...rest };
|
|
12405
|
+
const warnings = [];
|
|
12406
|
+
const ref = `${providerId ?? "?"}/${entry.id}`;
|
|
12393
12407
|
const hit = catalogHit(entry);
|
|
12394
12408
|
if (hit !== void 0) {
|
|
12395
12409
|
metadata.catalog = hit.ref;
|
|
12396
12410
|
inheritIntrinsic(out, hit, sources);
|
|
12411
|
+
} else if (typeof entry.catalog === "string") {
|
|
12412
|
+
warnings.push(`catalog "${entry.catalog}" for "${ref}" not found; ignored`);
|
|
12397
12413
|
}
|
|
12398
12414
|
const explicit = typeof modelsDev === "string" ? modelsDev : hit?.snapshotRef;
|
|
12399
12415
|
const lookup = modelsDev !== false && (needsLookup(out) || modelsDev !== void 0);
|
|
@@ -12420,7 +12436,10 @@ function enrichEntry(entry, index2) {
|
|
|
12420
12436
|
}
|
|
12421
12437
|
}
|
|
12422
12438
|
}
|
|
12439
|
+
if (typeof modelsDev === "string" && metadata.looked && metadata.match === void 0)
|
|
12440
|
+
warnings.push(`modelsDev "${modelsDev}" for "${ref}" not found`);
|
|
12423
12441
|
if (hit !== void 0 && modelsDev !== false) fillLimits(out, hit, sources);
|
|
12442
|
+
if (warnings.length > 0) metadata.warnings = warnings;
|
|
12424
12443
|
return { entry: out, metadata };
|
|
12425
12444
|
}
|
|
12426
12445
|
function catalogMetadata(model) {
|
|
@@ -17599,8 +17618,8 @@ var init_background_jobs = __esm({
|
|
|
17599
17618
|
await entry.done;
|
|
17600
17619
|
return entry.job;
|
|
17601
17620
|
}
|
|
17602
|
-
/**
|
|
17603
|
-
output(id) {
|
|
17621
|
+
/** 输出文件尾部(缺省 2000 行 / 50 KB;调用方可传字节上限,#155)。 */
|
|
17622
|
+
output(id, options = {}) {
|
|
17604
17623
|
const entry = this.entries.get(id);
|
|
17605
17624
|
if (entry === void 0) return void 0;
|
|
17606
17625
|
let text = "";
|
|
@@ -17609,7 +17628,7 @@ var init_background_jobs = __esm({
|
|
|
17609
17628
|
text = (0, import_node_fs24.readFileSync)(entry.job.outputPath, "utf8");
|
|
17610
17629
|
} catch {
|
|
17611
17630
|
}
|
|
17612
|
-
return { ...truncateTail(text), job: entry.job };
|
|
17631
|
+
return { ...truncateTail(text, options), job: entry.job };
|
|
17613
17632
|
}
|
|
17614
17633
|
/** 取走已退出、尚未通知的任务(提醒通道用;wait 已看到退出的也算已知)。 */
|
|
17615
17634
|
takeExited() {
|
|
@@ -18097,7 +18116,7 @@ async function jobAction(input2, ctx, options) {
|
|
|
18097
18116
|
}
|
|
18098
18117
|
if (action === "stop") {
|
|
18099
18118
|
const job2 = await jobs.stop(id);
|
|
18100
|
-
const out2 = jobs.output(id);
|
|
18119
|
+
const out2 = jobs.output(id, { maxBytes: toolOutputBytes(ctx.maxResultChars) });
|
|
18101
18120
|
const text = out2?.content ?? "";
|
|
18102
18121
|
return {
|
|
18103
18122
|
content: `${text === "" ? "(no output)" : text}
|
|
@@ -18112,7 +18131,7 @@ ${jobStatusLine(job2)}`,
|
|
|
18112
18131
|
return fail2(`timeoutMs must be between 1 and ${MAX_BASH_TIMEOUT_MS}`);
|
|
18113
18132
|
await jobs.wait(id, waitMs, ctx.signal);
|
|
18114
18133
|
}
|
|
18115
|
-
const out = jobs.output(id);
|
|
18134
|
+
const out = jobs.output(id, { maxBytes: toolOutputBytes(ctx.maxResultChars) });
|
|
18116
18135
|
if (out === void 0) return fail2(`Unknown background job ${id}`);
|
|
18117
18136
|
const job = out.job;
|
|
18118
18137
|
if (job.status !== "running") jobs.markSeen(id);
|
|
@@ -18799,6 +18818,16 @@ var init_result = __esm({
|
|
|
18799
18818
|
});
|
|
18800
18819
|
|
|
18801
18820
|
// src/tools/task.ts
|
|
18821
|
+
function taskLine(prompt) {
|
|
18822
|
+
const line2 = prompt.split("\n").find((text) => text.trim() !== "")?.trim() ?? "";
|
|
18823
|
+
return line2.length > TASK_LINE_MAX ? `${line2.slice(0, TASK_LINE_MAX - 1)}…` : line2;
|
|
18824
|
+
}
|
|
18825
|
+
function nestedTaskRejection(ctx, tool, fallback) {
|
|
18826
|
+
const mark = ctx.session.lastCustom(FORK_CUSTOM_TYPE);
|
|
18827
|
+
if (mark === void 0 || mark === null) return fallback;
|
|
18828
|
+
const line2 = typeof mark.taskLine === "string" ? mark.taskLine : "";
|
|
18829
|
+
return `${tool} rejected: you are a sub-agent forked from the main conversation and cannot start or manage sub-agents. Do not call task or task_ctl again; complete the sub-task in your <task> block yourself with your other tools, then end with your report.` + (line2 !== "" ? ` Your task begins: "${line2}"` : "");
|
|
18830
|
+
}
|
|
18802
18831
|
function bindTaskAgents(tool, catalog) {
|
|
18803
18832
|
if (tool !== void 0) catalogs.set(tool, catalog);
|
|
18804
18833
|
}
|
|
@@ -18878,7 +18907,13 @@ function createTaskTool(_options = {}) {
|
|
|
18878
18907
|
promptGuidelines: [TASK_NOTIFICATION_RULE],
|
|
18879
18908
|
async execute(input2, ctx) {
|
|
18880
18909
|
if (ctx.depth >= MAX_TASK_DEPTH || ctx.spawnSubagent === void 0) {
|
|
18881
|
-
return fail3(
|
|
18910
|
+
return fail3(
|
|
18911
|
+
nestedTaskRejection(
|
|
18912
|
+
ctx,
|
|
18913
|
+
"task",
|
|
18914
|
+
"Sub-agents are not available here (nested tasks are not allowed)."
|
|
18915
|
+
)
|
|
18916
|
+
);
|
|
18882
18917
|
}
|
|
18883
18918
|
const request = buildSubagentRequest(input2, ctx);
|
|
18884
18919
|
if (typeof request === "string") return fail3(request);
|
|
@@ -18907,13 +18942,15 @@ function createTaskTool(_options = {}) {
|
|
|
18907
18942
|
};
|
|
18908
18943
|
return tool;
|
|
18909
18944
|
}
|
|
18910
|
-
var MAX_TASK_DEPTH, THINKING, TASK_CONTEXT_LEAD, FOREGROUND_DESCRIPTION, BACKGROUND_DESCRIPTION, TASK_AGENTS_HEADING, catalogs, backgrounds;
|
|
18945
|
+
var MAX_TASK_DEPTH, TASK_LINE_MAX, FORK_CUSTOM_TYPE, THINKING, TASK_CONTEXT_LEAD, FOREGROUND_DESCRIPTION, BACKGROUND_DESCRIPTION, TASK_AGENTS_HEADING, catalogs, backgrounds;
|
|
18911
18946
|
var init_task = __esm({
|
|
18912
18947
|
"src/tools/task.ts"() {
|
|
18913
18948
|
"use strict";
|
|
18914
18949
|
init_catalog3();
|
|
18915
18950
|
init_result();
|
|
18916
18951
|
MAX_TASK_DEPTH = 1;
|
|
18952
|
+
TASK_LINE_MAX = 120;
|
|
18953
|
+
FORK_CUSTOM_TYPE = "ama.fork";
|
|
18917
18954
|
THINKING = [
|
|
18918
18955
|
"off",
|
|
18919
18956
|
"minimal",
|
|
@@ -18995,7 +19032,10 @@ function createTaskCtlTool() {
|
|
|
18995
19032
|
executionMode: "parallel",
|
|
18996
19033
|
annotations: { pollable: true },
|
|
18997
19034
|
async execute(input2, ctx) {
|
|
18998
|
-
if (ctx.depth >= 1)
|
|
19035
|
+
if (ctx.depth >= 1)
|
|
19036
|
+
return fail4(
|
|
19037
|
+
nestedTaskRejection(ctx, "task_ctl", "task_ctl is not available inside a sub-agent.")
|
|
19038
|
+
);
|
|
18999
19039
|
const control = taskControl(ctx.sessionId);
|
|
19000
19040
|
if (input2.action === "list") {
|
|
19001
19041
|
const tasks = control?.list() ?? ctx.tasks?.list() ?? [];
|
|
@@ -19052,6 +19092,7 @@ var init_task_ctl = __esm({
|
|
|
19052
19092
|
"use strict";
|
|
19053
19093
|
init_result();
|
|
19054
19094
|
init_task_control();
|
|
19095
|
+
init_task();
|
|
19055
19096
|
TASK_CTL_TOOL = "task_ctl";
|
|
19056
19097
|
DEFAULT_WAIT_MS = 3e4;
|
|
19057
19098
|
MAX_WAIT_MS = 6e5;
|
|
@@ -20522,8 +20563,23 @@ var init_classifier = __esm({
|
|
|
20522
20563
|
function textOf(message) {
|
|
20523
20564
|
return message.content.filter((block) => block.type === "text").map((block) => block.type === "text" ? block.text : "").join("").trim();
|
|
20524
20565
|
}
|
|
20566
|
+
function inferredSmall(core, session) {
|
|
20567
|
+
const hit = catalogByAlias(session.id);
|
|
20568
|
+
if (hit === void 0) return void 0;
|
|
20569
|
+
const origin = hit.ref.slice(0, hit.ref.indexOf("/"));
|
|
20570
|
+
const small = catalogSmall(origin);
|
|
20571
|
+
const target = `${origin}/${small}`;
|
|
20572
|
+
if (small === void 0 || hit.ref === target) return void 0;
|
|
20573
|
+
const listed2 = core.options.providers.get(session.provider)?.models ?? [];
|
|
20574
|
+
return listed2.find((m) => {
|
|
20575
|
+
if (m.id === small) return true;
|
|
20576
|
+
const entry = catalogByAlias(m.id);
|
|
20577
|
+
return entry?.ref === target && entry.tier === void 0;
|
|
20578
|
+
})?.id;
|
|
20579
|
+
}
|
|
20525
20580
|
async function smallModel(core, session) {
|
|
20526
|
-
const
|
|
20581
|
+
const own = catalogSmall(session.provider);
|
|
20582
|
+
const small = own === void 0 ? inferredSmall(core, session) : own;
|
|
20527
20583
|
if (small === void 0 || small === session.id) return void 0;
|
|
20528
20584
|
const lookup = core.options.providers.findModel(`${session.provider}/${small}`);
|
|
20529
20585
|
if (!lookup.ok) return void 0;
|
|
@@ -25219,7 +25275,7 @@ function editTargets(file) {
|
|
|
25219
25275
|
}
|
|
25220
25276
|
return targets;
|
|
25221
25277
|
}
|
|
25222
|
-
var import_node_fs31, placeholder, ImageOffload;
|
|
25278
|
+
var import_node_fs31, placeholder, PENDING_WARNINGS, ImageOffload;
|
|
25223
25279
|
var init_offload = __esm({
|
|
25224
25280
|
"src/session/offload.ts"() {
|
|
25225
25281
|
"use strict";
|
|
@@ -25228,15 +25284,26 @@ var init_offload = __esm({
|
|
|
25228
25284
|
init_line_reader();
|
|
25229
25285
|
init_projection();
|
|
25230
25286
|
placeholder = (block) => ({ ...block, data: "" });
|
|
25287
|
+
PENDING_WARNINGS = 16;
|
|
25231
25288
|
ImageOffload = class {
|
|
25232
|
-
constructor(warn2 = () => {
|
|
25233
|
-
}) {
|
|
25234
|
-
this.warn = warn2;
|
|
25235
|
-
}
|
|
25236
|
-
warn;
|
|
25237
25289
|
/** 含图 message 条目的行位置(只有已落盘的条目才有)。 */
|
|
25238
25290
|
locators = /* @__PURE__ */ new Map();
|
|
25239
25291
|
offloaded = /* @__PURE__ */ new Set();
|
|
25292
|
+
warn;
|
|
25293
|
+
pending = [];
|
|
25294
|
+
dropped = 0;
|
|
25295
|
+
constructor(warn2) {
|
|
25296
|
+
this.warn = warn2;
|
|
25297
|
+
}
|
|
25298
|
+
/** 接上(或换掉)告警通道;之前缓冲的告警按序冲出。 */
|
|
25299
|
+
setWarn(warn2) {
|
|
25300
|
+
this.warn = warn2;
|
|
25301
|
+
const pending = this.pending.splice(0);
|
|
25302
|
+
if (this.dropped > 0)
|
|
25303
|
+
pending.push(`and ${this.dropped} more session entries could not be read back`);
|
|
25304
|
+
this.dropped = 0;
|
|
25305
|
+
for (const message of pending) warn2(message);
|
|
25306
|
+
}
|
|
25240
25307
|
/** 记下条目的行位置;不含图片的条目忽略。 */
|
|
25241
25308
|
track(entry, locator) {
|
|
25242
25309
|
if (hasImages(entry)) this.locators.set(entry.id, locator);
|
|
@@ -25326,10 +25393,15 @@ var init_offload = __esm({
|
|
|
25326
25393
|
} catch (error2) {
|
|
25327
25394
|
this.locators.delete(entry.id);
|
|
25328
25395
|
this.offloaded.delete(entry.id);
|
|
25329
|
-
this.
|
|
25396
|
+
this.report(`cannot read session entry ${entry.id} back from ${file}: ${String(error2)}`);
|
|
25330
25397
|
return void 0;
|
|
25331
25398
|
}
|
|
25332
25399
|
}
|
|
25400
|
+
report(message) {
|
|
25401
|
+
if (this.warn !== void 0) this.warn(message);
|
|
25402
|
+
else if (this.pending.length < PENDING_WARNINGS) this.pending.push(message);
|
|
25403
|
+
else this.dropped++;
|
|
25404
|
+
}
|
|
25333
25405
|
};
|
|
25334
25406
|
}
|
|
25335
25407
|
});
|
|
@@ -25514,6 +25586,11 @@ var init_manager = __esm({
|
|
|
25514
25586
|
if (this.storage.kind !== "file" || !this.images.isOffloaded(entry.id)) return entry;
|
|
25515
25587
|
return this.images.original(this.storage.file, entry);
|
|
25516
25588
|
}
|
|
25589
|
+
/** 接上(或换掉)告警出口(图片读不回等);`open()` 期间缓冲的告警随即按序冲出(#183)。 */
|
|
25590
|
+
setWarn(warn2) {
|
|
25591
|
+
this.warn = warn2;
|
|
25592
|
+
this.images.setWarn(warn2);
|
|
25593
|
+
}
|
|
25517
25594
|
/** 已卸载图片的条目数(测试与诊断用)。 */
|
|
25518
25595
|
offloadedCount() {
|
|
25519
25596
|
return this.images.size;
|
|
@@ -25626,6 +25703,9 @@ var init_manager = __esm({
|
|
|
25626
25703
|
});
|
|
25627
25704
|
|
|
25628
25705
|
// src/agent/subagent-fork.ts
|
|
25706
|
+
function forkRatio(ratio) {
|
|
25707
|
+
return ratio !== void 0 && Number.isFinite(ratio) && ratio > 0 && ratio < 1 ? ratio : FORK_MAX_CONTEXT_RATIO;
|
|
25708
|
+
}
|
|
25629
25709
|
function requestedContext(request, agent) {
|
|
25630
25710
|
return request.context ?? agent.context ?? "fresh";
|
|
25631
25711
|
}
|
|
@@ -25637,7 +25717,7 @@ function forkPoint(branch, parentToolCallId) {
|
|
|
25637
25717
|
);
|
|
25638
25718
|
return index2 > 0 ? branch[index2 - 1]?.id : void 0;
|
|
25639
25719
|
}
|
|
25640
|
-
function forkPlan(parent, spec2, model, thinking) {
|
|
25720
|
+
function forkPlan(parent, spec2, model, thinking, ratio) {
|
|
25641
25721
|
const base4 = parent.childBase();
|
|
25642
25722
|
if (model.provider !== base4.model.provider || model.id !== base4.model.id)
|
|
25643
25723
|
return { fallback: `model ${model.provider}/${model.id} differs from the parent` };
|
|
@@ -25647,7 +25727,7 @@ function forkPlan(parent, spec2, model, thinking) {
|
|
|
25647
25727
|
if (last === void 0) return { fallback: "the parent has not sent a request yet" };
|
|
25648
25728
|
const reserve = parent.options.compaction?.reserveTokens ?? DEFAULT_COMPACTION_SETTINGS.reserveTokens;
|
|
25649
25729
|
const window2 = model.contextWindow;
|
|
25650
|
-
const limit = window2 === void 0 ? Infinity :
|
|
25730
|
+
const limit = window2 === void 0 ? Infinity : forkRatio(ratio) * Math.max(0, window2 - reserve);
|
|
25651
25731
|
if (last.promptTokens > limit)
|
|
25652
25732
|
return { fallback: `parent context ${last.promptTokens} tokens exceeds ${Math.floor(limit)}` };
|
|
25653
25733
|
const forkedFrom = forkPoint(parent.manager.branch(), spec2.request.parentToolCallId);
|
|
@@ -25670,12 +25750,17 @@ function forkPlan(parent, spec2, model, thinking) {
|
|
|
25670
25750
|
}
|
|
25671
25751
|
}
|
|
25672
25752
|
});
|
|
25753
|
+
manager.append({
|
|
25754
|
+
type: "custom",
|
|
25755
|
+
customType: FORK_CUSTOM_TYPE,
|
|
25756
|
+
data: { taskLine: taskLine(spec2.request.prompt) }
|
|
25757
|
+
});
|
|
25673
25758
|
return { manager, forkedFrom };
|
|
25674
25759
|
}
|
|
25675
25760
|
function forkBrief(input2) {
|
|
25676
25761
|
const lines2 = [
|
|
25677
25762
|
"<task>",
|
|
25678
|
-
"You are a sub-agent forked from the conversation above at this point. The main agent cannot see your work, only your final reply; do not delegate further. Requests above were for the main agent: do only this task. Instructions in this block take precedence over earlier plans or reminders above."
|
|
25763
|
+
"You are a sub-agent forked from the conversation above at this point. The main agent cannot see your work, only your final reply; do not delegate further. Requests above were for the main agent: do only this task. Instructions in this block take precedence over earlier plans or reminders above. Do not call task or task_ctl."
|
|
25679
25764
|
];
|
|
25680
25765
|
if (input2.worktree !== void 0)
|
|
25681
25766
|
lines2.push(
|
|
@@ -25702,6 +25787,7 @@ var FORK_MAX_CONTEXT_RATIO, TASK_CUSTOM_TYPE2;
|
|
|
25702
25787
|
var init_subagent_fork = __esm({
|
|
25703
25788
|
"src/agent/subagent-fork.ts"() {
|
|
25704
25789
|
"use strict";
|
|
25790
|
+
init_task();
|
|
25705
25791
|
init_session_compaction();
|
|
25706
25792
|
FORK_MAX_CONTEXT_RATIO = 0.5;
|
|
25707
25793
|
TASK_CUSTOM_TYPE2 = "ama.task";
|
|
@@ -26613,9 +26699,15 @@ function runningResult(record3, text, outputFile) {
|
|
|
26613
26699
|
status: "running"
|
|
26614
26700
|
};
|
|
26615
26701
|
if (outputFile !== void 0) result.outputFile = outputFile;
|
|
26702
|
+
if (record3.info.context !== void 0) result.context = record3.info.context;
|
|
26616
26703
|
return result;
|
|
26617
26704
|
}
|
|
26618
|
-
function startedResult(record3, outputFile) {
|
|
26705
|
+
async function startedResult(record3, outputFile, settle) {
|
|
26706
|
+
if (settle !== void 0)
|
|
26707
|
+
await Promise.race([
|
|
26708
|
+
settle.catch(() => void 0),
|
|
26709
|
+
new Promise((resolve41) => setImmediate(resolve41))
|
|
26710
|
+
]);
|
|
26619
26711
|
return runningResult(record3, startedText(record3.info.taskId, record3.agent.name), outputFile);
|
|
26620
26712
|
}
|
|
26621
26713
|
function backgroundedResult(record3, reason, afterMs, outputFile) {
|
|
@@ -26997,7 +27089,7 @@ var init_subagent_registry = __esm({
|
|
|
26997
27089
|
const file = this.outputFileFor(record3.info.taskId);
|
|
26998
27090
|
if (background) {
|
|
26999
27091
|
void running.then((result) => this.notifier.notify(record3, result));
|
|
27000
|
-
return
|
|
27092
|
+
return startedResult(record3, file, running);
|
|
27001
27093
|
}
|
|
27002
27094
|
const { waiter, promise } = foregroundWaiter(() => {
|
|
27003
27095
|
clearTimeout(timer);
|
|
@@ -27302,7 +27394,8 @@ async function startAmaChild(parent, spec2, createChild, run7) {
|
|
|
27302
27394
|
}
|
|
27303
27395
|
const thinkingLevel = spec2.request.thinkingLevel ?? spec2.agent.thinking ?? base4.thinkingLevel ?? "off";
|
|
27304
27396
|
const wanted = spec2.resumeFile === void 0 && requestedContext(spec2.request, spec2.agent) === "fork";
|
|
27305
|
-
const
|
|
27397
|
+
const ratio = subagentRegistryFor(parent).env.modelConfig?.subagents?.forkMaxContextRatio;
|
|
27398
|
+
const plan2 = wanted ? forkPlan(parent, spec2, model, thinkingLevel, ratio) : void 0;
|
|
27306
27399
|
if (plan2 !== void 0 && "fallback" in plan2)
|
|
27307
27400
|
parent.log("info", `task ${spec2.taskId}: fork falls back to fresh (${plan2.fallback})`);
|
|
27308
27401
|
const forked = plan2 !== void 0 && "manager" in plan2 ? plan2.manager : void 0;
|
|
@@ -27315,6 +27408,10 @@ async function startAmaChild(parent, spec2, createChild, run7) {
|
|
|
27315
27408
|
const unavailable = inherited.filter(
|
|
27316
27409
|
(name) => !allowed.includes(name) && !PARENT_ONLY_TOOLS.includes(name)
|
|
27317
27410
|
);
|
|
27411
|
+
const briefUnavailable = [
|
|
27412
|
+
...unavailable,
|
|
27413
|
+
...PARENT_ONLY_TOOLS.filter((name) => inherited.includes(name))
|
|
27414
|
+
];
|
|
27318
27415
|
const options = {
|
|
27319
27416
|
...parent.options,
|
|
27320
27417
|
...base4,
|
|
@@ -27403,7 +27500,7 @@ async function startAmaChild(parent, spec2, createChild, run7) {
|
|
|
27403
27500
|
const first = forked === void 0 ? run7.prompt : forkBrief({
|
|
27404
27501
|
prompt: run7.prompt,
|
|
27405
27502
|
role: spec2.agent.prompt,
|
|
27406
|
-
unavailable,
|
|
27503
|
+
unavailable: briefUnavailable,
|
|
27407
27504
|
...spec2.isolated ? { worktree: { cwd: spec2.cwd, parentCwd: parent.cwd } } : {}
|
|
27408
27505
|
});
|
|
27409
27506
|
let current3 = runOnce(first, spec2.origin);
|
|
@@ -27631,6 +27728,7 @@ var init_session_extensions = __esm({
|
|
|
27631
27728
|
if (extension !== void 0) list5.push(extension);
|
|
27632
27729
|
}
|
|
27633
27730
|
this.list = list5;
|
|
27731
|
+
core.manager.setWarn((message) => core.log("warn", message));
|
|
27634
27732
|
}
|
|
27635
27733
|
get size() {
|
|
27636
27734
|
return this.list.length;
|
|
@@ -30292,7 +30390,7 @@ async function readSmall2(path) {
|
|
|
30292
30390
|
return void 0;
|
|
30293
30391
|
}
|
|
30294
30392
|
}
|
|
30295
|
-
var import_node_child_process7, import_node_crypto10, import_promises16, import_node_os10, import_node_path51, SHADOW_DIR, SHADOW_MAX_FILES, SHADOW_MAX_SNAPSHOT_MS, GIT_TIMEOUT_MS, CONFIG_VERSION, IDENTITY, ATTRIBUTES, GitMissingError, MODE_ABSENT, MODE_SYMLINK, MODE_GITLINK, MODE_EXECUTABLE, queues2, ShadowRepo;
|
|
30393
|
+
var import_node_child_process7, import_node_crypto10, import_promises16, import_node_os10, import_node_path51, SHADOW_DIR, SHADOW_MAX_FILES, SHADOW_MAX_SNAPSHOT_MS, SHADOW_SLOW_STREAK, GIT_TIMEOUT_MS, CONFIG_VERSION, IDENTITY, ATTRIBUTES, GitMissingError, MODE_ABSENT, MODE_SYMLINK, MODE_GITLINK, MODE_EXECUTABLE, queues2, ShadowRepo;
|
|
30296
30394
|
var init_shadow_git = __esm({
|
|
30297
30395
|
"src/checkpoints/shadow-git.ts"() {
|
|
30298
30396
|
"use strict";
|
|
@@ -30306,6 +30404,7 @@ var init_shadow_git = __esm({
|
|
|
30306
30404
|
SHADOW_DIR = "shadow";
|
|
30307
30405
|
SHADOW_MAX_FILES = 2e4;
|
|
30308
30406
|
SHADOW_MAX_SNAPSHOT_MS = 3e3;
|
|
30407
|
+
SHADOW_SLOW_STREAK = 2;
|
|
30309
30408
|
GIT_TIMEOUT_MS = 6e4;
|
|
30310
30409
|
CONFIG_VERSION = "1";
|
|
30311
30410
|
IDENTITY = { name: "ama", email: "ama@localhost" };
|
|
@@ -30331,6 +30430,8 @@ var init_shadow_git = __esm({
|
|
|
30331
30430
|
indexFile;
|
|
30332
30431
|
initialized;
|
|
30333
30432
|
counted = false;
|
|
30433
|
+
/** 连续超时的快照数(首次快照不计),到 `SHADOW_SLOW_STREAK` 才降级。 */
|
|
30434
|
+
slowStreak = 0;
|
|
30334
30435
|
constructor(dataDir, cwd, options = {}) {
|
|
30335
30436
|
this.cwd = (0, import_node_path51.resolve)(cwd);
|
|
30336
30437
|
this.dir = shadowRepoDir(dataDir, this.cwd);
|
|
@@ -30450,6 +30551,7 @@ var init_shadow_git = __esm({
|
|
|
30450
30551
|
return exclusive(this.dir, async () => {
|
|
30451
30552
|
await this.init();
|
|
30452
30553
|
const started = this.now();
|
|
30554
|
+
const first = !this.counted;
|
|
30453
30555
|
await this.writeExcludes();
|
|
30454
30556
|
if (!this.counted) {
|
|
30455
30557
|
const out = await this.run([
|
|
@@ -30475,7 +30577,9 @@ var init_shadow_git = __esm({
|
|
|
30475
30577
|
if (parent !== void 0 && await this.hasCommitUnlocked(parent)) args.push("-p", parent);
|
|
30476
30578
|
const commit = await this.text(args);
|
|
30477
30579
|
const elapsed = this.now() - started;
|
|
30478
|
-
if (
|
|
30580
|
+
if (first) return { commit };
|
|
30581
|
+
this.slowStreak = elapsed > this.maxSnapshotMs ? this.slowStreak + 1 : 0;
|
|
30582
|
+
if (this.slowStreak >= SHADOW_SLOW_STREAK) {
|
|
30479
30583
|
return {
|
|
30480
30584
|
commit,
|
|
30481
30585
|
degrade: {
|
|
@@ -31390,7 +31494,9 @@ function openSession(request, context) {
|
|
|
31390
31494
|
return file === void 0 ? SessionManager.create(dir, cwd, { id: request.id }) : SessionManager.open(file);
|
|
31391
31495
|
}
|
|
31392
31496
|
case "fork": {
|
|
31393
|
-
const source = SessionManager.open(requireFile(root, request.id, cwd)
|
|
31497
|
+
const source = SessionManager.open(requireFile(root, request.id, cwd), {
|
|
31498
|
+
warn: (message) => context.log?.("warn", message)
|
|
31499
|
+
});
|
|
31394
31500
|
try {
|
|
31395
31501
|
const leaf = source.leafId();
|
|
31396
31502
|
if (leaf === null)
|
|
@@ -31406,9 +31512,9 @@ function listSessions(context) {
|
|
|
31406
31512
|
const dirs = context.cwd === void 0 ? cwdDirs(context.sessionDir) : [sessionDirForCwd(context.sessionDir, context.cwd)];
|
|
31407
31513
|
return dirs.flatMap((dir) => SessionManager.list(dir)).filter((item) => context.includeSubagents === true || item.subagent !== true).sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt));
|
|
31408
31514
|
}
|
|
31409
|
-
function createSessionStore() {
|
|
31515
|
+
function createSessionStore(log) {
|
|
31410
31516
|
return {
|
|
31411
|
-
open: (request, context) => openSession(request, context),
|
|
31517
|
+
open: (request, context) => openSession(request, { ...context, log }),
|
|
31412
31518
|
list: async (context) => listSessions(context),
|
|
31413
31519
|
show: async (id, context) => {
|
|
31414
31520
|
const file = requireFile(context.sessionDir, id);
|
|
@@ -33124,6 +33230,16 @@ function candidateCapabilities(c) {
|
|
|
33124
33230
|
usage: "tokens",
|
|
33125
33231
|
images: false
|
|
33126
33232
|
};
|
|
33233
|
+
case "pi-rpc":
|
|
33234
|
+
return {
|
|
33235
|
+
resume: "resume",
|
|
33236
|
+
list: false,
|
|
33237
|
+
permissions: "interactive",
|
|
33238
|
+
steer: true,
|
|
33239
|
+
modes: ALL_MODES,
|
|
33240
|
+
usage: "usd",
|
|
33241
|
+
images: true
|
|
33242
|
+
};
|
|
33127
33243
|
case "oneshot":
|
|
33128
33244
|
return {
|
|
33129
33245
|
resume: c.oneshot === "gemini" ? "none" : "resume",
|
|
@@ -33147,7 +33263,7 @@ function candidateCapabilities(c) {
|
|
|
33147
33263
|
};
|
|
33148
33264
|
}
|
|
33149
33265
|
}
|
|
33150
|
-
var ALL_MODES, DRIVER_CATALOG;
|
|
33266
|
+
var ALL_MODES, CLAUDE_ACP_MODES, CODEX_ACP_MODES, COPILOT_MODE, COPILOT_MODES, CURSOR_MODES, DRIVER_CATALOG;
|
|
33151
33267
|
var init_catalog4 = __esm({
|
|
33152
33268
|
"src/drivers/catalog.ts"() {
|
|
33153
33269
|
"use strict";
|
|
@@ -33159,12 +33275,48 @@ var init_catalog4 = __esm({
|
|
|
33159
33275
|
"auto",
|
|
33160
33276
|
"full-auto"
|
|
33161
33277
|
];
|
|
33278
|
+
CLAUDE_ACP_MODES = {
|
|
33279
|
+
plan: "plan",
|
|
33280
|
+
default: "default",
|
|
33281
|
+
"auto-edit": "acceptEdits",
|
|
33282
|
+
auto: "auto",
|
|
33283
|
+
"full-auto": "auto"
|
|
33284
|
+
};
|
|
33285
|
+
CODEX_ACP_MODES = {
|
|
33286
|
+
plan: "read-only",
|
|
33287
|
+
default: "read-only",
|
|
33288
|
+
"auto-edit": "workspace-write",
|
|
33289
|
+
auto: "agent",
|
|
33290
|
+
"full-auto": "agent"
|
|
33291
|
+
};
|
|
33292
|
+
COPILOT_MODE = "https://agentclientprotocol.com/protocol/session-modes#";
|
|
33293
|
+
COPILOT_MODES = {
|
|
33294
|
+
plan: `${COPILOT_MODE}plan`,
|
|
33295
|
+
default: `${COPILOT_MODE}agent`,
|
|
33296
|
+
"auto-edit": `${COPILOT_MODE}agent`,
|
|
33297
|
+
auto: `${COPILOT_MODE}agent`,
|
|
33298
|
+
"full-auto": `${COPILOT_MODE}agent`
|
|
33299
|
+
};
|
|
33300
|
+
CURSOR_MODES = {
|
|
33301
|
+
plan: "plan",
|
|
33302
|
+
default: "agent",
|
|
33303
|
+
"auto-edit": "agent",
|
|
33304
|
+
auto: "agent",
|
|
33305
|
+
"full-auto": "agent"
|
|
33306
|
+
};
|
|
33162
33307
|
DRIVER_CATALOG = [
|
|
33163
33308
|
{
|
|
33164
33309
|
agentId: "claude",
|
|
33165
33310
|
label: "Claude Code",
|
|
33166
33311
|
candidates: [
|
|
33167
|
-
{
|
|
33312
|
+
{
|
|
33313
|
+
kind: "acp-adapter",
|
|
33314
|
+
program: "claude-agent-acp",
|
|
33315
|
+
args: [],
|
|
33316
|
+
verified: ">=0.89.0 <1.0.0",
|
|
33317
|
+
usage: "usd",
|
|
33318
|
+
modes: CLAUDE_ACP_MODES
|
|
33319
|
+
},
|
|
33168
33320
|
{
|
|
33169
33321
|
kind: "claude-stream",
|
|
33170
33322
|
program: "claude",
|
|
@@ -33179,7 +33331,14 @@ var init_catalog4 = __esm({
|
|
|
33179
33331
|
agentId: "codex",
|
|
33180
33332
|
label: "Codex",
|
|
33181
33333
|
candidates: [
|
|
33182
|
-
{
|
|
33334
|
+
{
|
|
33335
|
+
kind: "acp-adapter",
|
|
33336
|
+
program: "codex-acp",
|
|
33337
|
+
args: [],
|
|
33338
|
+
verified: ">=2.2.0 <3.0.0",
|
|
33339
|
+
usage: "tokens",
|
|
33340
|
+
modes: CODEX_ACP_MODES
|
|
33341
|
+
},
|
|
33183
33342
|
{
|
|
33184
33343
|
kind: "codex-app-server",
|
|
33185
33344
|
program: "codex",
|
|
@@ -33212,15 +33371,44 @@ var init_catalog4 = __esm({
|
|
|
33212
33371
|
{
|
|
33213
33372
|
agentId: "opencode",
|
|
33214
33373
|
label: "OpenCode",
|
|
33215
|
-
candidates: [{ kind: "acp", program: "opencode", args: ["acp"] }]
|
|
33374
|
+
candidates: [{ kind: "acp", program: "opencode", args: ["acp"], verified: ">=1.18.0 <2.0.0" }]
|
|
33216
33375
|
},
|
|
33217
33376
|
{
|
|
33218
33377
|
agentId: "copilot",
|
|
33219
33378
|
label: "GitHub Copilot CLI",
|
|
33220
33379
|
candidates: [
|
|
33221
|
-
{
|
|
33380
|
+
{
|
|
33381
|
+
kind: "acp",
|
|
33382
|
+
program: "copilot",
|
|
33383
|
+
args: ["--acp", "--stdio"],
|
|
33384
|
+
verified: ">=1.0.95 <2.0.0",
|
|
33385
|
+
usage: "requests",
|
|
33386
|
+
modes: COPILOT_MODES,
|
|
33387
|
+
acpUsage: "session"
|
|
33388
|
+
}
|
|
33389
|
+
]
|
|
33390
|
+
},
|
|
33391
|
+
{
|
|
33392
|
+
agentId: "pi",
|
|
33393
|
+
label: "Pi",
|
|
33394
|
+
// 社区 ACP 适配器 pi-acp 不发 request_permission(pi 没有审批通道),会让工具不经人直接执行,不收录
|
|
33395
|
+
candidates: [
|
|
33396
|
+
{
|
|
33397
|
+
kind: "pi-rpc",
|
|
33398
|
+
program: "pi",
|
|
33399
|
+
args: ["--mode", "rpc"],
|
|
33400
|
+
verified: ">=1.1.0 <2.0.0",
|
|
33401
|
+
usage: "usd"
|
|
33402
|
+
}
|
|
33222
33403
|
]
|
|
33223
33404
|
},
|
|
33405
|
+
{
|
|
33406
|
+
agentId: "cursor",
|
|
33407
|
+
label: "Cursor CLI",
|
|
33408
|
+
// 未实测(本机未装):按官方文档 `cursor-agent acp`,模式 agent / plan / ask;`cursor/ask_question`
|
|
33409
|
+
// 等阻塞式扩展方法 ama 不实现(回 method not found,不代答)
|
|
33410
|
+
candidates: [{ kind: "acp", program: "cursor-agent", args: ["acp"], modes: CURSOR_MODES }]
|
|
33411
|
+
},
|
|
33224
33412
|
{
|
|
33225
33413
|
agentId: "goose",
|
|
33226
33414
|
label: "Goose",
|
|
@@ -33942,6 +34130,24 @@ function pushAcpUpdate(update, turn) {
|
|
|
33942
34130
|
return;
|
|
33943
34131
|
}
|
|
33944
34132
|
}
|
|
34133
|
+
function acpTurnUsage(usage, previous) {
|
|
34134
|
+
const diff = (key) => {
|
|
34135
|
+
const now = usage[key];
|
|
34136
|
+
if (now === void 0) return void 0;
|
|
34137
|
+
return previous === void 0 ? now : Math.max(0, now - (previous[key] ?? 0));
|
|
34138
|
+
};
|
|
34139
|
+
const input2 = diff("inputTokens");
|
|
34140
|
+
const output = diff("outputTokens");
|
|
34141
|
+
const cacheRead = diff("cachedReadTokens");
|
|
34142
|
+
const { totalTokens: total, inputTokens: rawIn = 0, outputTokens: rawOut = 0 } = usage;
|
|
34143
|
+
const cached = usage.cachedReadTokens ?? 0;
|
|
34144
|
+
const includesCache = total !== void 0 && cached > 0 && Math.abs(total - (rawIn + rawOut)) < Math.abs(total - (rawIn + rawOut + cached));
|
|
34145
|
+
return {
|
|
34146
|
+
...input2 !== void 0 ? { input: includesCache ? Math.max(0, input2 - (cacheRead ?? 0)) : input2 } : {},
|
|
34147
|
+
...output !== void 0 ? { output } : {},
|
|
34148
|
+
...cacheRead !== void 0 ? { cacheRead } : {}
|
|
34149
|
+
};
|
|
34150
|
+
}
|
|
33945
34151
|
function wantedModeIds(mode, candidate) {
|
|
33946
34152
|
const wanted = [candidate.modes?.[mode] ?? mode];
|
|
33947
34153
|
if (mode === "allowlist") wanted.push(candidate.modes?.plan ?? "plan");
|
|
@@ -33962,6 +34168,14 @@ function pickConfigModeValue(mode, candidate, option2) {
|
|
|
33962
34168
|
);
|
|
33963
34169
|
return wantedModeIds(mode, candidate).find((id) => values.includes(id));
|
|
33964
34170
|
}
|
|
34171
|
+
function pickModelValue(model, options) {
|
|
34172
|
+
const option2 = options?.find((o) => o.category === "model" && o.type === "select");
|
|
34173
|
+
if (option2 === void 0) return void 0;
|
|
34174
|
+
const values = option2.options.flatMap((o) => "options" in o ? o.options : [o]);
|
|
34175
|
+
const lower = model.toLowerCase();
|
|
34176
|
+
const hit = values.find((v) => v.value === model) ?? values.find((v) => v.value.toLowerCase() === lower || v.name.toLowerCase() === lower) ?? values.find((v) => v.value.toLowerCase().split("/").at(-1) === lower);
|
|
34177
|
+
return hit === void 0 ? void 0 : { configId: option2.id, value: hit.value, current: option2.currentValue === hit.value };
|
|
34178
|
+
}
|
|
33965
34179
|
function authMethodText(method, command3) {
|
|
33966
34180
|
if (method.type !== "terminal") return method.name;
|
|
33967
34181
|
const words = [...command3, ...method.args ?? []].map(
|
|
@@ -34048,6 +34262,9 @@ var init_driver = __esm({
|
|
|
34048
34262
|
notices = [];
|
|
34049
34263
|
/** 本回合已发过 cancel。 */
|
|
34050
34264
|
cancelling = false;
|
|
34265
|
+
/** Agent 的 usage 是会话累计时,上一回合的原始值({@link acpTurnUsage})。 */
|
|
34266
|
+
usageTotals;
|
|
34267
|
+
cumulativeUsage = false;
|
|
34051
34268
|
get sessionId() {
|
|
34052
34269
|
return this.id;
|
|
34053
34270
|
}
|
|
@@ -34062,6 +34279,7 @@ var init_driver = __esm({
|
|
|
34062
34279
|
onProtocolError: (_line, reason) => this.deps.log?.("debug", `${this.agentId}: ${reason}`)
|
|
34063
34280
|
});
|
|
34064
34281
|
const signal = options.signal;
|
|
34282
|
+
this.cumulativeUsage = candidate.acpUsage === "session";
|
|
34065
34283
|
await this.client.initialize(signal);
|
|
34066
34284
|
let opened;
|
|
34067
34285
|
try {
|
|
@@ -34088,6 +34306,13 @@ var init_driver = __esm({
|
|
|
34088
34306
|
} else if (modes != null || modeOption !== void 0) {
|
|
34089
34307
|
this.notices.push(msg().drivers.agent.noMatchingMode(this.agentId, options.mode));
|
|
34090
34308
|
}
|
|
34309
|
+
if (options.model !== void 0) {
|
|
34310
|
+
const model = pickModelValue(options.model, opened.configOptions);
|
|
34311
|
+
if (model === void 0)
|
|
34312
|
+
this.notices.push(msg().drivers.agent.noMatchingModel(this.agentId, options.model));
|
|
34313
|
+
else if (!model.current)
|
|
34314
|
+
await this.client.setConfigOption(this.id, model.configId, model.value);
|
|
34315
|
+
}
|
|
34091
34316
|
}
|
|
34092
34317
|
/** 续聊优先 resume(不回放),其次 load(回放丢弃),都不行就新开;设好 `this.id`。 */
|
|
34093
34318
|
async openSession(options) {
|
|
@@ -34148,11 +34373,10 @@ var init_driver = __esm({
|
|
|
34148
34373
|
});
|
|
34149
34374
|
const usage = result.usage;
|
|
34150
34375
|
if (usage != null) {
|
|
34151
|
-
turn.mergeUsage(
|
|
34152
|
-
|
|
34153
|
-
|
|
34154
|
-
|
|
34155
|
-
});
|
|
34376
|
+
turn.mergeUsage(
|
|
34377
|
+
acpTurnUsage(usage, this.cumulativeUsage ? this.usageTotals ?? {} : void 0)
|
|
34378
|
+
);
|
|
34379
|
+
if (this.cumulativeUsage) this.usageTotals = usage;
|
|
34156
34380
|
}
|
|
34157
34381
|
return turn.result(result.stopReason);
|
|
34158
34382
|
} finally {
|
|
@@ -34261,6 +34485,26 @@ function claudePermissionMode(mode, manualName) {
|
|
|
34261
34485
|
return "auto";
|
|
34262
34486
|
}
|
|
34263
34487
|
}
|
|
34488
|
+
function claudeContextTokens(usage) {
|
|
34489
|
+
if (typeof usage !== "object" || usage === null) return void 0;
|
|
34490
|
+
const u = usage;
|
|
34491
|
+
let total = 0;
|
|
34492
|
+
for (const key of [
|
|
34493
|
+
"input_tokens",
|
|
34494
|
+
"cache_read_input_tokens",
|
|
34495
|
+
"cache_creation_input_tokens",
|
|
34496
|
+
"output_tokens"
|
|
34497
|
+
])
|
|
34498
|
+
if (typeof u[key] === "number") total += u[key];
|
|
34499
|
+
return total > 0 ? total : void 0;
|
|
34500
|
+
}
|
|
34501
|
+
function claudeContextWindow(result, model) {
|
|
34502
|
+
const entries = result.modelUsage ?? {};
|
|
34503
|
+
const hit = model !== void 0 ? entries[model]?.contextWindow : void 0;
|
|
34504
|
+
if (typeof hit === "number" && hit > 0) return hit;
|
|
34505
|
+
const windows = Object.values(entries).map((e) => e.contextWindow).filter((w) => typeof w === "number" && w > 0);
|
|
34506
|
+
return windows.length > 0 ? Math.max(...windows) : void 0;
|
|
34507
|
+
}
|
|
34264
34508
|
function claudeStopReason(result, interrupted) {
|
|
34265
34509
|
if (interrupted) return "cancelled";
|
|
34266
34510
|
switch (result.subtype) {
|
|
@@ -34421,6 +34665,8 @@ var init_claude_stream = __esm({
|
|
|
34421
34665
|
interrupted = false;
|
|
34422
34666
|
sawPartialText = false;
|
|
34423
34667
|
lastTotalCost = 0;
|
|
34668
|
+
/** 最近一条主线 assistant 消息的上下文占用与模型(result 里查窗口用)。 */
|
|
34669
|
+
context = {};
|
|
34424
34670
|
closed = false;
|
|
34425
34671
|
exited = false;
|
|
34426
34672
|
get sessionId() {
|
|
@@ -34512,6 +34758,13 @@ var init_claude_stream = __esm({
|
|
|
34512
34758
|
...u.cache_read_input_tokens !== void 0 ? { cacheRead: u.cache_read_input_tokens } : {},
|
|
34513
34759
|
...cost2 !== void 0 ? { costUsd: cost2 } : {}
|
|
34514
34760
|
});
|
|
34761
|
+
const window2 = claudeContextWindow(result, this.context.model);
|
|
34762
|
+
if (this.context.tokens !== void 0 || window2 !== void 0)
|
|
34763
|
+
turn.push({
|
|
34764
|
+
type: "usage",
|
|
34765
|
+
...this.context.tokens !== void 0 ? { contextTokens: this.context.tokens } : {},
|
|
34766
|
+
...window2 !== void 0 ? { contextWindow: window2 } : {}
|
|
34767
|
+
});
|
|
34515
34768
|
if (typeof result.result === "string" && result.result !== "") turn.setFinalText(result.result);
|
|
34516
34769
|
const denials = result.permission_denials?.length ?? 0;
|
|
34517
34770
|
if (denials > 0)
|
|
@@ -34629,6 +34882,12 @@ var init_claude_stream = __esm({
|
|
|
34629
34882
|
const turn = this.turn;
|
|
34630
34883
|
if (turn === void 0 || !Array.isArray(message["content"])) return;
|
|
34631
34884
|
const nested = typeof parent === "string" && parent !== "";
|
|
34885
|
+
const tokens = nested ? void 0 : claudeContextTokens(message["usage"]);
|
|
34886
|
+
if (tokens !== void 0)
|
|
34887
|
+
this.context = {
|
|
34888
|
+
tokens,
|
|
34889
|
+
...typeof message["model"] === "string" ? { model: message["model"] } : {}
|
|
34890
|
+
};
|
|
34632
34891
|
for (const block of message["content"]) {
|
|
34633
34892
|
if (block["type"] === "text" && !nested && !this.sawPartialText && typeof block["text"] === "string")
|
|
34634
34893
|
turn.push({ type: "message_delta", text: block["text"] });
|
|
@@ -35078,11 +35337,12 @@ var init_codex_app_server = __esm({
|
|
|
35078
35337
|
const start = this.tokensAtStart;
|
|
35079
35338
|
const end = this.tokensTotal;
|
|
35080
35339
|
if (end !== void 0) {
|
|
35340
|
+
const cacheRead = end.cachedInputTokens - (start?.cachedInputTokens ?? 0);
|
|
35081
35341
|
turn.push({
|
|
35082
35342
|
type: "usage",
|
|
35083
|
-
input: end.inputTokens - (start?.inputTokens ?? 0),
|
|
35343
|
+
input: end.inputTokens - (start?.inputTokens ?? 0) - cacheRead,
|
|
35084
35344
|
output: end.outputTokens - (start?.outputTokens ?? 0),
|
|
35085
|
-
cacheRead
|
|
35345
|
+
cacheRead,
|
|
35086
35346
|
...this.contextTokens !== void 0 ? { contextTokens: this.contextTokens } : {},
|
|
35087
35347
|
...this.contextWindow !== void 0 ? { contextWindow: this.contextWindow } : {}
|
|
35088
35348
|
});
|
|
@@ -35277,7 +35537,14 @@ function oneshotArgs(dialect, options, session, prompt) {
|
|
|
35277
35537
|
return args;
|
|
35278
35538
|
}
|
|
35279
35539
|
case "codex": {
|
|
35280
|
-
const common = [
|
|
35540
|
+
const common = [
|
|
35541
|
+
"--json",
|
|
35542
|
+
"--skip-git-repo-check",
|
|
35543
|
+
"-c",
|
|
35544
|
+
'sandbox_mode="read-only"',
|
|
35545
|
+
"-c",
|
|
35546
|
+
'approval_policy="never"'
|
|
35547
|
+
];
|
|
35281
35548
|
if (options.model !== void 0) common.push("-m", options.model);
|
|
35282
35549
|
return session.resume ? ["exec", "resume", session.id, ...common, "-"] : ["exec", ...common, "-"];
|
|
35283
35550
|
}
|
|
@@ -35497,9 +35764,10 @@ ${item["text"]}`
|
|
|
35497
35764
|
}
|
|
35498
35765
|
case "turn.completed": {
|
|
35499
35766
|
const u = msg2["usage"] ?? {};
|
|
35767
|
+
const input2 = u["input_tokens"];
|
|
35500
35768
|
turn.push({
|
|
35501
35769
|
type: "usage",
|
|
35502
|
-
...
|
|
35770
|
+
...input2 !== void 0 ? { input: input2 - (u["cached_input_tokens"] ?? 0) } : {},
|
|
35503
35771
|
...u["output_tokens"] !== void 0 ? { output: u["output_tokens"] } : {},
|
|
35504
35772
|
...u["cached_input_tokens"] !== void 0 ? { cacheRead: u["cached_input_tokens"] } : {}
|
|
35505
35773
|
});
|
|
@@ -35563,13 +35831,516 @@ ${item["text"]}`
|
|
|
35563
35831
|
}
|
|
35564
35832
|
});
|
|
35565
35833
|
|
|
35834
|
+
// src/drivers/native/pi-gate.ts
|
|
35835
|
+
function writePiGate() {
|
|
35836
|
+
const dir = (0, import_node_fs41.mkdtempSync)((0, import_node_path60.join)((0, import_node_os11.tmpdir)(), "ama-pi-"));
|
|
35837
|
+
const path = (0, import_node_path60.join)(dir, "ama-approval-gate.ts");
|
|
35838
|
+
(0, import_node_fs41.writeFileSync)(path, PI_GATE_SOURCE, { mode: 384 });
|
|
35839
|
+
return {
|
|
35840
|
+
path,
|
|
35841
|
+
dispose: () => (0, import_node_fs41.rmSync)(dir, { recursive: true, force: true })
|
|
35842
|
+
};
|
|
35843
|
+
}
|
|
35844
|
+
var import_node_fs41, import_node_os11, import_node_path60, PI_GATE_TITLE, PI_READ_ONLY_TOOLS, PI_GATE_SOURCE;
|
|
35845
|
+
var init_pi_gate = __esm({
|
|
35846
|
+
"src/drivers/native/pi-gate.ts"() {
|
|
35847
|
+
"use strict";
|
|
35848
|
+
import_node_fs41 = require("node:fs");
|
|
35849
|
+
import_node_os11 = require("node:os");
|
|
35850
|
+
import_node_path60 = require("node:path");
|
|
35851
|
+
PI_GATE_TITLE = "ama-approval";
|
|
35852
|
+
PI_READ_ONLY_TOOLS = ["read", "grep", "find", "ls"];
|
|
35853
|
+
PI_GATE_SOURCE = `// Generated by ama for one pi run: routes non-read-only tool calls to ama for approval.
|
|
35854
|
+
const READ_ONLY = new Set(${JSON.stringify(PI_READ_ONLY_TOOLS)});
|
|
35855
|
+
export default function (pi) {
|
|
35856
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
35857
|
+
if (READ_ONLY.has(event.toolName)) return undefined;
|
|
35858
|
+
const ok = await ctx.ui.confirm(
|
|
35859
|
+
${JSON.stringify(PI_GATE_TITLE)},
|
|
35860
|
+
JSON.stringify({ id: event.toolCallId, tool: event.toolName, input: event.input }),
|
|
35861
|
+
);
|
|
35862
|
+
return ok ? undefined : { block: true, reason: event.toolName + " was not approved by the user" };
|
|
35863
|
+
});
|
|
35864
|
+
}
|
|
35865
|
+
`;
|
|
35866
|
+
}
|
|
35867
|
+
});
|
|
35868
|
+
|
|
35869
|
+
// src/drivers/native/pi-rpc.ts
|
|
35870
|
+
function piArgs(options, sessionId, gatePath) {
|
|
35871
|
+
const args = ["--session-id", sessionId];
|
|
35872
|
+
if (options.model !== void 0) args.push("--model", options.model);
|
|
35873
|
+
args.push("-e", gatePath);
|
|
35874
|
+
if (isReadOnlyMode(options.mode)) args.push("--tools", PI_READ_ONLY_TOOLS.join(","));
|
|
35875
|
+
return args;
|
|
35876
|
+
}
|
|
35877
|
+
function piToolKind(tool) {
|
|
35878
|
+
switch (tool) {
|
|
35879
|
+
case "bash":
|
|
35880
|
+
case "powershell":
|
|
35881
|
+
return "execute";
|
|
35882
|
+
case "edit":
|
|
35883
|
+
case "write":
|
|
35884
|
+
return "edit";
|
|
35885
|
+
case "read":
|
|
35886
|
+
return "read";
|
|
35887
|
+
case "grep":
|
|
35888
|
+
case "find":
|
|
35889
|
+
case "ls":
|
|
35890
|
+
return "search";
|
|
35891
|
+
default:
|
|
35892
|
+
return "other";
|
|
35893
|
+
}
|
|
35894
|
+
}
|
|
35895
|
+
function piToolTitle(tool, input2) {
|
|
35896
|
+
if (typeof input2["command"] === "string") return `$ ${oneLine2(input2["command"], 100)}`;
|
|
35897
|
+
if (typeof input2["path"] === "string") return `${tool} ${input2["path"]}`;
|
|
35898
|
+
if (typeof input2["pattern"] === "string") return `${tool} ${oneLine2(input2["pattern"], 80)}`;
|
|
35899
|
+
return tool;
|
|
35900
|
+
}
|
|
35901
|
+
function textOf4(message) {
|
|
35902
|
+
const content = message["content"];
|
|
35903
|
+
if (typeof content === "string") return content;
|
|
35904
|
+
if (!Array.isArray(content)) return "";
|
|
35905
|
+
return content.map((b) => b["type"] === "text" && typeof b["text"] === "string" ? b["text"] : "").join("");
|
|
35906
|
+
}
|
|
35907
|
+
var import_node_crypto14, import_node_path61, DIALOG_METHODS, EDIT_TOOLS, PiRpcDriver, PiSession;
|
|
35908
|
+
var init_pi_rpc = __esm({
|
|
35909
|
+
"src/drivers/native/pi-rpc.ts"() {
|
|
35910
|
+
"use strict";
|
|
35911
|
+
import_node_crypto14 = require("node:crypto");
|
|
35912
|
+
import_node_path61 = require("node:path");
|
|
35913
|
+
init_errors();
|
|
35914
|
+
init_jsonl();
|
|
35915
|
+
init_base();
|
|
35916
|
+
init_process();
|
|
35917
|
+
init_turn();
|
|
35918
|
+
init_pi_gate();
|
|
35919
|
+
init_i18n();
|
|
35920
|
+
DIALOG_METHODS = /* @__PURE__ */ new Set(["select", "confirm", "input", "editor"]);
|
|
35921
|
+
EDIT_TOOLS = /* @__PURE__ */ new Set(["edit", "write"]);
|
|
35922
|
+
PiRpcDriver = class {
|
|
35923
|
+
constructor(agentId, candidate, deps = {}) {
|
|
35924
|
+
this.agentId = agentId;
|
|
35925
|
+
this.candidate = candidate;
|
|
35926
|
+
this.deps = deps;
|
|
35927
|
+
}
|
|
35928
|
+
agentId;
|
|
35929
|
+
candidate;
|
|
35930
|
+
deps;
|
|
35931
|
+
kind = "pi-rpc";
|
|
35932
|
+
probe() {
|
|
35933
|
+
return probeCandidate(this.candidate, this.deps);
|
|
35934
|
+
}
|
|
35935
|
+
async open(options) {
|
|
35936
|
+
const probed = await probeCandidate(this.candidate, this.deps);
|
|
35937
|
+
const sessionId = options.resume ?? (0, import_node_crypto14.randomUUID)();
|
|
35938
|
+
const gate = writePiGate();
|
|
35939
|
+
const transport = spawnOf(this.deps)({
|
|
35940
|
+
program: probed.path ?? this.candidate.program,
|
|
35941
|
+
args: [...this.candidate.args, ...piArgs(options, sessionId, gate.path)],
|
|
35942
|
+
cwd: options.cwd,
|
|
35943
|
+
env: options.env
|
|
35944
|
+
});
|
|
35945
|
+
const session = new PiSession(
|
|
35946
|
+
this.agentId,
|
|
35947
|
+
sessionId,
|
|
35948
|
+
transport,
|
|
35949
|
+
options,
|
|
35950
|
+
this.deps,
|
|
35951
|
+
() => gate.dispose()
|
|
35952
|
+
);
|
|
35953
|
+
if (probed.warning !== void 0) session.notices.push(probed.warning);
|
|
35954
|
+
try {
|
|
35955
|
+
await session.start(options.signal);
|
|
35956
|
+
} catch (error2) {
|
|
35957
|
+
await session.close();
|
|
35958
|
+
throw new AmaError(
|
|
35959
|
+
"agent_start_failed",
|
|
35960
|
+
`${this.agentId}: failed to start (${error2.message})${stderrHint(transport) !== "" ? `: ${stderrHint(transport)}` : ""}`,
|
|
35961
|
+
{ cause: error2 }
|
|
35962
|
+
);
|
|
35963
|
+
}
|
|
35964
|
+
return session;
|
|
35965
|
+
}
|
|
35966
|
+
};
|
|
35967
|
+
PiSession = class {
|
|
35968
|
+
constructor(agentId, id, transport, options, deps, dispose) {
|
|
35969
|
+
this.agentId = agentId;
|
|
35970
|
+
this.id = id;
|
|
35971
|
+
this.transport = transport;
|
|
35972
|
+
this.options = options;
|
|
35973
|
+
this.deps = deps;
|
|
35974
|
+
this.dispose = dispose;
|
|
35975
|
+
createLineReader(
|
|
35976
|
+
transport.stdout,
|
|
35977
|
+
(line2) => this.onLine(line2),
|
|
35978
|
+
() => this.onExit()
|
|
35979
|
+
);
|
|
35980
|
+
transport.stdin.on?.("error", () => void 0);
|
|
35981
|
+
}
|
|
35982
|
+
agentId;
|
|
35983
|
+
id;
|
|
35984
|
+
transport;
|
|
35985
|
+
options;
|
|
35986
|
+
deps;
|
|
35987
|
+
dispose;
|
|
35988
|
+
notices = [];
|
|
35989
|
+
nextId = 1;
|
|
35990
|
+
pending = /* @__PURE__ */ new Map();
|
|
35991
|
+
permissions = /* @__PURE__ */ new Set();
|
|
35992
|
+
turn;
|
|
35993
|
+
hooks;
|
|
35994
|
+
settle;
|
|
35995
|
+
running;
|
|
35996
|
+
usage = { input: 0, output: 0, cacheRead: 0, costUsd: 0, seen: false };
|
|
35997
|
+
lastAssistant;
|
|
35998
|
+
interrupted = false;
|
|
35999
|
+
closed = false;
|
|
36000
|
+
exited = false;
|
|
36001
|
+
exitWaiters = /* @__PURE__ */ new Set();
|
|
36002
|
+
get sessionId() {
|
|
36003
|
+
return this.id;
|
|
36004
|
+
}
|
|
36005
|
+
/** 握手:`get_state` 确认进程起来了,并取 pi 实际使用的会话 id。 */
|
|
36006
|
+
async start(signal) {
|
|
36007
|
+
const aborted = new Promise((_, reject2) => {
|
|
36008
|
+
if (signal.aborted) reject2(new Error("aborted"));
|
|
36009
|
+
signal.addEventListener("abort", () => reject2(new Error("aborted")), { once: true });
|
|
36010
|
+
});
|
|
36011
|
+
void aborted.catch(() => void 0);
|
|
36012
|
+
const state = await Promise.race([this.request({ type: "get_state" }), aborted]);
|
|
36013
|
+
const data2 = state["data"] ?? {};
|
|
36014
|
+
if (typeof data2["sessionId"] === "string" && data2["sessionId"] !== "")
|
|
36015
|
+
this.id = data2["sessionId"];
|
|
36016
|
+
}
|
|
36017
|
+
async prompt(content, hooks) {
|
|
36018
|
+
if (this.closed || this.exited)
|
|
36019
|
+
throw new AmaError("agent_closed", `${this.agentId} session is closed`);
|
|
36020
|
+
if (this.running !== void 0)
|
|
36021
|
+
throw new AmaError("busy", `${this.agentId} is already running`);
|
|
36022
|
+
const turn = new TurnCollector((e) => hooks.onEvent(e));
|
|
36023
|
+
for (const text of this.notices.splice(0)) turn.push({ type: "notice", level: "warn", text });
|
|
36024
|
+
this.turn = turn;
|
|
36025
|
+
this.hooks = hooks;
|
|
36026
|
+
this.interrupted = false;
|
|
36027
|
+
this.usage = { input: 0, output: 0, cacheRead: 0, costUsd: 0, seen: false };
|
|
36028
|
+
this.lastAssistant = void 0;
|
|
36029
|
+
this.running = this.run(content, turn);
|
|
36030
|
+
try {
|
|
36031
|
+
return await this.running;
|
|
36032
|
+
} finally {
|
|
36033
|
+
this.running = void 0;
|
|
36034
|
+
this.turn = void 0;
|
|
36035
|
+
this.hooks = void 0;
|
|
36036
|
+
this.settle = void 0;
|
|
36037
|
+
this.exitWaiters.clear();
|
|
36038
|
+
}
|
|
36039
|
+
}
|
|
36040
|
+
async run(content, turn) {
|
|
36041
|
+
await Promise.resolve();
|
|
36042
|
+
const settled = new Promise((resolve41) => this.settle = resolve41);
|
|
36043
|
+
const response = await this.request({ type: "prompt", ...this.message(content) });
|
|
36044
|
+
if (response["success"] !== true)
|
|
36045
|
+
throw new AmaError(
|
|
36046
|
+
"agent_failed",
|
|
36047
|
+
`${this.agentId} rejected the prompt: ${oneLine2(String(response["error"] ?? "unknown"), 300)}`
|
|
36048
|
+
);
|
|
36049
|
+
const disposition = (response["data"] ?? {})["disposition"];
|
|
36050
|
+
if (disposition === "handled") return turn.result("end_turn");
|
|
36051
|
+
const aborted = await Promise.race([settled, this.exitPromise()]);
|
|
36052
|
+
await this.reportContext(turn);
|
|
36053
|
+
return this.complete(turn, aborted);
|
|
36054
|
+
}
|
|
36055
|
+
async steer(content) {
|
|
36056
|
+
if (this.closed || this.exited)
|
|
36057
|
+
throw new AmaError("agent_closed", `${this.agentId} session is closed`);
|
|
36058
|
+
await this.request({ type: "steer", ...this.message(content) });
|
|
36059
|
+
}
|
|
36060
|
+
async cancel() {
|
|
36061
|
+
const running = this.running;
|
|
36062
|
+
if (running === void 0 || this.closed) return;
|
|
36063
|
+
this.interrupted = true;
|
|
36064
|
+
for (const c of this.permissions) c.abort();
|
|
36065
|
+
void this.request({ type: "abort" }).catch(() => void 0);
|
|
36066
|
+
armCancelWatchdog(
|
|
36067
|
+
this.transport,
|
|
36068
|
+
running.catch(() => void 0),
|
|
36069
|
+
this.deps
|
|
36070
|
+
);
|
|
36071
|
+
}
|
|
36072
|
+
async close() {
|
|
36073
|
+
if (this.closed) return;
|
|
36074
|
+
this.closed = true;
|
|
36075
|
+
for (const c of this.permissions) c.abort();
|
|
36076
|
+
if (this.running !== void 0) {
|
|
36077
|
+
this.interrupted = true;
|
|
36078
|
+
this.write({ type: "abort" });
|
|
36079
|
+
}
|
|
36080
|
+
try {
|
|
36081
|
+
await this.transport.terminate();
|
|
36082
|
+
} finally {
|
|
36083
|
+
this.dispose();
|
|
36084
|
+
}
|
|
36085
|
+
}
|
|
36086
|
+
message(content) {
|
|
36087
|
+
const text = content.map((b) => b.type === "text" ? b.text : "").join("\n");
|
|
36088
|
+
const images = content.flatMap(
|
|
36089
|
+
(b) => b.type === "image" ? [{ type: "image", data: b.data, mimeType: b.mimeType }] : []
|
|
36090
|
+
);
|
|
36091
|
+
return { message: text, ...images.length > 0 ? { images } : {} };
|
|
36092
|
+
}
|
|
36093
|
+
complete(turn, aborted) {
|
|
36094
|
+
const u = this.usage;
|
|
36095
|
+
if (u.seen)
|
|
36096
|
+
turn.push({
|
|
36097
|
+
type: "usage",
|
|
36098
|
+
input: u.input,
|
|
36099
|
+
output: u.output,
|
|
36100
|
+
cacheRead: u.cacheRead,
|
|
36101
|
+
costUsd: u.costUsd
|
|
36102
|
+
});
|
|
36103
|
+
const last = this.lastAssistant;
|
|
36104
|
+
if (last !== void 0) {
|
|
36105
|
+
const text = textOf4(last);
|
|
36106
|
+
if (text !== "") turn.setFinalText(text);
|
|
36107
|
+
}
|
|
36108
|
+
if (aborted || this.interrupted) return turn.result("cancelled");
|
|
36109
|
+
switch (last?.["stopReason"]) {
|
|
36110
|
+
case "error":
|
|
36111
|
+
throw new AmaError(
|
|
36112
|
+
"agent_failed",
|
|
36113
|
+
`${this.agentId} failed: ${oneLine2(String(last["errorMessage"] ?? "unknown error"), 300)}`
|
|
36114
|
+
);
|
|
36115
|
+
case "aborted":
|
|
36116
|
+
return turn.result("cancelled");
|
|
36117
|
+
case "length":
|
|
36118
|
+
return turn.result("max_tokens");
|
|
36119
|
+
default:
|
|
36120
|
+
return turn.result("end_turn");
|
|
36121
|
+
}
|
|
36122
|
+
}
|
|
36123
|
+
/** `get_session_stats.contextUsage` → 上下文占用与窗口(拿不到就算了)。 */
|
|
36124
|
+
async reportContext(turn) {
|
|
36125
|
+
if (this.exited) return;
|
|
36126
|
+
try {
|
|
36127
|
+
const stats = await Promise.race([
|
|
36128
|
+
this.request({ type: "get_session_stats" }),
|
|
36129
|
+
new Promise((resolve41) => setTimeout(() => resolve41({}), 5e3).unref())
|
|
36130
|
+
]);
|
|
36131
|
+
const usage = (stats["data"] ?? {})["contextUsage"] ?? {};
|
|
36132
|
+
const tokens = usage["tokens"];
|
|
36133
|
+
const window2 = usage["contextWindow"];
|
|
36134
|
+
if (typeof tokens === "number" || typeof window2 === "number")
|
|
36135
|
+
turn.push({
|
|
36136
|
+
type: "usage",
|
|
36137
|
+
...typeof tokens === "number" ? { contextTokens: tokens } : {},
|
|
36138
|
+
...typeof window2 === "number" ? { contextWindow: window2 } : {}
|
|
36139
|
+
});
|
|
36140
|
+
} catch {
|
|
36141
|
+
}
|
|
36142
|
+
}
|
|
36143
|
+
exitPromise() {
|
|
36144
|
+
return new Promise((_, reject2) => {
|
|
36145
|
+
if (this.exited) reject2(this.exitError());
|
|
36146
|
+
else this.exitWaiters.add(reject2);
|
|
36147
|
+
});
|
|
36148
|
+
}
|
|
36149
|
+
exitError() {
|
|
36150
|
+
const hint = stderrHint(this.transport);
|
|
36151
|
+
return new AmaError(
|
|
36152
|
+
"agent_exited",
|
|
36153
|
+
`${this.agentId} process exited${hint !== "" ? `: ${hint}` : ""}`
|
|
36154
|
+
);
|
|
36155
|
+
}
|
|
36156
|
+
request(command3) {
|
|
36157
|
+
if (this.exited) return Promise.reject(this.exitError());
|
|
36158
|
+
const id = `ama-${this.nextId++}`;
|
|
36159
|
+
return new Promise((resolve41, reject2) => {
|
|
36160
|
+
this.pending.set(id, { resolve: resolve41, reject: reject2 });
|
|
36161
|
+
this.write({ id, ...command3 });
|
|
36162
|
+
});
|
|
36163
|
+
}
|
|
36164
|
+
write(record3) {
|
|
36165
|
+
if (this.exited) return;
|
|
36166
|
+
this.transport.stdin.write(`${JSON.stringify(record3)}
|
|
36167
|
+
`);
|
|
36168
|
+
}
|
|
36169
|
+
onExit() {
|
|
36170
|
+
this.exited = true;
|
|
36171
|
+
const error2 = this.exitError();
|
|
36172
|
+
for (const p of this.pending.values()) p.reject(error2);
|
|
36173
|
+
this.pending.clear();
|
|
36174
|
+
for (const reject2 of this.exitWaiters) reject2(error2);
|
|
36175
|
+
this.exitWaiters.clear();
|
|
36176
|
+
for (const c of this.permissions) c.abort();
|
|
36177
|
+
}
|
|
36178
|
+
onLine(line2) {
|
|
36179
|
+
let record3;
|
|
36180
|
+
try {
|
|
36181
|
+
record3 = JSON.parse(line2);
|
|
36182
|
+
} catch {
|
|
36183
|
+
this.deps.log?.("debug", msg().drivers.agent.nonJson(this.agentId));
|
|
36184
|
+
return;
|
|
36185
|
+
}
|
|
36186
|
+
switch (record3["type"]) {
|
|
36187
|
+
case "response": {
|
|
36188
|
+
const id = record3["id"];
|
|
36189
|
+
const pending = typeof id === "string" ? this.pending.get(id) : void 0;
|
|
36190
|
+
if (pending === void 0 || typeof id !== "string") return;
|
|
36191
|
+
this.pending.delete(id);
|
|
36192
|
+
pending.resolve(record3);
|
|
36193
|
+
return;
|
|
36194
|
+
}
|
|
36195
|
+
case "agent_settled":
|
|
36196
|
+
this.settle?.(record3["aborted"] === true);
|
|
36197
|
+
return;
|
|
36198
|
+
case "extension_ui_request":
|
|
36199
|
+
void this.onDialog(record3);
|
|
36200
|
+
return;
|
|
36201
|
+
default:
|
|
36202
|
+
this.onEvent(record3);
|
|
36203
|
+
}
|
|
36204
|
+
}
|
|
36205
|
+
onEvent(record3) {
|
|
36206
|
+
const turn = this.turn;
|
|
36207
|
+
if (turn === void 0) return;
|
|
36208
|
+
switch (record3["type"]) {
|
|
36209
|
+
case "message_update": {
|
|
36210
|
+
const event = record3["assistantMessageEvent"] ?? {};
|
|
36211
|
+
const delta = event["delta"];
|
|
36212
|
+
if (typeof delta !== "string") return;
|
|
36213
|
+
if (event["type"] === "text_delta") turn.push({ type: "message_delta", text: delta });
|
|
36214
|
+
else if (event["type"] === "thinking_delta")
|
|
36215
|
+
turn.push({ type: "thought_delta", text: delta });
|
|
36216
|
+
return;
|
|
36217
|
+
}
|
|
36218
|
+
case "message_end": {
|
|
36219
|
+
const message = record3["message"] ?? {};
|
|
36220
|
+
if (message["role"] !== "assistant") return;
|
|
36221
|
+
this.lastAssistant = message;
|
|
36222
|
+
const usage = message["usage"] ?? {};
|
|
36223
|
+
const num10 = (key) => typeof usage[key] === "number" ? usage[key] : 0;
|
|
36224
|
+
const cost2 = (usage["cost"] ?? {})["total"];
|
|
36225
|
+
this.usage = {
|
|
36226
|
+
input: this.usage.input + num10("input"),
|
|
36227
|
+
output: this.usage.output + num10("output"),
|
|
36228
|
+
cacheRead: this.usage.cacheRead + num10("cacheRead"),
|
|
36229
|
+
costUsd: this.usage.costUsd + (typeof cost2 === "number" ? cost2 : 0),
|
|
36230
|
+
seen: true
|
|
36231
|
+
};
|
|
36232
|
+
return;
|
|
36233
|
+
}
|
|
36234
|
+
case "tool_execution_start":
|
|
36235
|
+
case "tool_execution_end": {
|
|
36236
|
+
const tool = String(record3["toolName"] ?? "tool");
|
|
36237
|
+
const known = turn.tool(String(record3["toolCallId"] ?? ""));
|
|
36238
|
+
const input2 = record3["args"] ?? {};
|
|
36239
|
+
const path = typeof input2["path"] === "string" ? input2["path"] : void 0;
|
|
36240
|
+
const locations = path !== void 0 ? [(0, import_node_path61.resolve)(this.options.cwd, path)] : known?.locations;
|
|
36241
|
+
turn.push({
|
|
36242
|
+
type: "tool_call",
|
|
36243
|
+
id: String(record3["toolCallId"] ?? ""),
|
|
36244
|
+
title: known?.title ?? piToolTitle(tool, input2),
|
|
36245
|
+
kind: piToolKind(tool),
|
|
36246
|
+
status: record3["type"] === "tool_execution_start" ? "in_progress" : record3["isError"] === true ? "failed" : "completed",
|
|
36247
|
+
...locations !== void 0 && locations.length > 0 ? { locations } : {}
|
|
36248
|
+
});
|
|
36249
|
+
return;
|
|
36250
|
+
}
|
|
36251
|
+
case "auto_retry_start":
|
|
36252
|
+
turn.push({
|
|
36253
|
+
type: "notice",
|
|
36254
|
+
level: "warn",
|
|
36255
|
+
text: msg().drivers.agent.error(
|
|
36256
|
+
this.agentId,
|
|
36257
|
+
oneLine2(String(record3["errorMessage"] ?? "error"), 200),
|
|
36258
|
+
true
|
|
36259
|
+
)
|
|
36260
|
+
});
|
|
36261
|
+
return;
|
|
36262
|
+
default:
|
|
36263
|
+
return;
|
|
36264
|
+
}
|
|
36265
|
+
}
|
|
36266
|
+
/** 扩展对话框:ama 的审批闸按模式决定或交给人;其它扩展的对话框取消(不代答)。 */
|
|
36267
|
+
async onDialog(record3) {
|
|
36268
|
+
const id = String(record3["id"] ?? "");
|
|
36269
|
+
const method = String(record3["method"] ?? "");
|
|
36270
|
+
if (!DIALOG_METHODS.has(method)) {
|
|
36271
|
+
if (record3["method"] === "notify" && record3["notifyType"] !== "info")
|
|
36272
|
+
this.turn?.push({
|
|
36273
|
+
type: "notice",
|
|
36274
|
+
level: "warn",
|
|
36275
|
+
text: `${this.agentId}: ${oneLine2(String(record3["message"] ?? ""), 200)}`
|
|
36276
|
+
});
|
|
36277
|
+
return;
|
|
36278
|
+
}
|
|
36279
|
+
if (method !== "confirm" || record3["title"] !== PI_GATE_TITLE) {
|
|
36280
|
+
this.turn?.push({
|
|
36281
|
+
type: "notice",
|
|
36282
|
+
level: "warn",
|
|
36283
|
+
text: msg().drivers.agent.extensionDialog(
|
|
36284
|
+
this.agentId,
|
|
36285
|
+
oneLine2(String(record3["title"] ?? method), 80)
|
|
36286
|
+
)
|
|
36287
|
+
});
|
|
36288
|
+
this.write({ type: "extension_ui_response", id, cancelled: true });
|
|
36289
|
+
return;
|
|
36290
|
+
}
|
|
36291
|
+
const confirmed = await this.decide(record3);
|
|
36292
|
+
this.write({ type: "extension_ui_response", id, confirmed });
|
|
36293
|
+
}
|
|
36294
|
+
async decide(record3) {
|
|
36295
|
+
let call;
|
|
36296
|
+
try {
|
|
36297
|
+
call = JSON.parse(String(record3["message"] ?? "{}"));
|
|
36298
|
+
} catch {
|
|
36299
|
+
return false;
|
|
36300
|
+
}
|
|
36301
|
+
const tool = String(call["tool"] ?? "tool");
|
|
36302
|
+
const input2 = call["input"] ?? {};
|
|
36303
|
+
const mode = this.options.mode;
|
|
36304
|
+
if (isReadOnlyMode(mode)) return false;
|
|
36305
|
+
if (mode !== "default" && EDIT_TOOLS.has(tool)) return true;
|
|
36306
|
+
const hooks = this.hooks;
|
|
36307
|
+
if (hooks === void 0 || this.interrupted || this.closed) return false;
|
|
36308
|
+
const known = this.turn?.tool(String(call["id"] ?? ""));
|
|
36309
|
+
const path = typeof input2["path"] === "string" ? input2["path"] : void 0;
|
|
36310
|
+
const controller = new AbortController();
|
|
36311
|
+
this.permissions.add(controller);
|
|
36312
|
+
try {
|
|
36313
|
+
const outcome = await hooks.onPermission(
|
|
36314
|
+
{
|
|
36315
|
+
toolCall: {
|
|
36316
|
+
title: known?.title ?? piToolTitle(tool, input2),
|
|
36317
|
+
kind: piToolKind(tool),
|
|
36318
|
+
...path !== void 0 ? { locations: [(0, import_node_path61.resolve)(this.options.cwd, path)] } : {},
|
|
36319
|
+
inputSummary: oneLine2(JSON.stringify(input2), 300)
|
|
36320
|
+
},
|
|
36321
|
+
options: [
|
|
36322
|
+
{ optionId: "allow", kind: "allow_once" },
|
|
36323
|
+
{ optionId: "reject", kind: "reject_once" }
|
|
36324
|
+
]
|
|
36325
|
+
},
|
|
36326
|
+
controller.signal
|
|
36327
|
+
);
|
|
36328
|
+
return !controller.signal.aborted && outcome.outcome === "selected" && outcome.optionId === "allow";
|
|
36329
|
+
} finally {
|
|
36330
|
+
this.permissions.delete(controller);
|
|
36331
|
+
}
|
|
36332
|
+
}
|
|
36333
|
+
};
|
|
36334
|
+
}
|
|
36335
|
+
});
|
|
36336
|
+
|
|
35566
36337
|
// src/drivers/pids.ts
|
|
35567
36338
|
function pidsFile(dataDir) {
|
|
35568
|
-
return (0,
|
|
36339
|
+
return (0, import_node_path62.join)(dataDir, "drivers", "pids.json");
|
|
35569
36340
|
}
|
|
35570
36341
|
function read(file) {
|
|
35571
36342
|
try {
|
|
35572
|
-
const parsed = JSON.parse((0,
|
|
36343
|
+
const parsed = JSON.parse((0, import_node_fs42.readFileSync)(file, "utf8"));
|
|
35573
36344
|
return Array.isArray(parsed.entries) ? parsed.entries : [];
|
|
35574
36345
|
} catch {
|
|
35575
36346
|
return [];
|
|
@@ -35577,11 +36348,11 @@ function read(file) {
|
|
|
35577
36348
|
}
|
|
35578
36349
|
function write(file, entries) {
|
|
35579
36350
|
try {
|
|
35580
|
-
(0,
|
|
36351
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path62.dirname)(file), { recursive: true });
|
|
35581
36352
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
35582
|
-
(0,
|
|
36353
|
+
(0, import_node_fs42.writeFileSync)(tmp, `${JSON.stringify({ version: 1, entries }, null, 2)}
|
|
35583
36354
|
`);
|
|
35584
|
-
(0,
|
|
36355
|
+
(0, import_node_fs42.renameSync)(tmp, file);
|
|
35585
36356
|
} catch {
|
|
35586
36357
|
}
|
|
35587
36358
|
}
|
|
@@ -35597,13 +36368,13 @@ function psCommand(pid) {
|
|
|
35597
36368
|
const out = (0, import_node_child_process11.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
|
|
35598
36369
|
return out.status === 0 ? out.stdout.trim() : void 0;
|
|
35599
36370
|
}
|
|
35600
|
-
var import_node_child_process11,
|
|
36371
|
+
var import_node_child_process11, import_node_fs42, import_node_path62, PidRegistry;
|
|
35601
36372
|
var init_pids = __esm({
|
|
35602
36373
|
"src/drivers/pids.ts"() {
|
|
35603
36374
|
"use strict";
|
|
35604
36375
|
import_node_child_process11 = require("node:child_process");
|
|
35605
|
-
|
|
35606
|
-
|
|
36376
|
+
import_node_fs42 = require("node:fs");
|
|
36377
|
+
import_node_path62 = require("node:path");
|
|
35607
36378
|
init_process_tree();
|
|
35608
36379
|
PidRegistry = class {
|
|
35609
36380
|
constructor(file) {
|
|
@@ -35639,7 +36410,7 @@ var init_pids = __esm({
|
|
|
35639
36410
|
}
|
|
35640
36411
|
if (platform === "win32" || !groupAlive(entry.pid)) continue;
|
|
35641
36412
|
const command3 = commandOf(entry.pid);
|
|
35642
|
-
if (command3 !== void 0 && command3.includes((0,
|
|
36413
|
+
if (command3 !== void 0 && command3.includes((0, import_node_path62.basename)(entry.program))) {
|
|
35643
36414
|
await kill(entry.pid);
|
|
35644
36415
|
killed.push(entry.pid);
|
|
35645
36416
|
}
|
|
@@ -35799,7 +36570,7 @@ async function askHuman(request, ctx) {
|
|
|
35799
36570
|
if (ctx.signal.aborted) return CANCELLED;
|
|
35800
36571
|
if (ctx.unattended) return pick(request, "reject_once") ?? CANCELLED;
|
|
35801
36572
|
const approval = {
|
|
35802
|
-
requestId: (0,
|
|
36573
|
+
requestId: (0, import_node_crypto15.randomUUID)(),
|
|
35803
36574
|
toolName: externalToolName(ctx.agent),
|
|
35804
36575
|
input: request.toolCall,
|
|
35805
36576
|
reason: "mode",
|
|
@@ -35840,11 +36611,11 @@ function supportedMode(mode, supported) {
|
|
|
35840
36611
|
if (rank(m) <= rank(mode) && (best === void 0 || rank(m) > rank(best))) best = m;
|
|
35841
36612
|
return best;
|
|
35842
36613
|
}
|
|
35843
|
-
var
|
|
36614
|
+
var import_node_crypto15, CANCELLED;
|
|
35844
36615
|
var init_permissions2 = __esm({
|
|
35845
36616
|
"src/drivers/permissions.ts"() {
|
|
35846
36617
|
"use strict";
|
|
35847
|
-
|
|
36618
|
+
import_node_crypto15 = require("node:crypto");
|
|
35848
36619
|
init_types();
|
|
35849
36620
|
CANCELLED = { outcome: "cancelled" };
|
|
35850
36621
|
}
|
|
@@ -35991,7 +36762,8 @@ var init_runner2 = __esm({
|
|
|
35991
36762
|
"acp",
|
|
35992
36763
|
"acp-adapter",
|
|
35993
36764
|
"claude-stream",
|
|
35994
|
-
"codex-app-server"
|
|
36765
|
+
"codex-app-server",
|
|
36766
|
+
"pi-rpc"
|
|
35995
36767
|
]);
|
|
35996
36768
|
ProcessHandle = class {
|
|
35997
36769
|
constructor(runner, chosen, request, deps) {
|
|
@@ -36318,15 +37090,17 @@ function createDriver(agentId, candidate, deps) {
|
|
|
36318
37090
|
return new ClaudeStreamDriver(agentId, candidate, deps);
|
|
36319
37091
|
case "codex-app-server":
|
|
36320
37092
|
return new CodexAppServerDriver(agentId, candidate, deps);
|
|
37093
|
+
case "pi-rpc":
|
|
37094
|
+
return new PiRpcDriver(agentId, candidate, deps);
|
|
36321
37095
|
case "oneshot":
|
|
36322
37096
|
return new OneshotDriver(agentId, candidate, deps);
|
|
36323
37097
|
}
|
|
36324
37098
|
}
|
|
36325
|
-
var
|
|
37099
|
+
var import_node_path63, reaped, ExternalAgents;
|
|
36326
37100
|
var init_agents2 = __esm({
|
|
36327
37101
|
"src/drivers/agents.ts"() {
|
|
36328
37102
|
"use strict";
|
|
36329
|
-
|
|
37103
|
+
import_node_path63 = require("node:path");
|
|
36330
37104
|
init_errors();
|
|
36331
37105
|
init_driver();
|
|
36332
37106
|
init_catalog4();
|
|
@@ -36334,6 +37108,7 @@ var init_agents2 = __esm({
|
|
|
36334
37108
|
init_claude_stream();
|
|
36335
37109
|
init_codex_app_server();
|
|
36336
37110
|
init_oneshot();
|
|
37111
|
+
init_pi_rpc();
|
|
36337
37112
|
init_pids();
|
|
36338
37113
|
init_pool();
|
|
36339
37114
|
init_probe();
|
|
@@ -36359,7 +37134,7 @@ var init_agents2 = __esm({
|
|
|
36359
37134
|
probe: new ProgramProbe({
|
|
36360
37135
|
env: options.env,
|
|
36361
37136
|
cwd: options.cwd,
|
|
36362
|
-
...options.dataDir !== void 0 ? { cacheFile: (0,
|
|
37137
|
+
...options.dataDir !== void 0 ? { cacheFile: (0, import_node_path63.join)(options.dataDir, "drivers.json") } : {}
|
|
36363
37138
|
}),
|
|
36364
37139
|
spawn: (spec2) => spawnTransport(spec2, {
|
|
36365
37140
|
onSpawn: (pid) => registry3?.add(pid, spec2.program),
|
|
@@ -36606,11 +37381,11 @@ function mergeAgentInfos(base4, external) {
|
|
|
36606
37381
|
}
|
|
36607
37382
|
return out;
|
|
36608
37383
|
}
|
|
36609
|
-
var
|
|
37384
|
+
var import_node_crypto16, LISTED_EXTERNAL_AGENTS, NO_AGENT_PROBE_ENV, externalTesting, HOST_AMA_RUNNER, ExternalTaskHandle, infoCache, SessionExternalAgents;
|
|
36610
37385
|
var init_external = __esm({
|
|
36611
37386
|
"src/agents/external.ts"() {
|
|
36612
37387
|
"use strict";
|
|
36613
|
-
|
|
37388
|
+
import_node_crypto16 = require("node:crypto");
|
|
36614
37389
|
init_session_tools();
|
|
36615
37390
|
init_types_w5();
|
|
36616
37391
|
init_agents2();
|
|
@@ -36785,7 +37560,7 @@ var init_external = __esm({
|
|
|
36785
37560
|
agentEntry(this.wiring.config, spec2)?.maxMode
|
|
36786
37561
|
);
|
|
36787
37562
|
const approval = {
|
|
36788
|
-
requestId: (0,
|
|
37563
|
+
requestId: (0, import_node_crypto16.randomUUID)(),
|
|
36789
37564
|
toolName: "task",
|
|
36790
37565
|
input: {
|
|
36791
37566
|
agent: spec2,
|
|
@@ -37031,7 +37806,7 @@ function sourceText2(source, cache3, log) {
|
|
|
37031
37806
|
if (cached !== void 0) return cached;
|
|
37032
37807
|
let text = "";
|
|
37033
37808
|
try {
|
|
37034
|
-
text = (0,
|
|
37809
|
+
text = (0, import_node_fs43.readFileSync)(source.path, "utf8");
|
|
37035
37810
|
} catch (error2) {
|
|
37036
37811
|
log(
|
|
37037
37812
|
"warn",
|
|
@@ -37385,11 +38160,11 @@ async function disposeSessionAlongside(target, session, fallback) {
|
|
|
37385
38160
|
await session.dispose();
|
|
37386
38161
|
record3.live.delete(session);
|
|
37387
38162
|
}
|
|
37388
|
-
var
|
|
38163
|
+
var import_node_fs43, records, LOG_LEVELS;
|
|
37389
38164
|
var init_compose_session = __esm({
|
|
37390
38165
|
"src/cli/compose-session.ts"() {
|
|
37391
38166
|
"use strict";
|
|
37392
|
-
|
|
38167
|
+
import_node_fs43 = require("node:fs");
|
|
37393
38168
|
init_limits();
|
|
37394
38169
|
init_session2();
|
|
37395
38170
|
init_session_subagent();
|
|
@@ -37437,7 +38212,7 @@ function toolTitle(name, args, nested = false) {
|
|
|
37437
38212
|
function toolLocations(args, cwd) {
|
|
37438
38213
|
const path = argOf(args, "path", "file_path", "filePath");
|
|
37439
38214
|
if (path === void 0) return void 0;
|
|
37440
|
-
return [{ path: (0,
|
|
38215
|
+
return [{ path: (0, import_node_path64.isAbsolute)(path) ? path : (0, import_node_path64.resolve)(cwd, path) }];
|
|
37441
38216
|
}
|
|
37442
38217
|
function resultText2(content) {
|
|
37443
38218
|
const text = typeof content === "string" ? content : content.map((b) => b.type === "text" ? b.text : `[${b.type}]`).join("");
|
|
@@ -37464,11 +38239,11 @@ function resultContent(result) {
|
|
|
37464
38239
|
]
|
|
37465
38240
|
};
|
|
37466
38241
|
}
|
|
37467
|
-
var
|
|
38242
|
+
var import_node_path64, TOOL_OUTPUT_LIMIT, KINDS3;
|
|
37468
38243
|
var init_acp_tool_text = __esm({
|
|
37469
38244
|
"src/modes/acp/acp-tool-text.ts"() {
|
|
37470
38245
|
"use strict";
|
|
37471
|
-
|
|
38246
|
+
import_node_path64 = require("node:path");
|
|
37472
38247
|
init_turn();
|
|
37473
38248
|
init_i18n();
|
|
37474
38249
|
TOOL_OUTPUT_LIMIT = 4 * 1024;
|
|
@@ -38245,9 +39020,9 @@ var init_acp_sessions = __esm({
|
|
|
38245
39020
|
// src/modes/acp/acp-server.ts
|
|
38246
39021
|
function canonical(path) {
|
|
38247
39022
|
try {
|
|
38248
|
-
return
|
|
39023
|
+
return import_node_fs44.realpathSync.native((0, import_node_path65.resolve)(path));
|
|
38249
39024
|
} catch {
|
|
38250
|
-
return (0,
|
|
39025
|
+
return (0, import_node_path65.resolve)(path);
|
|
38251
39026
|
}
|
|
38252
39027
|
}
|
|
38253
39028
|
function str(params, key) {
|
|
@@ -38276,12 +39051,12 @@ ${block.resource.text}
|
|
|
38276
39051
|
function countOf(value) {
|
|
38277
39052
|
return Array.isArray(value) ? value.length : 0;
|
|
38278
39053
|
}
|
|
38279
|
-
var
|
|
39054
|
+
var import_node_fs44, import_node_path65, ACP_AGENT_CAPABILITIES, SESSION_ID_SHAPE, AcpServer;
|
|
38280
39055
|
var init_acp_server = __esm({
|
|
38281
39056
|
"src/modes/acp/acp-server.ts"() {
|
|
38282
39057
|
"use strict";
|
|
38283
|
-
|
|
38284
|
-
|
|
39058
|
+
import_node_fs44 = require("node:fs");
|
|
39059
|
+
import_node_path65 = require("node:path");
|
|
38285
39060
|
init_shared();
|
|
38286
39061
|
init_compose_session();
|
|
38287
39062
|
init_compose_store();
|
|
@@ -38795,7 +39570,7 @@ function terminalAuthMethods(authFile) {
|
|
|
38795
39570
|
];
|
|
38796
39571
|
}
|
|
38797
39572
|
function gateAuthFile(args, cwd) {
|
|
38798
|
-
if (args.authFile !== void 0) return (0,
|
|
39573
|
+
if (args.authFile !== void 0) return (0, import_node_path66.resolve)(cwd, args.authFile);
|
|
38799
39574
|
if (args.profile === void 0) return void 0;
|
|
38800
39575
|
try {
|
|
38801
39576
|
return loadProfile(args.profile, cwd).authFile;
|
|
@@ -38918,11 +39693,11 @@ async function runAcpAuthGate(args, deps, io, cause, options = {}) {
|
|
|
38918
39693
|
await runtime?.dispose("exit").catch(() => void 0);
|
|
38919
39694
|
return code;
|
|
38920
39695
|
}
|
|
38921
|
-
var
|
|
39696
|
+
var import_node_path66, AUTH_RETRY_INTERVAL_MS, SESSION_METHODS;
|
|
38922
39697
|
var init_acp_auth_gate = __esm({
|
|
38923
39698
|
"src/modes/acp/acp-auth-gate.ts"() {
|
|
38924
39699
|
"use strict";
|
|
38925
|
-
|
|
39700
|
+
import_node_path66 = require("node:path");
|
|
38926
39701
|
init_args();
|
|
38927
39702
|
init_bootstrap();
|
|
38928
39703
|
init_exit_codes();
|
|
@@ -39004,7 +39779,7 @@ async function bootstrap(argsIn, deps, io) {
|
|
|
39004
39779
|
() => deps.sessions.open(sessionRequest, { sessionDir: paths.sessionDir, cwd: paths.cwd })
|
|
39005
39780
|
);
|
|
39006
39781
|
let sessionCwd = sessionManager.cwd;
|
|
39007
|
-
if (!(0,
|
|
39782
|
+
if (!(0, import_node_fs45.existsSync)(sessionCwd)) {
|
|
39008
39783
|
const replacement = interactive ? await deps.ui?.askCwd?.(sessionCwd) : void 0;
|
|
39009
39784
|
if (replacement === void 0) {
|
|
39010
39785
|
throw new StartupError(
|
|
@@ -39013,7 +39788,7 @@ async function bootstrap(argsIn, deps, io) {
|
|
|
39013
39788
|
ExitCode.Session
|
|
39014
39789
|
);
|
|
39015
39790
|
}
|
|
39016
|
-
sessionCwd = (0,
|
|
39791
|
+
sessionCwd = (0, import_node_path67.resolve)(replacement);
|
|
39017
39792
|
}
|
|
39018
39793
|
const runtimePaths = { ...paths, cwd: sessionCwd };
|
|
39019
39794
|
const trust = await step(
|
|
@@ -39088,7 +39863,7 @@ async function bootstrap(argsIn, deps, io) {
|
|
|
39088
39863
|
() => deps.providers.create({
|
|
39089
39864
|
config,
|
|
39090
39865
|
cwd: sessionCwd,
|
|
39091
|
-
authFile: args.authFile !== void 0 ? (0,
|
|
39866
|
+
authFile: args.authFile !== void 0 ? (0, import_node_path67.resolve)(io.cwd, args.authFile) : defaultAuthFilePath(paths.configDir),
|
|
39092
39867
|
authEnv: profile?.authEnv ?? true,
|
|
39093
39868
|
dataDir: paths.dataDir,
|
|
39094
39869
|
...args.apiKey !== void 0 && args.model !== void 0 ? {
|
|
@@ -39398,12 +40173,12 @@ function reportError(error2, io, fallback = ExitCode.RuntimeError) {
|
|
|
39398
40173
|
if (isAmaError(error2) && error2.exitCode !== void 0) return error2.exitCode;
|
|
39399
40174
|
return fallback;
|
|
39400
40175
|
}
|
|
39401
|
-
var
|
|
40176
|
+
var import_node_fs45, import_node_path67;
|
|
39402
40177
|
var init_bootstrap = __esm({
|
|
39403
40178
|
"src/cli/bootstrap.ts"() {
|
|
39404
40179
|
"use strict";
|
|
39405
|
-
|
|
39406
|
-
|
|
40180
|
+
import_node_fs45 = require("node:fs");
|
|
40181
|
+
import_node_path67 = require("node:path");
|
|
39407
40182
|
init_auth_file();
|
|
39408
40183
|
init_context_files();
|
|
39409
40184
|
init_load();
|
|
@@ -39429,7 +40204,7 @@ var init_bootstrap = __esm({
|
|
|
39429
40204
|
// src/auth/oauth/token-store.ts
|
|
39430
40205
|
function readRaw(path) {
|
|
39431
40206
|
try {
|
|
39432
|
-
const value = JSON.parse(retryTransientFs(() => (0,
|
|
40207
|
+
const value = JSON.parse(retryTransientFs(() => (0, import_node_fs46.readFileSync)(path, "utf8")));
|
|
39433
40208
|
return typeof value === "object" && value !== null && typeof value.providers === "object" ? value : void 0;
|
|
39434
40209
|
} catch {
|
|
39435
40210
|
return void 0;
|
|
@@ -39461,12 +40236,12 @@ function isStaleLock(path, now = Date.now()) {
|
|
|
39461
40236
|
let age;
|
|
39462
40237
|
let pid;
|
|
39463
40238
|
try {
|
|
39464
|
-
age = now - (0,
|
|
39465
|
-
const value = JSON.parse((0,
|
|
40239
|
+
age = now - (0, import_node_fs46.statSync)(path).mtimeMs;
|
|
40240
|
+
const value = JSON.parse((0, import_node_fs46.readFileSync)(path, "utf8"));
|
|
39466
40241
|
pid = typeof value.pid === "number" ? value.pid : void 0;
|
|
39467
40242
|
} catch {
|
|
39468
40243
|
try {
|
|
39469
|
-
age = now - (0,
|
|
40244
|
+
age = now - (0, import_node_fs46.statSync)(path).mtimeMs;
|
|
39470
40245
|
} catch {
|
|
39471
40246
|
return false;
|
|
39472
40247
|
}
|
|
@@ -39475,11 +40250,11 @@ function isStaleLock(path, now = Date.now()) {
|
|
|
39475
40250
|
}
|
|
39476
40251
|
function tryAcquire(path) {
|
|
39477
40252
|
try {
|
|
39478
|
-
const fd = (0,
|
|
40253
|
+
const fd = (0, import_node_fs46.openSync)(path, "wx", 384);
|
|
39479
40254
|
try {
|
|
39480
|
-
(0,
|
|
40255
|
+
(0, import_node_fs46.writeSync)(fd, JSON.stringify({ pid: process.pid, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
39481
40256
|
} finally {
|
|
39482
|
-
(0,
|
|
40257
|
+
(0, import_node_fs46.closeSync)(fd);
|
|
39483
40258
|
}
|
|
39484
40259
|
return true;
|
|
39485
40260
|
} catch (error2) {
|
|
@@ -39490,13 +40265,13 @@ function tryAcquire(path) {
|
|
|
39490
40265
|
}
|
|
39491
40266
|
async function withRefreshLock(authFile, fn, options = {}) {
|
|
39492
40267
|
const path = lockPath(authFile);
|
|
39493
|
-
(0,
|
|
40268
|
+
(0, import_node_fs46.mkdirSync)((0, import_node_path68.dirname)(path), { recursive: true, mode: 448 });
|
|
39494
40269
|
const deadline = Date.now() + (options.waitMs ?? LOCK_WAIT_MS);
|
|
39495
40270
|
for (; ; ) {
|
|
39496
40271
|
if (tryAcquire(path)) break;
|
|
39497
40272
|
if (isStaleLock(path)) {
|
|
39498
40273
|
try {
|
|
39499
|
-
(0,
|
|
40274
|
+
(0, import_node_fs46.unlinkSync)(path);
|
|
39500
40275
|
} catch {
|
|
39501
40276
|
}
|
|
39502
40277
|
continue;
|
|
@@ -39511,17 +40286,17 @@ async function withRefreshLock(authFile, fn, options = {}) {
|
|
|
39511
40286
|
return await fn();
|
|
39512
40287
|
} finally {
|
|
39513
40288
|
try {
|
|
39514
|
-
(0,
|
|
40289
|
+
(0, import_node_fs46.unlinkSync)(path);
|
|
39515
40290
|
} catch {
|
|
39516
40291
|
}
|
|
39517
40292
|
}
|
|
39518
40293
|
}
|
|
39519
|
-
var
|
|
40294
|
+
var import_node_fs46, import_node_path68, LOCK_WAIT_MS, LOCK_STALE_MS, LOCK_POLL_MS;
|
|
39520
40295
|
var init_token_store = __esm({
|
|
39521
40296
|
"src/auth/oauth/token-store.ts"() {
|
|
39522
40297
|
"use strict";
|
|
39523
|
-
|
|
39524
|
-
|
|
40298
|
+
import_node_fs46 = require("node:fs");
|
|
40299
|
+
import_node_path68 = require("node:path");
|
|
39525
40300
|
init_auth_file();
|
|
39526
40301
|
init_fs_retry();
|
|
39527
40302
|
init_types2();
|
|
@@ -39535,7 +40310,7 @@ var init_token_store = __esm({
|
|
|
39535
40310
|
|
|
39536
40311
|
// src/ai/providers/discovered-cache.ts
|
|
39537
40312
|
function discoveredCachePath(dataDir, provider) {
|
|
39538
|
-
return (0,
|
|
40313
|
+
return (0, import_node_path69.join)(dataDir, "models", "discovered", `${provider}.json`);
|
|
39539
40314
|
}
|
|
39540
40315
|
function toEntry(value) {
|
|
39541
40316
|
if (typeof value !== "object" || value === null) return void 0;
|
|
@@ -39555,7 +40330,7 @@ function toEntry(value) {
|
|
|
39555
40330
|
function readDiscoveredCache(dataDir, provider) {
|
|
39556
40331
|
let parsed;
|
|
39557
40332
|
try {
|
|
39558
|
-
parsed = JSON.parse((0,
|
|
40333
|
+
parsed = JSON.parse((0, import_node_fs47.readFileSync)(discoveredCachePath(dataDir, provider), "utf8"));
|
|
39559
40334
|
} catch {
|
|
39560
40335
|
return void 0;
|
|
39561
40336
|
}
|
|
@@ -39579,17 +40354,17 @@ function writeDiscoveredCache(dataDir, provider, input2, now = Date.now()) {
|
|
|
39579
40354
|
...input2.flavor !== void 0 ? { flavor: input2.flavor } : {},
|
|
39580
40355
|
models: input2.models.map(toEntry).filter((m) => m !== void 0)
|
|
39581
40356
|
};
|
|
39582
|
-
(0,
|
|
40357
|
+
(0, import_node_fs47.mkdirSync)((0, import_node_path69.dirname)(path), { recursive: true, mode: 448 });
|
|
39583
40358
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
39584
|
-
(0,
|
|
40359
|
+
(0, import_node_fs47.writeFileSync)(tmp, `${JSON.stringify(file, null, 2)}
|
|
39585
40360
|
`);
|
|
39586
|
-
(0,
|
|
40361
|
+
(0, import_node_fs47.renameSync)(tmp, path);
|
|
39587
40362
|
return path;
|
|
39588
40363
|
}
|
|
39589
40364
|
function clearDiscoveredCache(dataDir, provider) {
|
|
39590
40365
|
const path = discoveredCachePath(dataDir, provider);
|
|
39591
|
-
if (!(0,
|
|
39592
|
-
(0,
|
|
40366
|
+
if (!(0, import_node_fs47.existsSync)(path)) return false;
|
|
40367
|
+
(0, import_node_fs47.rmSync)(path, { force: true });
|
|
39593
40368
|
return true;
|
|
39594
40369
|
}
|
|
39595
40370
|
function thinkingMapOf(levels) {
|
|
@@ -39643,12 +40418,12 @@ function mergeDiscoveredModels(registry3, dataDir, modelsDev, loginFlavor = () =
|
|
|
39643
40418
|
}
|
|
39644
40419
|
return merged;
|
|
39645
40420
|
}
|
|
39646
|
-
var
|
|
40421
|
+
var import_node_fs47, import_node_path69, DISCOVERED_CACHE_VERSION, EFFORT_LEVELS, SUBSCRIPTION_FALLBACK_CONTEXT_WINDOW, SUBSCRIPTION_PROVIDERS;
|
|
39647
40422
|
var init_discovered_cache = __esm({
|
|
39648
40423
|
"src/ai/providers/discovered-cache.ts"() {
|
|
39649
40424
|
"use strict";
|
|
39650
|
-
|
|
39651
|
-
|
|
40425
|
+
import_node_fs47 = require("node:fs");
|
|
40426
|
+
import_node_path69 = require("node:path");
|
|
39652
40427
|
init_catalog2();
|
|
39653
40428
|
init_enrich();
|
|
39654
40429
|
DISCOVERED_CACHE_VERSION = 1;
|
|
@@ -41531,7 +42306,7 @@ function parseKeybindings(value) {
|
|
|
41531
42306
|
function loadKeybindingsFile(path) {
|
|
41532
42307
|
let text;
|
|
41533
42308
|
try {
|
|
41534
|
-
text = (0,
|
|
42309
|
+
text = (0, import_node_fs49.readFileSync)(path, "utf8");
|
|
41535
42310
|
} catch (error2) {
|
|
41536
42311
|
if (error2.code === "ENOENT") return { overrides: {}, warnings: [] };
|
|
41537
42312
|
return {
|
|
@@ -41548,12 +42323,12 @@ function loadKeybindingsFile(path) {
|
|
|
41548
42323
|
};
|
|
41549
42324
|
}
|
|
41550
42325
|
}
|
|
41551
|
-
var
|
|
42326
|
+
var import_node_fs49, DEFAULT_KEYBINDINGS, Keybindings, defaultKeybindings;
|
|
41552
42327
|
var init_keybindings = __esm({
|
|
41553
42328
|
"src/tui/keybindings.ts"() {
|
|
41554
42329
|
"use strict";
|
|
41555
42330
|
init_i18n();
|
|
41556
|
-
|
|
42331
|
+
import_node_fs49 = require("node:fs");
|
|
41557
42332
|
init_keys();
|
|
41558
42333
|
DEFAULT_KEYBINDINGS = {
|
|
41559
42334
|
"tui.editor.submit": ["enter"],
|
|
@@ -42389,7 +43164,7 @@ var init_editor_buffer = __esm({
|
|
|
42389
43164
|
function loadHistoryFile(path, limit = 500) {
|
|
42390
43165
|
let text;
|
|
42391
43166
|
try {
|
|
42392
|
-
text = (0,
|
|
43167
|
+
text = (0, import_node_fs50.readFileSync)(path, "utf8");
|
|
42393
43168
|
} catch {
|
|
42394
43169
|
return [];
|
|
42395
43170
|
}
|
|
@@ -42406,11 +43181,11 @@ function loadHistoryFile(path, limit = 500) {
|
|
|
42406
43181
|
}
|
|
42407
43182
|
function appendHistoryFile(path, entry, limit) {
|
|
42408
43183
|
try {
|
|
42409
|
-
(0,
|
|
42410
|
-
(0,
|
|
43184
|
+
(0, import_node_fs50.mkdirSync)((0, import_node_path71.dirname)(path), { recursive: true });
|
|
43185
|
+
(0, import_node_fs50.appendFileSync)(path, JSON.stringify(entry) + "\n", { mode: 384 });
|
|
42411
43186
|
const all = loadHistoryFile(path, Number.MAX_SAFE_INTEGER);
|
|
42412
43187
|
if (all.length > limit * 2) {
|
|
42413
|
-
(0,
|
|
43188
|
+
(0, import_node_fs50.writeFileSync)(
|
|
42414
43189
|
path,
|
|
42415
43190
|
all.slice(-limit).map((e) => JSON.stringify(e) + "\n").join("")
|
|
42416
43191
|
);
|
|
@@ -42418,12 +43193,12 @@ function appendHistoryFile(path, entry, limit) {
|
|
|
42418
43193
|
} catch {
|
|
42419
43194
|
}
|
|
42420
43195
|
}
|
|
42421
|
-
var
|
|
43196
|
+
var import_node_fs50, import_node_path71;
|
|
42422
43197
|
var init_editor_history = __esm({
|
|
42423
43198
|
"src/tui/components/editor-history.ts"() {
|
|
42424
43199
|
"use strict";
|
|
42425
|
-
|
|
42426
|
-
|
|
43200
|
+
import_node_fs50 = require("node:fs");
|
|
43201
|
+
import_node_path71 = require("node:path");
|
|
42427
43202
|
}
|
|
42428
43203
|
});
|
|
42429
43204
|
|
|
@@ -43981,7 +44756,8 @@ var init_key_docs = __esm({
|
|
|
43981
44756
|
maxPending: 16,
|
|
43982
44757
|
background: "auto",
|
|
43983
44758
|
autoBackgroundAfterMs: 0,
|
|
43984
|
-
retainSessions: 4
|
|
44759
|
+
retainSessions: 4,
|
|
44760
|
+
forkMaxContextRatio: 0.5
|
|
43985
44761
|
},
|
|
43986
44762
|
reminders: { todo: true, fileChanges: true, contextPressure: true, budget: true },
|
|
43987
44763
|
todo: { reminder: 10 }
|
|
@@ -43996,7 +44772,7 @@ var init_key_docs = __esm({
|
|
|
43996
44772
|
|
|
43997
44773
|
// src/ai/providers/models-dev-cache.ts
|
|
43998
44774
|
function modelsDevCachePath(dataDir) {
|
|
43999
|
-
return (0,
|
|
44775
|
+
return (0, import_node_path73.join)(dataDir, MODELS_DEV_FILE);
|
|
44000
44776
|
}
|
|
44001
44777
|
function modelsDevUrl(env = process.env) {
|
|
44002
44778
|
const custom = env[MODELS_DEV_URL_ENV]?.trim();
|
|
@@ -44004,7 +44780,7 @@ function modelsDevUrl(env = process.env) {
|
|
|
44004
44780
|
}
|
|
44005
44781
|
function readModelsDevCache(dataDir) {
|
|
44006
44782
|
try {
|
|
44007
|
-
const value = JSON.parse((0,
|
|
44783
|
+
const value = JSON.parse((0, import_node_fs51.readFileSync)(modelsDevCachePath(dataDir), "utf8"));
|
|
44008
44784
|
if (typeof value !== "object" || value === null) return void 0;
|
|
44009
44785
|
const file = value;
|
|
44010
44786
|
if (file.version !== 2 || typeof file.fetchedAt !== "string") return void 0;
|
|
@@ -44017,10 +44793,10 @@ function readModelsDevCache(dataDir) {
|
|
|
44017
44793
|
}
|
|
44018
44794
|
function writeModelsDevCache(dataDir, file) {
|
|
44019
44795
|
const path = modelsDevCachePath(dataDir);
|
|
44020
|
-
(0,
|
|
44796
|
+
(0, import_node_fs51.mkdirSync)((0, import_node_path73.dirname)(path), { recursive: true, mode: 448 });
|
|
44021
44797
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
44022
|
-
(0,
|
|
44023
|
-
(0,
|
|
44798
|
+
(0, import_node_fs51.writeFileSync)(tmp, JSON.stringify(file));
|
|
44799
|
+
(0, import_node_fs51.renameSync)(tmp, path);
|
|
44024
44800
|
memo = void 0;
|
|
44025
44801
|
}
|
|
44026
44802
|
function overrideApplies(file) {
|
|
@@ -44030,7 +44806,7 @@ function loadModelsDevIndex(dataDir) {
|
|
|
44030
44806
|
const path = modelsDevCachePath(dataDir);
|
|
44031
44807
|
let key;
|
|
44032
44808
|
try {
|
|
44033
|
-
const stat16 = (0,
|
|
44809
|
+
const stat16 = (0, import_node_fs51.statSync)(path);
|
|
44034
44810
|
key = `${path}\0${stat16.mtimeMs}\0${stat16.size}`;
|
|
44035
44811
|
} catch {
|
|
44036
44812
|
return builtinSnapshotIndex();
|
|
@@ -44115,12 +44891,12 @@ function describeRefresh(result, limit = 20) {
|
|
|
44115
44891
|
}
|
|
44116
44892
|
return lines2.join("\n");
|
|
44117
44893
|
}
|
|
44118
|
-
var
|
|
44894
|
+
var import_node_fs51, import_node_path73, MODELS_DEV_URL, MODELS_DEV_URL_ENV, MODELS_DEV_FILE, MODELS_DEV_TIMEOUT_MS, memo;
|
|
44119
44895
|
var init_models_dev_cache = __esm({
|
|
44120
44896
|
"src/ai/providers/models-dev-cache.ts"() {
|
|
44121
44897
|
"use strict";
|
|
44122
|
-
|
|
44123
|
-
|
|
44898
|
+
import_node_fs51 = require("node:fs");
|
|
44899
|
+
import_node_path73 = require("node:path");
|
|
44124
44900
|
init_models_dev();
|
|
44125
44901
|
init_models_dev_snapshot();
|
|
44126
44902
|
init_i18n();
|
|
@@ -44246,7 +45022,8 @@ function w5Sections() {
|
|
|
44246
45022
|
defaultModel: str3(),
|
|
44247
45023
|
background: oneOf(SUBAGENT_BACKGROUND_MODES),
|
|
44248
45024
|
autoBackgroundAfterMs: num2(0),
|
|
44249
|
-
retainSessions: num2(0)
|
|
45025
|
+
retainSessions: num2(0),
|
|
45026
|
+
forkMaxContextRatio: num2(0.05, 0.95)
|
|
44250
45027
|
}),
|
|
44251
45028
|
models: object({ aliases: object({ fast: str3(), strong: str3() }), enabled: strings2 }),
|
|
44252
45029
|
fallbackModel: str3(),
|
|
@@ -44464,40 +45241,40 @@ function minimalConfig() {
|
|
|
44464
45241
|
}
|
|
44465
45242
|
function writeAtomic2(path, text, mode) {
|
|
44466
45243
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
44467
|
-
(0,
|
|
44468
|
-
(0,
|
|
45244
|
+
(0, import_node_fs52.writeFileSync)(tmp, text, { mode });
|
|
45245
|
+
(0, import_node_fs52.renameSync)(tmp, path);
|
|
44469
45246
|
}
|
|
44470
45247
|
function initConfigDir(dir, options = {}) {
|
|
44471
|
-
const dirCreated = !(0,
|
|
44472
|
-
(0,
|
|
44473
|
-
if (dirCreated && process.platform !== "win32") (0,
|
|
45248
|
+
const dirCreated = !(0, import_node_fs52.existsSync)(dir);
|
|
45249
|
+
(0, import_node_fs52.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
45250
|
+
if (dirCreated && process.platform !== "win32") (0, import_node_fs52.chmodSync)(dir, 448);
|
|
44474
45251
|
const files = [];
|
|
44475
|
-
const config = (0,
|
|
45252
|
+
const config = (0, import_node_path74.join)(dir, CONFIG_FILE);
|
|
44476
45253
|
const text = `${JSON.stringify(minimalConfig(), null, 2)}
|
|
44477
45254
|
`;
|
|
44478
|
-
if (!(0,
|
|
45255
|
+
if (!(0, import_node_fs52.existsSync)(config)) {
|
|
44479
45256
|
writeAtomic2(config, text, 420);
|
|
44480
45257
|
files.push({ path: config, status: "created" });
|
|
44481
45258
|
} else if (options.force) {
|
|
44482
|
-
(0,
|
|
45259
|
+
(0, import_node_fs52.copyFileSync)(config, `${config}.bak`);
|
|
44483
45260
|
writeAtomic2(config, text, 420);
|
|
44484
45261
|
files.push({ path: config, status: "overwritten" });
|
|
44485
45262
|
} else files.push({ path: config, status: "exists" });
|
|
44486
|
-
const schema = (0,
|
|
45263
|
+
const schema = (0, import_node_path74.join)(dir, CONFIG_SCHEMA_FILE);
|
|
44487
45264
|
const schemaText = configSchemaText();
|
|
44488
|
-
if (!(0,
|
|
45265
|
+
if (!(0, import_node_fs52.existsSync)(schema)) {
|
|
44489
45266
|
writeAtomic2(schema, schemaText, 420);
|
|
44490
45267
|
files.push({ path: schema, status: "created" });
|
|
44491
|
-
} else if ((0,
|
|
45268
|
+
} else if ((0, import_node_fs52.readFileSync)(schema, "utf8") !== schemaText) {
|
|
44492
45269
|
writeAtomic2(schema, schemaText, 420);
|
|
44493
45270
|
files.push({ path: schema, status: "updated" });
|
|
44494
45271
|
} else files.push({ path: schema, status: "unchanged" });
|
|
44495
|
-
const auth = (0,
|
|
44496
|
-
if ((0,
|
|
45272
|
+
const auth = (0, import_node_path74.join)(dir, AUTH_FILE);
|
|
45273
|
+
if ((0, import_node_fs52.existsSync)(auth)) files.push({ path: auth, status: "exists" });
|
|
44497
45274
|
return { dir, dirCreated, files };
|
|
44498
45275
|
}
|
|
44499
45276
|
function autoInitConfigDir(dir, env) {
|
|
44500
|
-
if (env[NO_INIT_ENV] === "1" || (0,
|
|
45277
|
+
if (env[NO_INIT_ENV] === "1" || (0, import_node_fs52.existsSync)(dir)) return false;
|
|
44501
45278
|
try {
|
|
44502
45279
|
initConfigDir(dir);
|
|
44503
45280
|
return true;
|
|
@@ -44515,12 +45292,12 @@ function describeInit(result) {
|
|
|
44515
45292
|
return `${lines2.join("\n")}
|
|
44516
45293
|
`;
|
|
44517
45294
|
}
|
|
44518
|
-
var
|
|
45295
|
+
var import_node_fs52, import_node_path74, NO_INIT_ENV;
|
|
44519
45296
|
var init_init = __esm({
|
|
44520
45297
|
"src/config/init.ts"() {
|
|
44521
45298
|
"use strict";
|
|
44522
|
-
|
|
44523
|
-
|
|
45299
|
+
import_node_fs52 = require("node:fs");
|
|
45300
|
+
import_node_path74 = require("node:path");
|
|
44524
45301
|
init_i18n();
|
|
44525
45302
|
init_json_schema();
|
|
44526
45303
|
init_paths();
|
|
@@ -45566,6 +46343,13 @@ function recoverChatGptError(error2, model, compat, options, apiKey, tried) {
|
|
|
45566
46343
|
return { kind: "retry" };
|
|
45567
46344
|
}
|
|
45568
46345
|
}
|
|
46346
|
+
if (backend === "codex" && error2.status === 400 && /not supported when using codex with a chatgpt account/i.test(error2.body))
|
|
46347
|
+
return {
|
|
46348
|
+
kind: "fail",
|
|
46349
|
+
error: new Error(
|
|
46350
|
+
`model_unavailable: ${msg().auth.request.modelUnavailable(`${provider}/${model.id}`)}`
|
|
46351
|
+
)
|
|
46352
|
+
};
|
|
45569
46353
|
if (backend === "codex" && error2.status === 400 && /instructions are not valid/i.test(error2.body) && !tried.has("instructions")) {
|
|
45570
46354
|
tried.add("instructions");
|
|
45571
46355
|
developerMode.add(sessionKeyOf(model, options));
|
|
@@ -46233,6 +47017,10 @@ var init_sse = __esm({
|
|
|
46233
47017
|
});
|
|
46234
47018
|
|
|
46235
47019
|
// src/ai/apis/max-tokens.ts
|
|
47020
|
+
function onMaxTokensCap(listener) {
|
|
47021
|
+
capListeners.add(listener);
|
|
47022
|
+
return () => capListeners.delete(listener);
|
|
47023
|
+
}
|
|
46236
47024
|
function clampMaxTokens(requested, window2, estimatedInput, fixed) {
|
|
46237
47025
|
if (fixed || window2 === void 0 || !Number.isFinite(window2) || window2 <= 0) return requested;
|
|
46238
47026
|
const room = Math.floor(window2 - estimatedInput - OUTPUT_HEADROOM_TOKENS);
|
|
@@ -46293,14 +47081,17 @@ async function postWithMaxTokensFallback(model, url, options, field2) {
|
|
|
46293
47081
|
const sent = body[field2];
|
|
46294
47082
|
if (rejection === void 0 || !("cap" in rejection) || typeof sent !== "number") throw error2;
|
|
46295
47083
|
if (rejection.cap >= sent || !budgetFits(body, rejection.cap)) throw error2;
|
|
46296
|
-
if (!rejection.transient)
|
|
47084
|
+
if (!rejection.transient) {
|
|
47085
|
+
maxTokensCaps.set(key, rejection.cap);
|
|
47086
|
+
for (const listener of capListeners) listener(key, rejection.cap);
|
|
47087
|
+
}
|
|
46297
47088
|
return postWithCacheFallback(model, url, {
|
|
46298
47089
|
...options,
|
|
46299
47090
|
body: withCap(body, field2, rejection.cap)
|
|
46300
47091
|
});
|
|
46301
47092
|
}
|
|
46302
47093
|
}
|
|
46303
|
-
var MIN_OUTPUT_TOKENS, OUTPUT_HEADROOM_TOKENS, maxTokensCaps, NUM, toInt, RANGE, LIMIT, CONTEXT_LIMIT;
|
|
47094
|
+
var MIN_OUTPUT_TOKENS, OUTPUT_HEADROOM_TOKENS, maxTokensCaps, capListeners, NUM, toInt, RANGE, LIMIT, CONTEXT_LIMIT;
|
|
46304
47095
|
var init_max_tokens = __esm({
|
|
46305
47096
|
"src/ai/apis/max-tokens.ts"() {
|
|
46306
47097
|
"use strict";
|
|
@@ -46309,6 +47100,7 @@ var init_max_tokens = __esm({
|
|
|
46309
47100
|
MIN_OUTPUT_TOKENS = 1024;
|
|
46310
47101
|
OUTPUT_HEADROOM_TOKENS = 2048;
|
|
46311
47102
|
maxTokensCaps = /* @__PURE__ */ new Map();
|
|
47103
|
+
capListeners = /* @__PURE__ */ new Set();
|
|
46312
47104
|
NUM = "`?(\\d[\\d,_]*)`?";
|
|
46313
47105
|
toInt = (text) => Number((text ?? "").replace(/[,_]/g, ""));
|
|
46314
47106
|
RANGE = new RegExp(
|
|
@@ -47388,14 +48180,14 @@ var init_api = __esm({
|
|
|
47388
48180
|
// src/ai/providers/auth.ts
|
|
47389
48181
|
function defaultConfigDir(env = process.env) {
|
|
47390
48182
|
if (env["AMA_CONFIG_DIR"]) return env["AMA_CONFIG_DIR"];
|
|
47391
|
-
if (process.platform === "win32" && env["APPDATA"]) return (0,
|
|
47392
|
-
if (env["XDG_CONFIG_HOME"]) return (0,
|
|
47393
|
-
return (0,
|
|
48183
|
+
if (process.platform === "win32" && env["APPDATA"]) return (0, import_node_path75.join)(env["APPDATA"], "ama");
|
|
48184
|
+
if (env["XDG_CONFIG_HOME"]) return (0, import_node_path75.join)(env["XDG_CONFIG_HOME"], "ama");
|
|
48185
|
+
return (0, import_node_path75.join)(env["HOME"] ?? (0, import_node_os12.homedir)(), ".config", "ama");
|
|
47394
48186
|
}
|
|
47395
48187
|
function readAuthFile2(path, onWarning) {
|
|
47396
48188
|
let raw;
|
|
47397
48189
|
try {
|
|
47398
|
-
raw = (0,
|
|
48190
|
+
raw = (0, import_node_fs53.readFileSync)(path, "utf8");
|
|
47399
48191
|
} catch (error2) {
|
|
47400
48192
|
const code = error2.code;
|
|
47401
48193
|
if (code !== "ENOENT") onWarning?.(`cannot read auth file ${path}`);
|
|
@@ -47403,7 +48195,7 @@ function readAuthFile2(path, onWarning) {
|
|
|
47403
48195
|
}
|
|
47404
48196
|
if (process.platform !== "win32") {
|
|
47405
48197
|
try {
|
|
47406
|
-
const mode = (0,
|
|
48198
|
+
const mode = (0, import_node_fs53.statSync)(path).mode & 511;
|
|
47407
48199
|
if ((mode & 63) !== 0) {
|
|
47408
48200
|
onWarning?.(
|
|
47409
48201
|
`auth file ${path} has permissions ${mode.toString(8).padStart(4, "0")}; expected 0600`
|
|
@@ -47437,14 +48229,14 @@ function expandEnvRefs(value, env) {
|
|
|
47437
48229
|
);
|
|
47438
48230
|
return missing || out.length === 0 ? void 0 : out;
|
|
47439
48231
|
}
|
|
47440
|
-
var import_node_child_process13,
|
|
48232
|
+
var import_node_child_process13, import_node_fs53, import_node_os12, import_node_path75, ApiKeyResolver;
|
|
47441
48233
|
var init_auth2 = __esm({
|
|
47442
48234
|
"src/ai/providers/auth.ts"() {
|
|
47443
48235
|
"use strict";
|
|
47444
48236
|
import_node_child_process13 = require("node:child_process");
|
|
47445
|
-
|
|
47446
|
-
|
|
47447
|
-
|
|
48237
|
+
import_node_fs53 = require("node:fs");
|
|
48238
|
+
import_node_os12 = require("node:os");
|
|
48239
|
+
import_node_path75 = require("node:path");
|
|
47448
48240
|
init_live();
|
|
47449
48241
|
init_refresh();
|
|
47450
48242
|
init_token_store();
|
|
@@ -47464,7 +48256,7 @@ var init_auth2 = __esm({
|
|
|
47464
48256
|
authFiles() {
|
|
47465
48257
|
const files = [];
|
|
47466
48258
|
if (this.options.authFile) files.push(this.options.authFile);
|
|
47467
|
-
const user = this.options.userAuthFile === void 0 ? (0,
|
|
48259
|
+
const user = this.options.userAuthFile === void 0 ? (0, import_node_path75.join)(defaultConfigDir(this.env), "auth.json") : this.options.userAuthFile;
|
|
47468
48260
|
if (user && !files.includes(user)) files.push(user);
|
|
47469
48261
|
return files;
|
|
47470
48262
|
}
|
|
@@ -47852,9 +48644,8 @@ var init_registry2 = __esm({
|
|
|
47852
48644
|
(name) => this.warn(`model "${id}/${modelId}" channel "${name}" not found; ignored`)
|
|
47853
48645
|
);
|
|
47854
48646
|
for (const entry of config.models ?? []) {
|
|
47855
|
-
const { entry: filled, metadata } = enrichEntry(entry, this.modelsDev);
|
|
47856
|
-
|
|
47857
|
-
this.warn(`modelsDev "${entry.modelsDev}" for "${id}/${entry.id}" not found`);
|
|
48647
|
+
const { entry: filled, metadata } = enrichEntry(entry, this.modelsDev, id);
|
|
48648
|
+
for (const warning of metadata.warnings ?? []) this.warn(warning);
|
|
47858
48649
|
const model = withCustomDefaults(filled, id, entry.api ?? provider.api);
|
|
47859
48650
|
if (provider.channels !== void 0 && (entry.channels !== void 0 || !provider.builtin))
|
|
47860
48651
|
model.channels = channelsOf(entry.channels, entry.id);
|
|
@@ -48207,6 +48998,7 @@ var init_settings_registry = __esm({
|
|
|
48207
48998
|
row2("subagents.maxConcurrent", "agents", "nextSession", "deny"),
|
|
48208
48999
|
row2("subagents.maxPending", "agents", "nextSession", "deny"),
|
|
48209
49000
|
row2("subagents.retainSessions", "agents", "nextSession", "deny"),
|
|
49001
|
+
row2("subagents.forkMaxContextRatio", "agents", "nextSession", "deny"),
|
|
48210
49002
|
// [W7-B2] 改 task 工具描述(缺省后台 / 前台两种文案),故 prefix
|
|
48211
49003
|
row2("subagents.background", "agents", "restart", "any", { prefix: true }),
|
|
48212
49004
|
row2("subagents.autoBackgroundAfterMs", "agents", "restart", "any"),
|
|
@@ -48230,26 +49022,26 @@ var init_settings_registry = __esm({
|
|
|
48230
49022
|
|
|
48231
49023
|
// src/config/write.ts
|
|
48232
49024
|
function writeConfigFile(path, config, options = {}) {
|
|
48233
|
-
(0,
|
|
49025
|
+
(0, import_node_fs54.mkdirSync)((0, import_node_path77.dirname)(path), { recursive: true });
|
|
48234
49026
|
let mode;
|
|
48235
49027
|
try {
|
|
48236
|
-
mode = (0,
|
|
49028
|
+
mode = (0, import_node_fs54.statSync)(path).mode & 511;
|
|
48237
49029
|
} catch {
|
|
48238
49030
|
mode = void 0;
|
|
48239
49031
|
}
|
|
48240
|
-
if (mode !== void 0 && options.backup !== false) (0,
|
|
49032
|
+
if (mode !== void 0 && options.backup !== false) (0, import_node_fs54.copyFileSync)(path, `${path}.bak`);
|
|
48241
49033
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
48242
|
-
(0,
|
|
49034
|
+
(0, import_node_fs54.writeFileSync)(tmp, `${JSON.stringify(config, null, 2)}
|
|
48243
49035
|
`, { mode: mode ?? 420 });
|
|
48244
|
-
if (mode !== void 0) (0,
|
|
48245
|
-
(0,
|
|
49036
|
+
if (mode !== void 0) (0, import_node_fs54.chmodSync)(tmp, mode);
|
|
49037
|
+
(0, import_node_fs54.renameSync)(tmp, path);
|
|
48246
49038
|
}
|
|
48247
|
-
var
|
|
49039
|
+
var import_node_fs54, import_node_path77;
|
|
48248
49040
|
var init_write2 = __esm({
|
|
48249
49041
|
"src/config/write.ts"() {
|
|
48250
49042
|
"use strict";
|
|
48251
|
-
|
|
48252
|
-
|
|
49043
|
+
import_node_fs54 = require("node:fs");
|
|
49044
|
+
import_node_path77 = require("node:path");
|
|
48253
49045
|
}
|
|
48254
49046
|
});
|
|
48255
49047
|
|
|
@@ -48447,7 +49239,7 @@ function parseEnum(key, text, options) {
|
|
|
48447
49239
|
function readTarget(path, scope) {
|
|
48448
49240
|
let text;
|
|
48449
49241
|
try {
|
|
48450
|
-
text = (0,
|
|
49242
|
+
text = (0, import_node_fs55.readFileSync)(path, "utf8");
|
|
48451
49243
|
} catch (error2) {
|
|
48452
49244
|
if (error2.code === "ENOENT")
|
|
48453
49245
|
return scope === "user" ? minimalConfig() : { version: CONFIG_FILE_VERSION };
|
|
@@ -48529,11 +49321,11 @@ function formatSettingValue(value) {
|
|
|
48529
49321
|
if (typeof value === "string") return value;
|
|
48530
49322
|
return JSON.stringify(value);
|
|
48531
49323
|
}
|
|
48532
|
-
var
|
|
49324
|
+
var import_node_fs55, ConfigEditError, same, ABOVE, TRUE, FALSE, UNSET;
|
|
48533
49325
|
var init_edit2 = __esm({
|
|
48534
49326
|
"src/config/edit.ts"() {
|
|
48535
49327
|
"use strict";
|
|
48536
|
-
|
|
49328
|
+
import_node_fs55 = require("node:fs");
|
|
48537
49329
|
init_errors();
|
|
48538
49330
|
init_i18n();
|
|
48539
49331
|
init_init();
|
|
@@ -48609,11 +49401,11 @@ async function readClipboardImage(dataDir, deps = {}) {
|
|
|
48609
49401
|
const platform = deps.platform ?? process.platform;
|
|
48610
49402
|
const env = deps.env ?? process.env;
|
|
48611
49403
|
const run7 = deps.run ?? runCommand;
|
|
48612
|
-
const dir = (0,
|
|
49404
|
+
const dir = (0, import_node_path80.join)(dataDir, CLIPBOARD_DIR);
|
|
48613
49405
|
await (0, import_promises22.mkdir)(dir, { recursive: true });
|
|
48614
49406
|
const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[:.]/g, "-");
|
|
48615
|
-
let file = (0,
|
|
48616
|
-
for (let n = 1; (0,
|
|
49407
|
+
let file = (0, import_node_path80.join)(dir, `${stamp}.png`);
|
|
49408
|
+
for (let n = 1; (0, import_node_fs61.existsSync)(file); n++) file = (0, import_node_path80.join)(dir, `${stamp}-${n}.png`);
|
|
48617
49409
|
let anyTool = false;
|
|
48618
49410
|
for (const attempt of attempts(platform, file, env)) {
|
|
48619
49411
|
const options = attempt.via === "file" && attempt.env !== void 0 ? { env: attempt.env } : {};
|
|
@@ -48632,7 +49424,7 @@ async function readClipboardImage(dataDir, deps = {}) {
|
|
|
48632
49424
|
return { ok: false, reason: anyTool ? "no_image" : "no_tool" };
|
|
48633
49425
|
}
|
|
48634
49426
|
async function gcClipboardImages(dataDir, options = {}) {
|
|
48635
|
-
const dir = (0,
|
|
49427
|
+
const dir = (0, import_node_path80.join)(dataDir, CLIPBOARD_DIR);
|
|
48636
49428
|
let names;
|
|
48637
49429
|
try {
|
|
48638
49430
|
names = await (0, import_promises22.readdir)(dir);
|
|
@@ -48642,7 +49434,7 @@ async function gcClipboardImages(dataDir, options = {}) {
|
|
|
48642
49434
|
const cutoff = (options.now ?? Date.now()) - (options.maxAgeDays ?? CLIPBOARD_MAX_AGE_DAYS) * 864e5;
|
|
48643
49435
|
const removed = [];
|
|
48644
49436
|
for (const name of names) {
|
|
48645
|
-
const file = (0,
|
|
49437
|
+
const file = (0, import_node_path80.join)(dir, name);
|
|
48646
49438
|
try {
|
|
48647
49439
|
const info2 = await (0, import_promises22.stat)(file);
|
|
48648
49440
|
if (!info2.isFile() || info2.mtimeMs >= cutoff) continue;
|
|
@@ -48653,13 +49445,13 @@ async function gcClipboardImages(dataDir, options = {}) {
|
|
|
48653
49445
|
}
|
|
48654
49446
|
return removed;
|
|
48655
49447
|
}
|
|
48656
|
-
var
|
|
49448
|
+
var import_node_fs61, import_promises22, import_node_path80, CLIPBOARD_DIR, CLIPBOARD_MAX_AGE_DAYS, OSASCRIPT, POWERSHELL;
|
|
48657
49449
|
var init_clipboard_image = __esm({
|
|
48658
49450
|
"src/tools/clipboard-image.ts"() {
|
|
48659
49451
|
"use strict";
|
|
48660
|
-
|
|
49452
|
+
import_node_fs61 = require("node:fs");
|
|
48661
49453
|
import_promises22 = require("node:fs/promises");
|
|
48662
|
-
|
|
49454
|
+
import_node_path80 = require("node:path");
|
|
48663
49455
|
init_image_file();
|
|
48664
49456
|
init_image_resize();
|
|
48665
49457
|
CLIPBOARD_DIR = "clipboard";
|
|
@@ -50046,7 +50838,7 @@ function statusCost(stats) {
|
|
|
50046
50838
|
function layoutRow(parts, width2, theme, style = {}) {
|
|
50047
50839
|
const sep5 = style.sep ?? " · ";
|
|
50048
50840
|
const dim = (text) => text === "" ? "" : theme.fg("dim", text);
|
|
50049
|
-
const
|
|
50841
|
+
const join68 = (list5) => {
|
|
50050
50842
|
let out = "";
|
|
50051
50843
|
let size = 0;
|
|
50052
50844
|
const add3 = (text, measured = visibleWidth(text)) => {
|
|
@@ -50078,7 +50870,7 @@ function layoutRow(parts, width2, theme, style = {}) {
|
|
|
50078
50870
|
const left = zone("left");
|
|
50079
50871
|
const right = zone("right");
|
|
50080
50872
|
const between = left.length === 0 || right.length === 0 ? 0 : sep5.length;
|
|
50081
|
-
return
|
|
50873
|
+
return join68(left)[1] + between + join68(right)[1] <= width2;
|
|
50082
50874
|
};
|
|
50083
50875
|
while (!fits()) {
|
|
50084
50876
|
const droppable = kept.filter((p) => p.priority !== void 0);
|
|
@@ -50086,8 +50878,8 @@ function layoutRow(parts, width2, theme, style = {}) {
|
|
|
50086
50878
|
const drop = droppable.reduce((worst, p) => p.priority > worst.priority ? p : worst);
|
|
50087
50879
|
kept = kept.filter((p) => p !== drop);
|
|
50088
50880
|
}
|
|
50089
|
-
const l =
|
|
50090
|
-
const r =
|
|
50881
|
+
const l = join68(zone("left"))[0];
|
|
50882
|
+
const r = join68(zone("right"))[0];
|
|
50091
50883
|
const gap = width2 - visibleWidth(l) - visibleWidth(r);
|
|
50092
50884
|
const line2 = r === "" ? l : l === "" ? " ".repeat(Math.max(0, gap)) + r : gap >= MIN_GAP ? l + " ".repeat(gap) + r : l + dim(sep5) + r;
|
|
50093
50885
|
return truncateToWidth(line2, width2);
|
|
@@ -50346,9 +51138,9 @@ function flat(text, max = 120) {
|
|
|
50346
51138
|
return one.length > max ? `${one.slice(0, max - 1)}…` : one;
|
|
50347
51139
|
}
|
|
50348
51140
|
function displayPath2(path, cwd) {
|
|
50349
|
-
if (cwd === void 0 || !(0,
|
|
50350
|
-
const rel = (0,
|
|
50351
|
-
return rel === "" ? "." : rel.startsWith("..") || (0,
|
|
51141
|
+
if (cwd === void 0 || !(0, import_node_path85.isAbsolute)(path)) return path;
|
|
51142
|
+
const rel = (0, import_node_path85.relative)(cwd, path);
|
|
51143
|
+
return rel === "" ? "." : rel.startsWith("..") || (0, import_node_path85.isAbsolute)(rel) ? path : rel;
|
|
50352
51144
|
}
|
|
50353
51145
|
function toolSummary(name, args, cwd) {
|
|
50354
51146
|
if (typeof args !== "object" || args === null) return "";
|
|
@@ -50503,12 +51295,12 @@ function resultSummary(input2, theme) {
|
|
|
50503
51295
|
return muted(count2 === 0 ? m.done : m.outputLines(count2));
|
|
50504
51296
|
}
|
|
50505
51297
|
}
|
|
50506
|
-
var
|
|
51298
|
+
var import_node_path85;
|
|
50507
51299
|
var init_tool_summary = __esm({
|
|
50508
51300
|
"src/modes/interactive/tool-summary.ts"() {
|
|
50509
51301
|
"use strict";
|
|
50510
51302
|
init_i18n();
|
|
50511
|
-
|
|
51303
|
+
import_node_path85 = require("node:path");
|
|
50512
51304
|
init_tui2();
|
|
50513
51305
|
init_status_bar();
|
|
50514
51306
|
}
|
|
@@ -51325,7 +52117,7 @@ function childLoader(read2 = readTraceInput) {
|
|
|
51325
52117
|
const load2 = ((file) => {
|
|
51326
52118
|
let stamp = "";
|
|
51327
52119
|
try {
|
|
51328
|
-
const st = (0,
|
|
52120
|
+
const st = (0, import_node_fs64.statSync)(file);
|
|
51329
52121
|
stamp = `${st.mtimeMs}:${st.size}`;
|
|
51330
52122
|
} catch {
|
|
51331
52123
|
stamp = "missing";
|
|
@@ -51369,11 +52161,11 @@ function traceText(session, taskId) {
|
|
|
51369
52161
|
`${msg().trace.taskTitle(node.taskId, node.agent)}${summary2}`
|
|
51370
52162
|
);
|
|
51371
52163
|
}
|
|
51372
|
-
var
|
|
52164
|
+
var import_node_fs64, LiveTracker, lineTraceCommand;
|
|
51373
52165
|
var init_session3 = __esm({
|
|
51374
52166
|
"src/trace/session.ts"() {
|
|
51375
52167
|
"use strict";
|
|
51376
|
-
|
|
52168
|
+
import_node_fs64 = require("node:fs");
|
|
51377
52169
|
init_session2();
|
|
51378
52170
|
init_i18n();
|
|
51379
52171
|
init_scan();
|
|
@@ -51447,10 +52239,10 @@ var init_session3 = __esm({
|
|
|
51447
52239
|
|
|
51448
52240
|
// src/skills/builtin.ts
|
|
51449
52241
|
function builtinSkillPath(dataDir, name) {
|
|
51450
|
-
return (0,
|
|
52242
|
+
return (0, import_node_path88.join)(dataDir, BUILTIN_SKILLS_DIR, `${name}.md`);
|
|
51451
52243
|
}
|
|
51452
52244
|
function isBuiltinSkill(skill) {
|
|
51453
|
-
return BUILTIN_SKILLS.some((b) => b.name === skill.name) && skill.location.endsWith((0,
|
|
52245
|
+
return BUILTIN_SKILLS.some((b) => b.name === skill.name) && skill.location.endsWith((0, import_node_path88.join)(BUILTIN_SKILLS_DIR, `${skill.name}.md`));
|
|
51454
52246
|
}
|
|
51455
52247
|
function builtinSkillText(skill) {
|
|
51456
52248
|
return `---
|
|
@@ -51465,7 +52257,7 @@ async function ensureFile(path, text) {
|
|
|
51465
52257
|
if (await (0, import_promises23.readFile)(path, "utf8") === text) return;
|
|
51466
52258
|
} catch {
|
|
51467
52259
|
}
|
|
51468
|
-
await (0, import_promises23.mkdir)((0,
|
|
52260
|
+
await (0, import_promises23.mkdir)((0, import_node_path88.dirname)(path), { recursive: true });
|
|
51469
52261
|
await (0, import_promises23.writeFile)(path, text, "utf8");
|
|
51470
52262
|
}
|
|
51471
52263
|
async function withBuiltinSkills(skills, dataDir, builtins = BUILTIN_SKILLS) {
|
|
@@ -51474,7 +52266,7 @@ async function withBuiltinSkills(skills, dataDir, builtins = BUILTIN_SKILLS) {
|
|
|
51474
52266
|
const taken = new Set(skills.map((skill) => skill.name));
|
|
51475
52267
|
for (const builtin2 of builtins) {
|
|
51476
52268
|
if (taken.has(builtin2.name)) continue;
|
|
51477
|
-
const baseDir = (0,
|
|
52269
|
+
const baseDir = (0, import_node_path88.join)(dataDir, BUILTIN_SKILLS_DIR);
|
|
51478
52270
|
const location = builtinSkillPath(dataDir, builtin2.name);
|
|
51479
52271
|
try {
|
|
51480
52272
|
await ensureFile(location, builtinSkillText(builtin2));
|
|
@@ -51495,12 +52287,12 @@ async function withBuiltinSkills(skills, dataDir, builtins = BUILTIN_SKILLS) {
|
|
|
51495
52287
|
}
|
|
51496
52288
|
return { skills: out, warnings };
|
|
51497
52289
|
}
|
|
51498
|
-
var import_promises23,
|
|
52290
|
+
var import_promises23, import_node_path88, BUILTIN_SKILLS_DIR, AMA_DOCS_BODY, BUILTIN_SKILLS;
|
|
51499
52291
|
var init_builtin3 = __esm({
|
|
51500
52292
|
"src/skills/builtin.ts"() {
|
|
51501
52293
|
"use strict";
|
|
51502
52294
|
import_promises23 = require("node:fs/promises");
|
|
51503
|
-
|
|
52295
|
+
import_node_path88 = require("node:path");
|
|
51504
52296
|
BUILTIN_SKILLS_DIR = "builtin";
|
|
51505
52297
|
AMA_DOCS_BODY = `# ama quick reference
|
|
51506
52298
|
|
|
@@ -51553,33 +52345,33 @@ Skills: \`<dir>/<name>/SKILL.md\` with \`name\` and \`description\` frontmatter
|
|
|
51553
52345
|
// src/skills/discover.ts
|
|
51554
52346
|
function ancestorDirs(cwd) {
|
|
51555
52347
|
const out = [];
|
|
51556
|
-
let dir = (0,
|
|
52348
|
+
let dir = (0, import_node_path89.resolve)(cwd);
|
|
51557
52349
|
for (; ; ) {
|
|
51558
52350
|
out.push(dir);
|
|
51559
|
-
if ((0,
|
|
51560
|
-
const parent = (0,
|
|
52351
|
+
if ((0, import_node_fs66.existsSync)((0, import_node_path89.join)(dir, ".git"))) return out;
|
|
52352
|
+
const parent = (0, import_node_path89.dirname)(dir);
|
|
51561
52353
|
if (parent === dir) return out;
|
|
51562
52354
|
dir = parent;
|
|
51563
52355
|
}
|
|
51564
52356
|
}
|
|
51565
52357
|
function skillSources(options) {
|
|
51566
52358
|
const sources = [];
|
|
51567
|
-
const add3 = (dir, scope, requiresTrust) => sources.push({ dir: (0,
|
|
52359
|
+
const add3 = (dir, scope, requiresTrust) => sources.push({ dir: (0, import_node_path89.resolve)(options.cwd, dir), scope, requiresTrust });
|
|
51568
52360
|
for (const d of options.cliDirs ?? []) add3(d, "cli", false);
|
|
51569
52361
|
for (const d of options.profileDirs ?? []) add3(d, "profile", false);
|
|
51570
52362
|
for (const d of options.configDirs ?? []) add3(d, "config", false);
|
|
51571
|
-
add3((0,
|
|
51572
|
-
add3((0,
|
|
51573
|
-
for (const d of ancestorDirs(options.cwd)) add3((0,
|
|
52363
|
+
add3((0, import_node_path89.join)(options.configDir, "skills"), "user", false);
|
|
52364
|
+
add3((0, import_node_path89.join)(options.cwd, ".ama", "skills"), "project", true);
|
|
52365
|
+
for (const d of ancestorDirs(options.cwd)) add3((0, import_node_path89.join)(d, ".agents", "skills"), "ancestor", true);
|
|
51574
52366
|
return sources;
|
|
51575
52367
|
}
|
|
51576
52368
|
function parseSkill(text, location, scope) {
|
|
51577
52369
|
const warnings = [];
|
|
51578
52370
|
const fm = parseFrontmatter(text);
|
|
51579
52371
|
for (const e of fm.errors) warnings.push(`${location}: ${e}`);
|
|
51580
|
-
const baseDir = (0,
|
|
52372
|
+
const baseDir = (0, import_node_path89.dirname)(location);
|
|
51581
52373
|
const rawName = fm.data["name"];
|
|
51582
|
-
const name = typeof rawName === "string" && rawName !== "" ? rawName : (0,
|
|
52374
|
+
const name = typeof rawName === "string" && rawName !== "" ? rawName : (0, import_node_path89.basename)(baseDir);
|
|
51583
52375
|
if (name.length > MAX_SKILL_NAME || !SKILL_NAME_RE.test(name)) {
|
|
51584
52376
|
warnings.push(`${location}: invalid skill name "${name}" (lowercase letters, digits, -)`);
|
|
51585
52377
|
return { warnings };
|
|
@@ -51617,8 +52409,8 @@ async function isDir3(path) {
|
|
|
51617
52409
|
}
|
|
51618
52410
|
async function findSkillFiles(dir, depth = 0) {
|
|
51619
52411
|
if (depth > MAX_DEPTH3) return [];
|
|
51620
|
-
const own = (0,
|
|
51621
|
-
if ((0,
|
|
52412
|
+
const own = (0, import_node_path89.join)(dir, SKILL_FILE);
|
|
52413
|
+
if ((0, import_node_fs66.existsSync)(own)) return [own];
|
|
51622
52414
|
let names;
|
|
51623
52415
|
try {
|
|
51624
52416
|
names = await (0, import_promises24.readdir)(dir);
|
|
@@ -51629,7 +52421,7 @@ async function findSkillFiles(dir, depth = 0) {
|
|
|
51629
52421
|
const out = [];
|
|
51630
52422
|
for (const name of names) {
|
|
51631
52423
|
if (SKIP_DIRS.has(name)) continue;
|
|
51632
|
-
const child = (0,
|
|
52424
|
+
const child = (0, import_node_path89.join)(dir, name);
|
|
51633
52425
|
if (await isDir3(child)) out.push(...await findSkillFiles(child, depth + 1));
|
|
51634
52426
|
}
|
|
51635
52427
|
return out;
|
|
@@ -51670,13 +52462,13 @@ async function discoverSkills(sources, options) {
|
|
|
51670
52462
|
}
|
|
51671
52463
|
return result;
|
|
51672
52464
|
}
|
|
51673
|
-
var
|
|
52465
|
+
var import_node_fs66, import_promises24, import_node_path89, SKILL_FILE, SKILL_NAME_RE, MAX_SKILL_NAME, MAX_SKILL_DESCRIPTION, MAX_DEPTH3, SKIP_DIRS;
|
|
51674
52466
|
var init_discover2 = __esm({
|
|
51675
52467
|
"src/skills/discover.ts"() {
|
|
51676
52468
|
"use strict";
|
|
51677
|
-
|
|
52469
|
+
import_node_fs66 = require("node:fs");
|
|
51678
52470
|
import_promises24 = require("node:fs/promises");
|
|
51679
|
-
|
|
52471
|
+
import_node_path89 = require("node:path");
|
|
51680
52472
|
init_frontmatter2();
|
|
51681
52473
|
SKILL_FILE = "SKILL.md";
|
|
51682
52474
|
SKILL_NAME_RE = /^[a-z0-9-]+$/;
|
|
@@ -51791,14 +52583,14 @@ var init_protocol2 = __esm({
|
|
|
51791
52583
|
|
|
51792
52584
|
// src/codemode/host-side.ts
|
|
51793
52585
|
function resolveSandboxEntry(moduleUrl = __ama_import_meta_url) {
|
|
51794
|
-
const here = (0,
|
|
52586
|
+
const here = (0, import_node_path90.dirname)((0, import_node_url2.fileURLToPath)(moduleUrl));
|
|
51795
52587
|
const candidates2 = [];
|
|
51796
52588
|
if (true)
|
|
51797
|
-
candidates2.push((0,
|
|
51798
|
-
candidates2.push((0,
|
|
51799
|
-
candidates2.push((0,
|
|
52589
|
+
candidates2.push((0, import_node_path90.join)(here, "ama-sandbox.cjs"));
|
|
52590
|
+
candidates2.push((0, import_node_path90.join)(here, "sandbox-entry.js"));
|
|
52591
|
+
candidates2.push((0, import_node_path90.join)(here, "sandbox-entry.ts"));
|
|
51800
52592
|
for (const candidate of candidates2) {
|
|
51801
|
-
if ((0,
|
|
52593
|
+
if ((0, import_node_fs67.existsSync)(candidate)) return (0, import_node_fs67.realpathSync)(candidate);
|
|
51802
52594
|
}
|
|
51803
52595
|
return void 0;
|
|
51804
52596
|
}
|
|
@@ -52030,13 +52822,13 @@ async function runSandbox(request) {
|
|
|
52030
52822
|
child.stdin.end();
|
|
52031
52823
|
return result;
|
|
52032
52824
|
}
|
|
52033
|
-
var import_node_child_process16,
|
|
52825
|
+
var import_node_child_process16, import_node_fs67, import_node_path90, import_node_url2, MAX_COLLECTED_OUTPUT_CHARS, ABORT_GRACE_MS, DEFAULT_CODEMODE_HEAP_MB, CODEMODE_OS_POLICY;
|
|
52034
52826
|
var init_host_side = __esm({
|
|
52035
52827
|
"src/codemode/host-side.ts"() {
|
|
52036
52828
|
"use strict";
|
|
52037
52829
|
import_node_child_process16 = require("node:child_process");
|
|
52038
|
-
|
|
52039
|
-
|
|
52830
|
+
import_node_fs67 = require("node:fs");
|
|
52831
|
+
import_node_path90 = require("node:path");
|
|
52040
52832
|
import_node_url2 = require("node:url");
|
|
52041
52833
|
init_detect();
|
|
52042
52834
|
init_wrap();
|
|
@@ -52098,7 +52890,7 @@ var init_store5 = __esm({
|
|
|
52098
52890
|
});
|
|
52099
52891
|
|
|
52100
52892
|
// src/codemode/tool.ts
|
|
52101
|
-
function
|
|
52893
|
+
function textOf5(content) {
|
|
52102
52894
|
if (typeof content === "string") return content;
|
|
52103
52895
|
return content.map((block) => block.type === "text" ? block.text : "").join("");
|
|
52104
52896
|
}
|
|
@@ -52117,8 +52909,8 @@ function toScriptValue(name, result) {
|
|
|
52117
52909
|
if (s2.full_output_path !== void 0) value.fullOutputPath = s2.full_output_path;
|
|
52118
52910
|
return value;
|
|
52119
52911
|
}
|
|
52120
|
-
if (result.isError === true) throw new Error(
|
|
52121
|
-
return result.structured !== void 0 ? result.structured :
|
|
52912
|
+
if (result.isError === true) throw new Error(textOf5(result.content) || `Tool ${name} failed`);
|
|
52913
|
+
return result.structured !== void 0 ? result.structured : textOf5(result.content);
|
|
52122
52914
|
}
|
|
52123
52915
|
function scriptErrorHint(error2, toolNames2) {
|
|
52124
52916
|
if (/Cannot use import statement|dynamic import callback/.test(error2) || SCRIPT_ONLY_GLOBALS.test(error2)) {
|
|
@@ -52200,10 +52992,10 @@ ${output.slice(-half)}`;
|
|
|
52200
52992
|
}
|
|
52201
52993
|
function saveFullOutput(ctx, text) {
|
|
52202
52994
|
try {
|
|
52203
|
-
const dir = ctx.outputDir ?? (0,
|
|
52204
|
-
(0,
|
|
52205
|
-
const file = (0,
|
|
52206
|
-
(0,
|
|
52995
|
+
const dir = ctx.outputDir ?? (0, import_node_path91.join)((0, import_node_os14.tmpdir)(), "ama-codemode");
|
|
52996
|
+
(0, import_node_fs68.mkdirSync)(dir, { recursive: true });
|
|
52997
|
+
const file = (0, import_node_path91.join)(dir, `${ctx.toolCallId.replace(/[^A-Za-z0-9_-]/g, "_")}.txt`);
|
|
52998
|
+
(0, import_node_fs68.writeFileSync)(file, text, "utf8");
|
|
52207
52999
|
return file;
|
|
52208
53000
|
} catch {
|
|
52209
53001
|
return void 0;
|
|
@@ -52309,7 +53101,7 @@ function createCodemodeTool(options) {
|
|
|
52309
53101
|
return shown2;
|
|
52310
53102
|
},
|
|
52311
53103
|
renderResult(result, width2, expanded) {
|
|
52312
|
-
const lines2 =
|
|
53104
|
+
const lines2 = textOf5(result.content).split("\n");
|
|
52313
53105
|
const clip4 = (line2) => line2.slice(0, Math.max(10, width2));
|
|
52314
53106
|
if (expanded || lines2.length <= 8) return lines2.map(clip4);
|
|
52315
53107
|
return [clip4(lines2[0] ?? ""), `… ${lines2.length - 6} lines`, ...lines2.slice(-5).map(clip4)];
|
|
@@ -52355,13 +53147,13 @@ function codemodeToolFactory(overrides = {}) {
|
|
|
52355
53147
|
return createCodemodeTool(options);
|
|
52356
53148
|
};
|
|
52357
53149
|
}
|
|
52358
|
-
var
|
|
53150
|
+
var import_node_fs68, import_node_os14, import_node_path91, CODEMODE_TOOL_NAME2, DEFAULT_MAX_TOOL_RESULT_CHARS2, CODEMODE_EXAMPLE, SCRIPT_ONLY_GLOBALS, TAIL_CHARS, CODEMODE_ONLY_GUIDELINE;
|
|
52359
53151
|
var init_tool = __esm({
|
|
52360
53152
|
"src/codemode/tool.ts"() {
|
|
52361
53153
|
"use strict";
|
|
52362
|
-
|
|
52363
|
-
|
|
52364
|
-
|
|
53154
|
+
import_node_fs68 = require("node:fs");
|
|
53155
|
+
import_node_os14 = require("node:os");
|
|
53156
|
+
import_node_path91 = require("node:path");
|
|
52365
53157
|
init_presets2();
|
|
52366
53158
|
init_capability();
|
|
52367
53159
|
init_declarations();
|
|
@@ -52473,7 +53265,7 @@ var init_tool2 = __esm({
|
|
|
52473
53265
|
// src/cli/codemode-notice.ts
|
|
52474
53266
|
function readNotices(path) {
|
|
52475
53267
|
try {
|
|
52476
|
-
const value = JSON.parse((0,
|
|
53268
|
+
const value = JSON.parse((0, import_node_fs69.readFileSync)(path, "utf8"));
|
|
52477
53269
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
52478
53270
|
const shown2 = value[KEY];
|
|
52479
53271
|
return {
|
|
@@ -52492,26 +53284,26 @@ function takeCodemodeNotice(input2) {
|
|
|
52492
53284
|
const resolved = resolveCodemodeMode(input2.config, input2.capability.strict);
|
|
52493
53285
|
if (resolved.source !== "preset" || resolved.preset !== "default" || input2.capability.strict)
|
|
52494
53286
|
return void 0;
|
|
52495
|
-
const path = (0,
|
|
53287
|
+
const path = (0, import_node_path92.join)(input2.dataDir, NOTICES_FILE);
|
|
52496
53288
|
const notices = readNotices(path);
|
|
52497
53289
|
const shown2 = notices[KEY] ?? [];
|
|
52498
53290
|
if (shown2.includes(input2.configDir)) return void 0;
|
|
52499
53291
|
try {
|
|
52500
|
-
(0,
|
|
53292
|
+
(0, import_node_fs69.mkdirSync)(input2.dataDir, { recursive: true });
|
|
52501
53293
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
52502
|
-
(0,
|
|
53294
|
+
(0, import_node_fs69.writeFileSync)(tmp, `${JSON.stringify({ ...notices, [KEY]: [...shown2, input2.configDir] })}
|
|
52503
53295
|
`);
|
|
52504
|
-
(0,
|
|
53296
|
+
(0, import_node_fs69.renameSync)(tmp, path);
|
|
52505
53297
|
} catch {
|
|
52506
53298
|
}
|
|
52507
53299
|
return codemodeNoticeText(input2.capability);
|
|
52508
53300
|
}
|
|
52509
|
-
var
|
|
53301
|
+
var import_node_fs69, import_node_path92, NOTICES_FILE, KEY;
|
|
52510
53302
|
var init_codemode_notice = __esm({
|
|
52511
53303
|
"src/cli/codemode-notice.ts"() {
|
|
52512
53304
|
"use strict";
|
|
52513
|
-
|
|
52514
|
-
|
|
53305
|
+
import_node_fs69 = require("node:fs");
|
|
53306
|
+
import_node_path92 = require("node:path");
|
|
52515
53307
|
init_presets2();
|
|
52516
53308
|
init_i18n();
|
|
52517
53309
|
NOTICES_FILE = "notices.json";
|
|
@@ -52519,6 +53311,81 @@ var init_codemode_notice = __esm({
|
|
|
52519
53311
|
}
|
|
52520
53312
|
});
|
|
52521
53313
|
|
|
53314
|
+
// src/ai/providers/max-tokens-cache.ts
|
|
53315
|
+
function maxTokensCachePath(dataDir) {
|
|
53316
|
+
return (0, import_node_path93.join)(dataDir, "models", "max-tokens-caps.json");
|
|
53317
|
+
}
|
|
53318
|
+
function readEntries(dataDir, now) {
|
|
53319
|
+
const out = /* @__PURE__ */ new Map();
|
|
53320
|
+
let parsed;
|
|
53321
|
+
try {
|
|
53322
|
+
parsed = JSON.parse((0, import_node_fs70.readFileSync)(maxTokensCachePath(dataDir), "utf8"));
|
|
53323
|
+
} catch {
|
|
53324
|
+
return out;
|
|
53325
|
+
}
|
|
53326
|
+
if (typeof parsed !== "object" || parsed === null) return out;
|
|
53327
|
+
const file = parsed;
|
|
53328
|
+
if (file.version !== MAX_TOKENS_CACHE_VERSION) return out;
|
|
53329
|
+
if (typeof file.caps !== "object" || file.caps === null) return out;
|
|
53330
|
+
for (const [key, value] of Object.entries(file.caps)) {
|
|
53331
|
+
if (typeof value !== "object" || value === null) continue;
|
|
53332
|
+
const { cap, learnedAt } = value;
|
|
53333
|
+
if (typeof cap !== "number" || !Number.isInteger(cap) || cap < 1) continue;
|
|
53334
|
+
if (typeof learnedAt !== "number" || !Number.isFinite(learnedAt)) continue;
|
|
53335
|
+
if (now - learnedAt > MAX_TOKENS_CACHE_TTL_MS) continue;
|
|
53336
|
+
out.set(key, { cap, learnedAt });
|
|
53337
|
+
}
|
|
53338
|
+
return out;
|
|
53339
|
+
}
|
|
53340
|
+
function loadMaxTokensCaps(dataDir, now = Date.now) {
|
|
53341
|
+
let loaded = 0;
|
|
53342
|
+
for (const [key, entry] of readEntries(dataDir, now())) {
|
|
53343
|
+
if (maxTokensCaps.has(key)) continue;
|
|
53344
|
+
maxTokensCaps.set(key, entry.cap);
|
|
53345
|
+
loaded++;
|
|
53346
|
+
}
|
|
53347
|
+
return loaded;
|
|
53348
|
+
}
|
|
53349
|
+
function recordMaxTokensCap(dataDir, key, cap, now = Date.now) {
|
|
53350
|
+
const at = now();
|
|
53351
|
+
const entries = readEntries(dataDir, at);
|
|
53352
|
+
entries.set(key, { cap, learnedAt: at });
|
|
53353
|
+
const path = maxTokensCachePath(dataDir);
|
|
53354
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
53355
|
+
try {
|
|
53356
|
+
(0, import_node_fs70.mkdirSync)((0, import_node_path93.dirname)(path), { recursive: true, mode: 448 });
|
|
53357
|
+
const caps = Object.fromEntries([...entries].sort(([a], [b]) => a < b ? -1 : 1));
|
|
53358
|
+
(0, import_node_fs70.writeFileSync)(tmp, `${JSON.stringify({ version: MAX_TOKENS_CACHE_VERSION, caps }, null, 2)}
|
|
53359
|
+
`);
|
|
53360
|
+
(0, import_node_fs70.renameSync)(tmp, path);
|
|
53361
|
+
} catch {
|
|
53362
|
+
}
|
|
53363
|
+
}
|
|
53364
|
+
function attachMaxTokensCache(dataDir, now = Date.now) {
|
|
53365
|
+
const existing = attached2.get(dataDir);
|
|
53366
|
+
if (existing !== void 0) return existing;
|
|
53367
|
+
loadMaxTokensCaps(dataDir, now);
|
|
53368
|
+
const unsubscribe = onMaxTokensCap((key, cap) => recordMaxTokensCap(dataDir, key, cap, now));
|
|
53369
|
+
const detach = () => {
|
|
53370
|
+
unsubscribe();
|
|
53371
|
+
attached2.delete(dataDir);
|
|
53372
|
+
};
|
|
53373
|
+
attached2.set(dataDir, detach);
|
|
53374
|
+
return detach;
|
|
53375
|
+
}
|
|
53376
|
+
var import_node_fs70, import_node_path93, MAX_TOKENS_CACHE_VERSION, MAX_TOKENS_CACHE_TTL_MS, attached2;
|
|
53377
|
+
var init_max_tokens_cache = __esm({
|
|
53378
|
+
"src/ai/providers/max-tokens-cache.ts"() {
|
|
53379
|
+
"use strict";
|
|
53380
|
+
import_node_fs70 = require("node:fs");
|
|
53381
|
+
import_node_path93 = require("node:path");
|
|
53382
|
+
init_max_tokens();
|
|
53383
|
+
MAX_TOKENS_CACHE_VERSION = 1;
|
|
53384
|
+
MAX_TOKENS_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
53385
|
+
attached2 = /* @__PURE__ */ new Map();
|
|
53386
|
+
}
|
|
53387
|
+
});
|
|
53388
|
+
|
|
52522
53389
|
// src/cli/compose-providers.ts
|
|
52523
53390
|
function modelConfigOf(model, providerApi) {
|
|
52524
53391
|
const { provider: _p, api, ...rest } = model;
|
|
@@ -52599,6 +53466,7 @@ async function buildProviderRegistry(input2, options = {}) {
|
|
|
52599
53466
|
if (provider !== void 0) registry3 = make({ provider, apiKey: cli.apiKey });
|
|
52600
53467
|
}
|
|
52601
53468
|
if (dataDir !== void 0) {
|
|
53469
|
+
attachMaxTokensCache(dataDir);
|
|
52602
53470
|
const flavor = readOAuthEntry(input2.authFile, CHATGPT_PROVIDER_ID)?.flavor;
|
|
52603
53471
|
mergeDiscoveredModels(
|
|
52604
53472
|
registry3,
|
|
@@ -52639,6 +53507,7 @@ var init_compose_providers = __esm({
|
|
|
52639
53507
|
init_models_dev_cache();
|
|
52640
53508
|
init_registry2();
|
|
52641
53509
|
init_discovered_cache();
|
|
53510
|
+
init_max_tokens_cache();
|
|
52642
53511
|
init_enrich();
|
|
52643
53512
|
init_token_store();
|
|
52644
53513
|
init_presets();
|
|
@@ -52649,8 +53518,8 @@ var init_compose_providers = __esm({
|
|
|
52649
53518
|
|
|
52650
53519
|
// src/modes/image-input.ts
|
|
52651
53520
|
function expand(path, cwd) {
|
|
52652
|
-
const home = path === "~" || path.startsWith("~/") ? (0,
|
|
52653
|
-
return (0,
|
|
53521
|
+
const home = path === "~" || path.startsWith("~/") ? (0, import_node_os15.homedir)() + path.slice(1) : path;
|
|
53522
|
+
return (0, import_node_path94.resolve)(cwd, home);
|
|
52654
53523
|
}
|
|
52655
53524
|
function findImageRefs(text, cwd) {
|
|
52656
53525
|
const out = [];
|
|
@@ -52662,7 +53531,7 @@ function findImageRefs(text, cwd) {
|
|
|
52662
53531
|
token = token.replace(/\\ /g, " ").replace(/[,\uFF0C\u3002;\uFF1B)\uFF09]+$/, "");
|
|
52663
53532
|
if (token === "" || imageMimeFromPath(token) === void 0) continue;
|
|
52664
53533
|
const path = expand(token, cwd);
|
|
52665
|
-
if (!explicit && !(0,
|
|
53534
|
+
if (!explicit && !(0, import_node_fs71.existsSync)(path)) continue;
|
|
52666
53535
|
if (seen.has(path)) continue;
|
|
52667
53536
|
seen.add(path);
|
|
52668
53537
|
out.push({ path, explicit });
|
|
@@ -52721,13 +53590,13 @@ async function loadLocalized(path, options) {
|
|
|
52721
53590
|
throw error2;
|
|
52722
53591
|
}
|
|
52723
53592
|
}
|
|
52724
|
-
var
|
|
53593
|
+
var import_node_fs71, import_node_os15, import_node_path94, TOKEN;
|
|
52725
53594
|
var init_image_input = __esm({
|
|
52726
53595
|
"src/modes/image-input.ts"() {
|
|
52727
53596
|
"use strict";
|
|
52728
|
-
|
|
52729
|
-
|
|
52730
|
-
|
|
53597
|
+
import_node_fs71 = require("node:fs");
|
|
53598
|
+
import_node_os15 = require("node:os");
|
|
53599
|
+
import_node_path94 = require("node:path");
|
|
52731
53600
|
init_channels();
|
|
52732
53601
|
init_errors();
|
|
52733
53602
|
init_image_limits();
|
|
@@ -52941,7 +53810,7 @@ async function runPrintMode(runtime, context) {
|
|
|
52941
53810
|
denied.push({
|
|
52942
53811
|
toolCallId: event.toolCallId,
|
|
52943
53812
|
toolName: event.toolName,
|
|
52944
|
-
reason:
|
|
53813
|
+
reason: textOf6(event)
|
|
52945
53814
|
});
|
|
52946
53815
|
const command3 = bashCommands.get(event.toolCallId);
|
|
52947
53816
|
if (event.toolName === "bash" && command3 !== void 0) deniedBash.push(command3);
|
|
@@ -53077,7 +53946,7 @@ function describeLimit(event) {
|
|
|
53077
53946
|
const m = msg().print.print;
|
|
53078
53947
|
return event.kind === "turns" ? m.limitTurns(event.limit) : m.limitCost(formatUsd(event.limit), formatUsd(event.value));
|
|
53079
53948
|
}
|
|
53080
|
-
function
|
|
53949
|
+
function textOf6(event) {
|
|
53081
53950
|
const content = event.result.content;
|
|
53082
53951
|
const text = typeof content === "string" ? content : content.map((b) => b.type === "text" ? b.text : "").join("");
|
|
53083
53952
|
return text.split("\n")[0]?.trim().slice(0, 200) ?? "";
|
|
@@ -53524,7 +54393,7 @@ function trustChoices() {
|
|
|
53524
54393
|
}
|
|
53525
54394
|
function isDirectory2(path) {
|
|
53526
54395
|
try {
|
|
53527
|
-
return (0,
|
|
54396
|
+
return (0, import_node_fs72.statSync)(path).isDirectory();
|
|
53528
54397
|
} catch {
|
|
53529
54398
|
return false;
|
|
53530
54399
|
}
|
|
@@ -53578,8 +54447,8 @@ function createStartupUi(options = {}) {
|
|
|
53578
54447
|
placeholder: m.cwdPlaceholder,
|
|
53579
54448
|
validate: (text) => {
|
|
53580
54449
|
if (text === "") return m.cwdEmpty;
|
|
53581
|
-
const abs = (0,
|
|
53582
|
-
if (!(0,
|
|
54450
|
+
const abs = (0, import_node_path95.resolve)(text);
|
|
54451
|
+
if (!(0, import_node_fs72.existsSync)(abs)) return m.cwdMissing(abs);
|
|
53583
54452
|
if (!isDirectory2(abs)) return m.cwdNotDir(abs);
|
|
53584
54453
|
return void 0;
|
|
53585
54454
|
}
|
|
@@ -53587,13 +54456,13 @@ function createStartupUi(options = {}) {
|
|
|
53587
54456
|
}
|
|
53588
54457
|
};
|
|
53589
54458
|
}
|
|
53590
|
-
var
|
|
54459
|
+
var import_node_fs72, import_node_path95;
|
|
53591
54460
|
var init_startup_ui = __esm({
|
|
53592
54461
|
"src/modes/interactive/startup-ui.ts"() {
|
|
53593
54462
|
"use strict";
|
|
53594
54463
|
init_i18n();
|
|
53595
|
-
|
|
53596
|
-
|
|
54464
|
+
import_node_fs72 = require("node:fs");
|
|
54465
|
+
import_node_path95 = require("node:path");
|
|
53597
54466
|
init_tui2();
|
|
53598
54467
|
init_model_items();
|
|
53599
54468
|
init_model_items();
|
|
@@ -53731,7 +54600,7 @@ function oneLine7(text, max = 60) {
|
|
|
53731
54600
|
const flat2 = text.replace(/\s+/g, " ").trim();
|
|
53732
54601
|
return flat2.length > max ? `${flat2.slice(0, max - 1)}…` : flat2;
|
|
53733
54602
|
}
|
|
53734
|
-
function
|
|
54603
|
+
function taskLine2(task, now) {
|
|
53735
54604
|
const m = msg().panels.tasks;
|
|
53736
54605
|
const agent = task.runner !== "ama" && task.runner !== task.agent ? m.agentRunner(task.agent, task.runner) : task.agent;
|
|
53737
54606
|
const parts = [agent, ...taskFacts(task, now)];
|
|
@@ -53745,7 +54614,7 @@ function describeTasks(sessionId, now) {
|
|
|
53745
54614
|
if (tasks.length === 0) return m.none;
|
|
53746
54615
|
return [
|
|
53747
54616
|
m.heading(tasks.length),
|
|
53748
|
-
...tasks.map((task) => ` ${
|
|
54617
|
+
...tasks.map((task) => ` ${taskLine2(task, now)}`),
|
|
53749
54618
|
m.footer
|
|
53750
54619
|
].join("\n");
|
|
53751
54620
|
}
|
|
@@ -53756,7 +54625,7 @@ function describeTaskOutput(sessionId, taskId, now) {
|
|
|
53756
54625
|
const output = taskOutput(sessionId, taskId) ?? "";
|
|
53757
54626
|
const file = task.outputFile !== void 0 ? `
|
|
53758
54627
|
${m.fullOutput(task.outputFile)}` : "";
|
|
53759
|
-
return `${
|
|
54628
|
+
return `${taskLine2(task, now)}${file}
|
|
53760
54629
|
${output.trim() === "" ? m.noOutput : output.trimEnd()}`;
|
|
53761
54630
|
}
|
|
53762
54631
|
function sourceText3(source) {
|
|
@@ -54010,7 +54879,7 @@ function startupInfo(runtime, home) {
|
|
|
54010
54879
|
permissionMode: runtime.session.state.permissionMode,
|
|
54011
54880
|
preset: runtime.config.tools?.preset ?? "default",
|
|
54012
54881
|
codemode: effectiveCodemodeMode(runtime.config),
|
|
54013
|
-
contextFiles: resources.contextFiles.map((f) => (0,
|
|
54882
|
+
contextFiles: resources.contextFiles.map((f) => (0, import_node_path96.basename)(f.path)),
|
|
54014
54883
|
skills: resources.skills.filter((s2) => !isBuiltinSkill(s2)).length,
|
|
54015
54884
|
prompts: resources.prompts.length,
|
|
54016
54885
|
hooks: runtime.hooks.list().length,
|
|
@@ -54019,12 +54888,12 @@ function startupInfo(runtime, home) {
|
|
|
54019
54888
|
if (runtime.host !== void 0) info2.host = runtime.host.adapter.id;
|
|
54020
54889
|
return info2;
|
|
54021
54890
|
}
|
|
54022
|
-
var
|
|
54891
|
+
var import_node_path96;
|
|
54023
54892
|
var init_startup_screen = __esm({
|
|
54024
54893
|
"src/cli/startup-screen.ts"() {
|
|
54025
54894
|
"use strict";
|
|
54026
54895
|
init_builtin3();
|
|
54027
|
-
|
|
54896
|
+
import_node_path96 = require("node:path");
|
|
54028
54897
|
init_channels();
|
|
54029
54898
|
init_presets2();
|
|
54030
54899
|
init_i18n();
|
|
@@ -56767,29 +57636,29 @@ function runEditor(command3, file) {
|
|
|
56767
57636
|
return result.status;
|
|
56768
57637
|
}
|
|
56769
57638
|
async function editExternally(text, name, deps) {
|
|
56770
|
-
const dir = (0,
|
|
56771
|
-
const file = (0,
|
|
56772
|
-
(0,
|
|
57639
|
+
const dir = (0, import_node_fs73.mkdtempSync)((0, import_node_path97.join)((0, import_node_os16.tmpdir)(), "ama-edit-"));
|
|
57640
|
+
const file = (0, import_node_path97.join)(dir, name);
|
|
57641
|
+
(0, import_node_fs73.writeFileSync)(file, text);
|
|
56773
57642
|
deps.suspend();
|
|
56774
57643
|
try {
|
|
56775
57644
|
const code = (deps.run ?? runEditor)(editorCommand(deps.env, deps.platform), file);
|
|
56776
57645
|
if (code !== 0) return void 0;
|
|
56777
|
-
return (0,
|
|
57646
|
+
return (0, import_node_fs73.readFileSync)(file, "utf8");
|
|
56778
57647
|
} catch {
|
|
56779
57648
|
return void 0;
|
|
56780
57649
|
} finally {
|
|
56781
57650
|
deps.resume();
|
|
56782
|
-
(0,
|
|
57651
|
+
(0, import_node_fs73.rmSync)(dir, { recursive: true, force: true });
|
|
56783
57652
|
}
|
|
56784
57653
|
}
|
|
56785
|
-
var import_node_child_process17,
|
|
57654
|
+
var import_node_child_process17, import_node_fs73, import_node_os16, import_node_path97;
|
|
56786
57655
|
var init_external_editor = __esm({
|
|
56787
57656
|
"src/modes/interactive/external-editor.ts"() {
|
|
56788
57657
|
"use strict";
|
|
56789
57658
|
import_node_child_process17 = require("node:child_process");
|
|
56790
|
-
|
|
56791
|
-
|
|
56792
|
-
|
|
57659
|
+
import_node_fs73 = require("node:fs");
|
|
57660
|
+
import_node_os16 = require("node:os");
|
|
57661
|
+
import_node_path97 = require("node:path");
|
|
56793
57662
|
}
|
|
56794
57663
|
});
|
|
56795
57664
|
|
|
@@ -59753,7 +60622,7 @@ function agentCommandHooks(get) {
|
|
|
59753
60622
|
agentView: (taskId) => get().openView(taskId)
|
|
59754
60623
|
};
|
|
59755
60624
|
}
|
|
59756
|
-
var TASK_NOTICE, AgentUi;
|
|
60625
|
+
var TASK_NOTICE, SESSION_NOTICE, AgentUi;
|
|
59757
60626
|
var init_agent_ui = __esm({
|
|
59758
60627
|
"src/modes/interactive/agent-ui.ts"() {
|
|
59759
60628
|
"use strict";
|
|
@@ -59773,6 +60642,7 @@ var init_agent_ui = __esm({
|
|
|
59773
60642
|
init_task_background();
|
|
59774
60643
|
init_tasks_report();
|
|
59775
60644
|
TASK_NOTICE = /^\[task (t\d+)\] ([\s\S]*)$/;
|
|
60645
|
+
SESSION_NOTICE = /^cannot read session entry (\S+) back from /;
|
|
59776
60646
|
AgentUi = class {
|
|
59777
60647
|
constructor(deps) {
|
|
59778
60648
|
this.deps = deps;
|
|
@@ -59883,6 +60753,11 @@ var init_agent_ui = __esm({
|
|
|
59883
60753
|
this.deps.notice(level === "warn" ? "warn" : "info", `[${agent} · ${taskId}] ${match[2]}`);
|
|
59884
60754
|
return;
|
|
59885
60755
|
}
|
|
60756
|
+
const image = level === "warn" ? SESSION_NOTICE.exec(message) : null;
|
|
60757
|
+
if (image !== null) {
|
|
60758
|
+
this.deps.notice("warn", msg().interactive.events.imageReadBackFailed(image[1]));
|
|
60759
|
+
return;
|
|
60760
|
+
}
|
|
59886
60761
|
original?.call(holder, level, message);
|
|
59887
60762
|
};
|
|
59888
60763
|
holder.log = routed;
|
|
@@ -60107,7 +60982,7 @@ var init_agent_ui = __esm({
|
|
|
60107
60982
|
const now = this.deps.now();
|
|
60108
60983
|
const picked = await this.deps.pick({
|
|
60109
60984
|
title: msg().interactive.agentUi.tasksTitle,
|
|
60110
|
-
items: [...tasks].reverse().map((task2) => ({ value: task2.taskId, label:
|
|
60985
|
+
items: [...tasks].reverse().map((task2) => ({ value: task2.taskId, label: taskLine2(task2, now) })),
|
|
60111
60986
|
footer: msg().interactive.agentUi.tasksFooter("↑↓")
|
|
60112
60987
|
});
|
|
60113
60988
|
if (picked === void 0) return;
|
|
@@ -60803,9 +61678,9 @@ function parseLeftRight(text) {
|
|
|
60803
61678
|
async function hasUpstream(cwd, branch) {
|
|
60804
61679
|
const gitDir = await findGitDir(cwd);
|
|
60805
61680
|
if (gitDir === void 0) return false;
|
|
60806
|
-
const common = (await (0, import_promises25.readFile)((0,
|
|
60807
|
-
const dir = common === void 0 ? gitDir : (0,
|
|
60808
|
-
const text = await (0, import_promises25.readFile)((0,
|
|
61681
|
+
const common = (await (0, import_promises25.readFile)((0, import_node_path98.join)(gitDir, "commondir"), "utf8").catch(() => void 0))?.trim();
|
|
61682
|
+
const dir = common === void 0 ? gitDir : (0, import_node_path98.isAbsolute)(common) ? common : (0, import_node_path98.resolve)(gitDir, common);
|
|
61683
|
+
const text = await (0, import_promises25.readFile)((0, import_node_path98.join)(dir, "config"), "utf8").catch(() => "");
|
|
60809
61684
|
let inBranch = false;
|
|
60810
61685
|
for (const raw of text.split("\n")) {
|
|
60811
61686
|
const line2 = raw.trim();
|
|
@@ -60828,17 +61703,17 @@ async function readHead2(cwd) {
|
|
|
60828
61703
|
}
|
|
60829
61704
|
const gitDir = await findGitDir(cwd);
|
|
60830
61705
|
if (gitDir === void 0) return void 0;
|
|
60831
|
-
const text = await (0, import_promises25.readFile)((0,
|
|
61706
|
+
const text = await (0, import_promises25.readFile)((0, import_node_path98.join)(gitDir, "HEAD"), "utf8").catch(() => void 0);
|
|
60832
61707
|
const match = /^ref:\s*refs\/heads\/(\S+)\s*$/.exec(text ?? "");
|
|
60833
61708
|
return match?.[1] !== void 0 ? { branch: match[1] } : void 0;
|
|
60834
61709
|
}
|
|
60835
|
-
var import_node_child_process18, import_promises25,
|
|
61710
|
+
var import_node_child_process18, import_promises25, import_node_path98, GIT_NUMSTAT_INTERVAL_MS, GIT_NUMSTAT_TIMEOUT_MS, sameInfo, GitInfoWatcher;
|
|
60836
61711
|
var init_info = __esm({
|
|
60837
61712
|
"src/git/info.ts"() {
|
|
60838
61713
|
"use strict";
|
|
60839
61714
|
import_node_child_process18 = require("node:child_process");
|
|
60840
61715
|
import_promises25 = require("node:fs/promises");
|
|
60841
|
-
|
|
61716
|
+
import_node_path98 = require("node:path");
|
|
60842
61717
|
init_git_head();
|
|
60843
61718
|
GIT_NUMSTAT_INTERVAL_MS = 1e4;
|
|
60844
61719
|
GIT_NUMSTAT_TIMEOUT_MS = 2e3;
|
|
@@ -61134,12 +62009,12 @@ function statusLineText(mode) {
|
|
|
61134
62009
|
const m = msg().interactive.statusLine;
|
|
61135
62010
|
return mode === "full" ? m.full : m.compact;
|
|
61136
62011
|
}
|
|
61137
|
-
var
|
|
62012
|
+
var import_node_path99, WRITE_TOOLS3, QUOTA_TICK_MS, HintLine, StatusArea;
|
|
61138
62013
|
var init_status_area = __esm({
|
|
61139
62014
|
"src/modes/interactive/status-area.ts"() {
|
|
61140
62015
|
"use strict";
|
|
61141
62016
|
init_i18n();
|
|
61142
|
-
|
|
62017
|
+
import_node_path99 = require("node:path");
|
|
61143
62018
|
init_capability();
|
|
61144
62019
|
init_channels();
|
|
61145
62020
|
init_info();
|
|
@@ -61329,7 +62204,7 @@ var init_status_area = __esm({
|
|
|
61329
62204
|
gitView() {
|
|
61330
62205
|
const cwd = this.gitCwd;
|
|
61331
62206
|
if (cwd === void 0) return void 0;
|
|
61332
|
-
return { dir: (0,
|
|
62207
|
+
return { dir: (0, import_node_path99.basename)(cwd), info: this.git?.current() };
|
|
61333
62208
|
}
|
|
61334
62209
|
watchGit() {
|
|
61335
62210
|
const cwd = this.deps.session().state.cwd;
|
|
@@ -63656,15 +64531,15 @@ function processTerminal() {
|
|
|
63656
64531
|
return new ProcessTerminal();
|
|
63657
64532
|
}
|
|
63658
64533
|
function loadKeys(runtime, warn2) {
|
|
63659
|
-
const parsed = loadKeybindingsFile((0,
|
|
64534
|
+
const parsed = loadKeybindingsFile((0, import_node_path100.join)(runtime.paths.configDir, KEYBINDINGS_FILE));
|
|
63660
64535
|
for (const w of parsed.warnings) warn2(msg().interactive.app.keybindingsWarning(w));
|
|
63661
64536
|
return new Keybindings(parsed.overrides);
|
|
63662
64537
|
}
|
|
63663
|
-
var
|
|
64538
|
+
var import_node_path100;
|
|
63664
64539
|
var init_terminal_setup = __esm({
|
|
63665
64540
|
"src/modes/interactive/terminal-setup.ts"() {
|
|
63666
64541
|
"use strict";
|
|
63667
|
-
|
|
64542
|
+
import_node_path100 = require("node:path");
|
|
63668
64543
|
init_paths();
|
|
63669
64544
|
init_errors();
|
|
63670
64545
|
init_i18n();
|
|
@@ -63730,7 +64605,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
63730
64605
|
...options.statusLine !== void 0 ? { layout: options.statusLine } : {}
|
|
63731
64606
|
});
|
|
63732
64607
|
const { hint, bar: status } = area;
|
|
63733
|
-
const historyFile = options.historyFile === false ? void 0 : options.historyFile ?? (0,
|
|
64608
|
+
const historyFile = options.historyFile === false ? void 0 : options.historyFile ?? (0, import_node_path101.join)(runtime.paths.dataDir, "history");
|
|
63734
64609
|
const completion = new InteractiveCompletion({
|
|
63735
64610
|
commands: () => ALL_COMMANDS,
|
|
63736
64611
|
prompts: () => runtime.resources.prompts,
|
|
@@ -64094,12 +64969,12 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64094
64969
|
}
|
|
64095
64970
|
});
|
|
64096
64971
|
}
|
|
64097
|
-
var
|
|
64972
|
+
var import_node_path101, HINT_MS;
|
|
64098
64973
|
var init_interactive_mode = __esm({
|
|
64099
64974
|
"src/modes/interactive/interactive-mode.ts"() {
|
|
64100
64975
|
"use strict";
|
|
64101
64976
|
init_image_input();
|
|
64102
|
-
|
|
64977
|
+
import_node_path101 = require("node:path");
|
|
64103
64978
|
init_session2();
|
|
64104
64979
|
init_compose_session();
|
|
64105
64980
|
init_startup_screen();
|
|
@@ -64175,7 +65050,7 @@ function choose(answer, values) {
|
|
|
64175
65050
|
}
|
|
64176
65051
|
function isDirectory3(path) {
|
|
64177
65052
|
try {
|
|
64178
|
-
return (0,
|
|
65053
|
+
return (0, import_node_fs74.statSync)(path).isDirectory();
|
|
64179
65054
|
} catch {
|
|
64180
65055
|
return false;
|
|
64181
65056
|
}
|
|
@@ -64219,8 +65094,8 @@ function createTextStartupUi(io) {
|
|
|
64219
65094
|
const m = msg().report.startup;
|
|
64220
65095
|
const answer = (await ask([m.cwdMissing(missing)], m.cwdAnswer))?.trim();
|
|
64221
65096
|
if (answer === void 0 || answer === "") return void 0;
|
|
64222
|
-
const abs = (0,
|
|
64223
|
-
if (!(0,
|
|
65097
|
+
const abs = (0, import_node_path102.resolve)(answer);
|
|
65098
|
+
if (!(0, import_node_fs74.existsSync)(abs) || !isDirectory3(abs)) {
|
|
64224
65099
|
io.write(m.notDirectory(abs));
|
|
64225
65100
|
return void 0;
|
|
64226
65101
|
}
|
|
@@ -64228,12 +65103,12 @@ function createTextStartupUi(io) {
|
|
|
64228
65103
|
}
|
|
64229
65104
|
};
|
|
64230
65105
|
}
|
|
64231
|
-
var
|
|
65106
|
+
var import_node_fs74, import_node_path102;
|
|
64232
65107
|
var init_startup_ui_text = __esm({
|
|
64233
65108
|
"src/modes/startup-ui-text.ts"() {
|
|
64234
65109
|
"use strict";
|
|
64235
|
-
|
|
64236
|
-
|
|
65110
|
+
import_node_fs74 = require("node:fs");
|
|
65111
|
+
import_node_path102 = require("node:path");
|
|
64237
65112
|
init_i18n();
|
|
64238
65113
|
}
|
|
64239
65114
|
});
|
|
@@ -64258,7 +65133,7 @@ function createTools(input2, options, state) {
|
|
|
64258
65133
|
const osStatus = configureOsSandbox(input2.config.sandbox?.enabled);
|
|
64259
65134
|
const bashSandbox = options.bashSandbox ?? resolveBashSandbox(input2.config.sandbox, {
|
|
64260
65135
|
status: osStatus,
|
|
64261
|
-
...input2.paths === void 0 ? {} : { hidden: [(0,
|
|
65136
|
+
...input2.paths === void 0 ? {} : { hidden: [(0, import_node_path103.join)(input2.paths.configDir, AUTH_FILE)] }
|
|
64262
65137
|
});
|
|
64263
65138
|
state.bashSandbox = bashSandbox;
|
|
64264
65139
|
const capability = options.sandboxCapability ?? sandboxCapabilityFor(input2.config);
|
|
@@ -64379,7 +65254,7 @@ function createRuntimeDeps(options = {}) {
|
|
|
64379
65254
|
return registry3;
|
|
64380
65255
|
}
|
|
64381
65256
|
},
|
|
64382
|
-
sessions: createSessionStore(),
|
|
65257
|
+
sessions: createSessionStore(options.log ?? stderrLog()),
|
|
64383
65258
|
tools: { create: (input2) => createTools(input2, options, state) },
|
|
64384
65259
|
permissions: {
|
|
64385
65260
|
create: (input2) => new PermissionPipeline({
|
|
@@ -64448,7 +65323,7 @@ function createRuntimeDeps(options = {}) {
|
|
|
64448
65323
|
if (ui !== void 0) deps.ui = ui;
|
|
64449
65324
|
return deps;
|
|
64450
65325
|
}
|
|
64451
|
-
var
|
|
65326
|
+
var import_node_path103, DEFAULT_TOOL_FACTORIES, DEFAULT_MODES;
|
|
64452
65327
|
var init_compose2 = __esm({
|
|
64453
65328
|
"src/cli/compose.ts"() {
|
|
64454
65329
|
"use strict";
|
|
@@ -64463,7 +65338,7 @@ var init_compose2 = __esm({
|
|
|
64463
65338
|
init_tool();
|
|
64464
65339
|
init_detect();
|
|
64465
65340
|
init_bash();
|
|
64466
|
-
|
|
65341
|
+
import_node_path103 = require("node:path");
|
|
64467
65342
|
init_paths();
|
|
64468
65343
|
init_presets2();
|
|
64469
65344
|
init_registry();
|
|
@@ -64678,8 +65553,8 @@ var init_memory3 = __esm({
|
|
|
64678
65553
|
});
|
|
64679
65554
|
|
|
64680
65555
|
// src/cli/main.ts
|
|
64681
|
-
var
|
|
64682
|
-
var
|
|
65556
|
+
var import_node_fs75 = require("node:fs");
|
|
65557
|
+
var import_node_path104 = require("node:path");
|
|
64683
65558
|
var import_node_url3 = require("node:url");
|
|
64684
65559
|
init_version();
|
|
64685
65560
|
init_args();
|
|
@@ -64687,7 +65562,7 @@ init_bootstrap();
|
|
|
64687
65562
|
init_exit_codes();
|
|
64688
65563
|
|
|
64689
65564
|
// src/cli/subcommands/auth.ts
|
|
64690
|
-
var
|
|
65565
|
+
var import_node_path72 = require("node:path");
|
|
64691
65566
|
init_builtin();
|
|
64692
65567
|
|
|
64693
65568
|
// src/auth/chatgpt/cli.ts
|
|
@@ -64967,15 +65842,15 @@ async function startCallbackServer(options) {
|
|
|
64967
65842
|
}
|
|
64968
65843
|
|
|
64969
65844
|
// src/auth/oauth/pkce.ts
|
|
64970
|
-
var
|
|
65845
|
+
var import_node_crypto17 = require("node:crypto");
|
|
64971
65846
|
function base64url(input2) {
|
|
64972
65847
|
return Buffer.from(input2).toString("base64url");
|
|
64973
65848
|
}
|
|
64974
65849
|
function randomToken(bytes = 32) {
|
|
64975
|
-
return base64url((0,
|
|
65850
|
+
return base64url((0, import_node_crypto17.randomBytes)(bytes));
|
|
64976
65851
|
}
|
|
64977
65852
|
function s256(verifier) {
|
|
64978
|
-
return base64url((0,
|
|
65853
|
+
return base64url((0, import_node_crypto17.createHash)("sha256").update(verifier, "ascii").digest());
|
|
64979
65854
|
}
|
|
64980
65855
|
function generatePkce() {
|
|
64981
65856
|
const verifier = randomToken(32);
|
|
@@ -65091,7 +65966,7 @@ async function loginDevice(preset, deps) {
|
|
|
65091
65966
|
}
|
|
65092
65967
|
|
|
65093
65968
|
// src/auth/oauth/jwt.ts
|
|
65094
|
-
var
|
|
65969
|
+
var import_node_crypto18 = require("node:crypto");
|
|
65095
65970
|
init_errors();
|
|
65096
65971
|
function invalid2(reason) {
|
|
65097
65972
|
return new AmaError("oauth_invalid_token", `invalid id_token: ${reason}`, { detail: { reason } });
|
|
@@ -65142,11 +66017,11 @@ function verifyJwtSignature(decoded, keys) {
|
|
|
65142
66017
|
if (candidates2.length === 0) throw invalid2("no matching key");
|
|
65143
66018
|
for (const jwk of candidates2) {
|
|
65144
66019
|
try {
|
|
65145
|
-
const key = (0,
|
|
65146
|
-
const ok = (0,
|
|
66020
|
+
const key = (0, import_node_crypto18.createPublicKey)({ key: jwk, format: "jwk" });
|
|
66021
|
+
const ok = (0, import_node_crypto18.verify)(
|
|
65147
66022
|
spec2.hash,
|
|
65148
66023
|
Buffer.from(decoded.signingInput),
|
|
65149
|
-
spec2.pss ? { key, padding:
|
|
66024
|
+
spec2.pss ? { key, padding: import_node_crypto18.constants.RSA_PKCS1_PSS_PADDING, saltLength: 32 } : spec2.ec ? { key, dsaEncoding: "ieee-p1363" } : key,
|
|
65150
66025
|
decoded.signature
|
|
65151
66026
|
);
|
|
65152
66027
|
if (ok) return;
|
|
@@ -65214,24 +66089,24 @@ async function validateIdToken(fetchFn, idToken, expect) {
|
|
|
65214
66089
|
init_token_client();
|
|
65215
66090
|
|
|
65216
66091
|
// src/auth/chatgpt/host-id.ts
|
|
65217
|
-
var
|
|
65218
|
-
var
|
|
65219
|
-
var
|
|
66092
|
+
var import_node_crypto19 = require("node:crypto");
|
|
66093
|
+
var import_node_fs48 = require("node:fs");
|
|
66094
|
+
var import_node_path70 = require("node:path");
|
|
65220
66095
|
var HOST_ID_FILE = "chatgpt-host.json";
|
|
65221
66096
|
function hostIdPath(dataDir) {
|
|
65222
|
-
return (0,
|
|
66097
|
+
return (0, import_node_path70.join)(dataDir, HOST_ID_FILE);
|
|
65223
66098
|
}
|
|
65224
66099
|
function readOrCreateHostId(dataDir) {
|
|
65225
66100
|
const path = hostIdPath(dataDir);
|
|
65226
66101
|
try {
|
|
65227
|
-
const value = JSON.parse((0,
|
|
66102
|
+
const value = JSON.parse((0, import_node_fs48.readFileSync)(path, "utf8"));
|
|
65228
66103
|
if (typeof value.hostId === "string" && /^urn:uuid:[0-9a-f-]{36}$/i.test(value.hostId))
|
|
65229
66104
|
return value.hostId;
|
|
65230
66105
|
} catch {
|
|
65231
66106
|
}
|
|
65232
|
-
const hostId = `urn:uuid:${(0,
|
|
65233
|
-
(0,
|
|
65234
|
-
(0,
|
|
66107
|
+
const hostId = `urn:uuid:${(0, import_node_crypto19.randomUUID)()}`;
|
|
66108
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path70.dirname)(path), { recursive: true, mode: 448 });
|
|
66109
|
+
(0, import_node_fs48.writeFileSync)(path, `${JSON.stringify({ version: 1, hostId }, null, 2)}
|
|
65235
66110
|
`, { mode: 384 });
|
|
65236
66111
|
return hostId;
|
|
65237
66112
|
}
|
|
@@ -65668,7 +66543,7 @@ async function runAuth(argv, io, deps = {}) {
|
|
|
65668
66543
|
return flags2.has("help") ? ExitCode.Ok : ExitCode.Usage;
|
|
65669
66544
|
}
|
|
65670
66545
|
const explicit = values.get("auth-file");
|
|
65671
|
-
const path = explicit !== void 0 ? (0,
|
|
66546
|
+
const path = explicit !== void 0 ? (0, import_node_path72.resolve)(io.cwd, explicit) : defaultAuthFilePath(resolveConfigDir({ env: io.env }));
|
|
65672
66547
|
const loginOnly = ["flavor", "port"].filter((name) => values.has(name));
|
|
65673
66548
|
const loginFlags = ["paste", "device", "no-browser", "yes"].filter((name) => flags2.has(name));
|
|
65674
66549
|
if (action !== "login" && [...loginOnly, ...loginFlags].length > 0)
|
|
@@ -65744,8 +66619,8 @@ init_merge();
|
|
|
65744
66619
|
init_key_docs();
|
|
65745
66620
|
init_paths();
|
|
65746
66621
|
var import_node_child_process14 = require("node:child_process");
|
|
65747
|
-
var
|
|
65748
|
-
var
|
|
66622
|
+
var import_node_fs57 = require("node:fs");
|
|
66623
|
+
var import_node_path79 = require("node:path");
|
|
65749
66624
|
init_models_dev_cache();
|
|
65750
66625
|
init_init();
|
|
65751
66626
|
init_json_schema();
|
|
@@ -65760,7 +66635,7 @@ init_default_model();
|
|
|
65760
66635
|
init_exit_codes();
|
|
65761
66636
|
|
|
65762
66637
|
// src/cli/subcommands/context.ts
|
|
65763
|
-
var
|
|
66638
|
+
var import_node_path76 = require("node:path");
|
|
65764
66639
|
init_auth_file();
|
|
65765
66640
|
init_load();
|
|
65766
66641
|
init_merge();
|
|
@@ -65781,7 +66656,7 @@ function loadUserLevel(io, options = {}) {
|
|
|
65781
66656
|
profile: profile?.config,
|
|
65782
66657
|
hasProfile: profile !== void 0
|
|
65783
66658
|
});
|
|
65784
|
-
const authFile = options.authFile !== void 0 ? (0,
|
|
66659
|
+
const authFile = options.authFile !== void 0 ? (0, import_node_path76.resolve)(io.cwd, options.authFile) : profile?.authFile ?? defaultAuthFilePath(configDir);
|
|
65785
66660
|
const result = { configDir, dataDir, merged, userConfigPath, authFile, warnings };
|
|
65786
66661
|
if (profile !== void 0) result.profile = profile;
|
|
65787
66662
|
return result;
|
|
@@ -65806,8 +66681,8 @@ init_ansi();
|
|
|
65806
66681
|
// src/cli/subcommands/config-set.ts
|
|
65807
66682
|
init_i18n();
|
|
65808
66683
|
init_edit2();
|
|
65809
|
-
var
|
|
65810
|
-
var
|
|
66684
|
+
var import_node_fs56 = require("node:fs");
|
|
66685
|
+
var import_node_path78 = require("node:path");
|
|
65811
66686
|
init_init();
|
|
65812
66687
|
init_paths();
|
|
65813
66688
|
init_profile();
|
|
@@ -65936,7 +66811,7 @@ async function runConfigEdit(action, argv, io, deps = {}) {
|
|
|
65936
66811
|
if (key === "permission.mode" && value === "full-auto" && scope === "user") {
|
|
65937
66812
|
if (!await confirmBypass(io, flags2.has("yes"), deps)) return ExitCode.Config;
|
|
65938
66813
|
}
|
|
65939
|
-
if (scope === "user" && !(0,
|
|
66814
|
+
if (scope === "user" && !(0, import_node_fs56.existsSync)((0, import_node_path78.join)(input2.configDir, CONFIG_FILE)))
|
|
65940
66815
|
initConfigDir(input2.configDir);
|
|
65941
66816
|
report(io, setConfigValue({ ...input2, scope, key, value }), value);
|
|
65942
66817
|
return ExitCode.Ok;
|
|
@@ -65949,17 +66824,17 @@ function showPaths(io) {
|
|
|
65949
66824
|
const configDir = resolveConfigDir({ env: io.env });
|
|
65950
66825
|
const dataDir = resolveDataDir({ env: io.env });
|
|
65951
66826
|
const m = msg().subcommands.configShow;
|
|
65952
|
-
const mark = (path) => `${path}${(0,
|
|
66827
|
+
const mark = (path) => `${path}${(0, import_node_fs57.existsSync)(path) ? "" : m.missing}`;
|
|
65953
66828
|
const width2 = Math.max(...[m.configDir, m.dataDir, m.projectLevel].map(visibleWidth)) + 2;
|
|
65954
66829
|
const label2 = (text) => padToWidth(text, width2);
|
|
65955
66830
|
const lines2 = [
|
|
65956
66831
|
`${label2(m.configDir)}${mark(configDir)}`,
|
|
65957
|
-
` config.json ${mark((0,
|
|
65958
|
-
` config.schema.json ${mark((0,
|
|
65959
|
-
` auth.json ${mark((0,
|
|
65960
|
-
` hooks.json ${mark((0,
|
|
66832
|
+
` config.json ${mark((0, import_node_path79.join)(configDir, CONFIG_FILE))}`,
|
|
66833
|
+
` config.schema.json ${mark((0, import_node_path79.join)(configDir, CONFIG_SCHEMA_FILE))}`,
|
|
66834
|
+
` auth.json ${mark((0, import_node_path79.join)(configDir, AUTH_FILE))}`,
|
|
66835
|
+
` hooks.json ${mark((0, import_node_path79.join)(configDir, HOOKS_FILE))}`,
|
|
65961
66836
|
`${label2(m.dataDir)}${mark(dataDir)}`,
|
|
65962
|
-
` sessions/ ${mark((0,
|
|
66837
|
+
` sessions/ ${mark((0, import_node_path79.join)(dataDir, "sessions"))}`,
|
|
65963
66838
|
` models-dev.json ${mark(modelsDevCachePath(dataDir))}`,
|
|
65964
66839
|
`${label2(m.projectLevel)}${mark(projectFile(io.cwd, CONFIG_FILE))}`
|
|
65965
66840
|
];
|
|
@@ -65969,8 +66844,8 @@ function showPaths(io) {
|
|
|
65969
66844
|
}
|
|
65970
66845
|
function editConfig(io) {
|
|
65971
66846
|
const configDir = resolveConfigDir({ env: io.env });
|
|
65972
|
-
const path = (0,
|
|
65973
|
-
if (!(0,
|
|
66847
|
+
const path = (0, import_node_path79.join)(configDir, CONFIG_FILE);
|
|
66848
|
+
if (!(0, import_node_fs57.existsSync)(path)) initConfigDir(configDir);
|
|
65974
66849
|
const editor = (io.env["VISUAL"] ?? io.env["EDITOR"] ?? "").trim();
|
|
65975
66850
|
if (editor === "") {
|
|
65976
66851
|
io.stdout(msg().subcommands.configShow.noEditor(path));
|
|
@@ -66262,7 +67137,7 @@ async function runConfig(argv, io, deps) {
|
|
|
66262
67137
|
}
|
|
66263
67138
|
|
|
66264
67139
|
// src/cli/subcommands/doctor.ts
|
|
66265
|
-
var
|
|
67140
|
+
var import_node_fs58 = require("node:fs");
|
|
66266
67141
|
init_blobs();
|
|
66267
67142
|
init_shadow_git();
|
|
66268
67143
|
init_gc();
|
|
@@ -66635,7 +67510,7 @@ async function runDoctor(argv, io, deps) {
|
|
|
66635
67510
|
const m = msg().report.doctor;
|
|
66636
67511
|
report2.section(m.dirsTitle);
|
|
66637
67512
|
report2.item(m.configDir(level.configDir));
|
|
66638
|
-
report2.item(m.dataDir(level.dataDir, (0,
|
|
67513
|
+
report2.item(m.dataDir(level.dataDir, (0, import_node_fs58.existsSync)(level.dataDir)));
|
|
66639
67514
|
await fileHistoryLine(report2, level.dataDir);
|
|
66640
67515
|
report2.section(m.layersTitle);
|
|
66641
67516
|
report2.item(m.builtinDefaults);
|
|
@@ -66863,7 +67738,7 @@ init_discovered_cache();
|
|
|
66863
67738
|
init_catalog2();
|
|
66864
67739
|
init_models_dev_cache();
|
|
66865
67740
|
init_models_dev();
|
|
66866
|
-
var
|
|
67741
|
+
var import_node_fs59 = require("node:fs");
|
|
66867
67742
|
init_load();
|
|
66868
67743
|
init_write2();
|
|
66869
67744
|
init_args();
|
|
@@ -67226,7 +68101,7 @@ function writeEntries(ctx, provider, entries, notes) {
|
|
|
67226
68101
|
return 0;
|
|
67227
68102
|
}
|
|
67228
68103
|
models.push(...added);
|
|
67229
|
-
const backup = (0,
|
|
68104
|
+
const backup = (0, import_node_fs59.existsSync)(path);
|
|
67230
68105
|
writeConfigFile(path, config, { backup: true });
|
|
67231
68106
|
io.stdout(m.written(path, provider.id, added.length, kept, backup));
|
|
67232
68107
|
if (notes.noTools.size > 0) io.stdout(m.skippedNoTools([...notes.noTools].join(", ")));
|
|
@@ -67651,7 +68526,7 @@ async function runModels(argv, io, deps) {
|
|
|
67651
68526
|
}
|
|
67652
68527
|
|
|
67653
68528
|
// src/cli/subcommands/providers.ts
|
|
67654
|
-
var
|
|
68529
|
+
var import_node_fs60 = require("node:fs");
|
|
67655
68530
|
init_models_dev_cache();
|
|
67656
68531
|
init_models_dev();
|
|
67657
68532
|
init_auth_file();
|
|
@@ -68308,7 +69183,7 @@ ${renderTable2(result.plans)}`);
|
|
|
68308
69183
|
const providers = config.providers ??= {};
|
|
68309
69184
|
providers[id] = merged.config;
|
|
68310
69185
|
if (defaultPick !== void 0) config.defaultModel = `${id}/${defaultPick.id}`;
|
|
68311
|
-
const backup = (0,
|
|
69186
|
+
const backup = (0, import_node_fs60.existsSync)(level.userConfigPath);
|
|
68312
69187
|
writeConfigFile(level.userConfigPath, config, { backup: true });
|
|
68313
69188
|
if (key.store !== void 0) setAuthKey(level.authFile, id, key.store);
|
|
68314
69189
|
io.stdout(m.written(level.userConfigPath, backup));
|
|
@@ -68424,7 +69299,7 @@ init_init();
|
|
|
68424
69299
|
init_paths();
|
|
68425
69300
|
|
|
68426
69301
|
// src/cli/subcommands/sessions.ts
|
|
68427
|
-
var
|
|
69302
|
+
var import_node_path87 = require("node:path");
|
|
68428
69303
|
init_gc();
|
|
68429
69304
|
init_paths();
|
|
68430
69305
|
init_args();
|
|
@@ -68433,8 +69308,8 @@ init_reuse();
|
|
|
68433
69308
|
init_clipboard_image();
|
|
68434
69309
|
|
|
68435
69310
|
// src/cli/subcommands/sessions-export.ts
|
|
68436
|
-
var
|
|
68437
|
-
var
|
|
69311
|
+
var import_node_fs62 = require("node:fs");
|
|
69312
|
+
var import_node_path81 = require("node:path");
|
|
68438
69313
|
init_paths();
|
|
68439
69314
|
|
|
68440
69315
|
// src/session/export.ts
|
|
@@ -68656,7 +69531,7 @@ async function runSessionsExport(argv, io) {
|
|
|
68656
69531
|
throw new UsageError(msg().subcommands.common.invalidChoice("--branch", BRANCHES, branch));
|
|
68657
69532
|
}
|
|
68658
69533
|
const dirFlag = values.get("session-dir");
|
|
68659
|
-
const root = dirFlag !== void 0 ? (0,
|
|
69534
|
+
const root = dirFlag !== void 0 ? (0, import_node_path81.resolve)(io.cwd, expandHome(dirFlag, { env: io.env })) : (0, import_node_path81.join)(resolveDataDir({ env: io.env }), "sessions");
|
|
68660
69535
|
const session = readSessionReadOnly(findSessionFileReadOnly(root, id, io.cwd));
|
|
68661
69536
|
const text = renderExport(session, format, branch);
|
|
68662
69537
|
const output = values.get("output");
|
|
@@ -68664,14 +69539,14 @@ async function runSessionsExport(argv, io) {
|
|
|
68664
69539
|
io.stdout(text);
|
|
68665
69540
|
return ExitCode.Ok;
|
|
68666
69541
|
}
|
|
68667
|
-
const target = (0,
|
|
68668
|
-
(0,
|
|
69542
|
+
const target = (0, import_node_path81.resolve)(io.cwd, expandHome(output, { env: io.env }));
|
|
69543
|
+
(0, import_node_fs62.writeFileSync)(target, text, { mode: 384 });
|
|
68669
69544
|
io.stderr(msg().subcommands.sessionsExport.exported(target));
|
|
68670
69545
|
return ExitCode.Ok;
|
|
68671
69546
|
}
|
|
68672
69547
|
|
|
68673
69548
|
// src/cli/subcommands/sessions-search.ts
|
|
68674
|
-
var
|
|
69549
|
+
var import_node_path84 = require("node:path");
|
|
68675
69550
|
init_paths();
|
|
68676
69551
|
init_scan();
|
|
68677
69552
|
|
|
@@ -68849,7 +69724,7 @@ init_args();
|
|
|
68849
69724
|
init_exit_codes();
|
|
68850
69725
|
|
|
68851
69726
|
// src/cli/subcommands/stats.ts
|
|
68852
|
-
var
|
|
69727
|
+
var import_node_path83 = require("node:path");
|
|
68853
69728
|
init_paths();
|
|
68854
69729
|
init_scan();
|
|
68855
69730
|
|
|
@@ -68997,8 +69872,8 @@ function aggregateStats(summaries, options = {}) {
|
|
|
68997
69872
|
}
|
|
68998
69873
|
|
|
68999
69874
|
// src/session/stats-index.ts
|
|
69000
|
-
var
|
|
69001
|
-
var
|
|
69875
|
+
var import_node_fs63 = require("node:fs");
|
|
69876
|
+
var import_node_path82 = require("node:path");
|
|
69002
69877
|
|
|
69003
69878
|
// src/session/stats-scan.ts
|
|
69004
69879
|
init_scan();
|
|
@@ -69211,7 +70086,7 @@ function collectSummaries(files, options = {}) {
|
|
|
69211
70086
|
let index2 = { version: INDEX_VERSION, zone, files: {} };
|
|
69212
70087
|
if (options.indexFile !== void 0) {
|
|
69213
70088
|
try {
|
|
69214
|
-
const loaded = JSON.parse((0,
|
|
70089
|
+
const loaded = JSON.parse((0, import_node_fs63.readFileSync)(options.indexFile, "utf8"));
|
|
69215
70090
|
if (loaded.version === INDEX_VERSION && loaded.zone === zone && typeof loaded.files === "object")
|
|
69216
70091
|
index2 = loaded;
|
|
69217
70092
|
} catch {
|
|
@@ -69222,7 +70097,7 @@ function collectSummaries(files, options = {}) {
|
|
|
69222
70097
|
for (const file of files) {
|
|
69223
70098
|
let stat16;
|
|
69224
70099
|
try {
|
|
69225
|
-
stat16 = (0,
|
|
70100
|
+
stat16 = (0, import_node_fs63.statSync)(file);
|
|
69226
70101
|
} catch {
|
|
69227
70102
|
result.invalid++;
|
|
69228
70103
|
continue;
|
|
@@ -69252,10 +70127,10 @@ function collectSummaries(files, options = {}) {
|
|
|
69252
70127
|
}
|
|
69253
70128
|
if (dirty && options.indexFile !== void 0) {
|
|
69254
70129
|
try {
|
|
69255
|
-
(0,
|
|
70130
|
+
(0, import_node_fs63.mkdirSync)((0, import_node_path82.dirname)(options.indexFile), { recursive: true, mode: 448 });
|
|
69256
70131
|
const tmp = `${options.indexFile}.${process.pid}.tmp`;
|
|
69257
|
-
(0,
|
|
69258
|
-
(0,
|
|
70132
|
+
(0, import_node_fs63.writeFileSync)(tmp, JSON.stringify(index2), { mode: 384 });
|
|
70133
|
+
(0, import_node_fs63.renameSync)(tmp, options.indexFile);
|
|
69259
70134
|
} catch {
|
|
69260
70135
|
}
|
|
69261
70136
|
}
|
|
@@ -69416,13 +70291,13 @@ async function runStats(argv, io) {
|
|
|
69416
70291
|
}
|
|
69417
70292
|
const dataDir = resolveDataDir({ env: io.env });
|
|
69418
70293
|
const dirFlag = values.get("session-dir");
|
|
69419
|
-
const root = dirFlag !== void 0 ? (0,
|
|
70294
|
+
const root = dirFlag !== void 0 ? (0, import_node_path83.resolve)(io.cwd, expandHome(dirFlag, { env: io.env })) : (0, import_node_path83.join)(dataDir, "sessions");
|
|
69420
70295
|
const projectFlag = values.get("project");
|
|
69421
|
-
const project = projectFlag !== void 0 ? (0,
|
|
70296
|
+
const project = projectFlag !== void 0 ? (0, import_node_path83.resolve)(io.cwd, expandHome(projectFlag, { env: io.env })) : flags2.has("all") || by === "project" ? void 0 : io.cwd;
|
|
69422
70297
|
const files = sessionFilesInScope(root, project);
|
|
69423
70298
|
const useCache = !flags2.has("no-cache");
|
|
69424
70299
|
const collected = collectSummaries(files, {
|
|
69425
|
-
...useCache ? { indexFile: (0,
|
|
70300
|
+
...useCache ? { indexFile: (0, import_node_path83.join)(dataDir, STATS_INDEX_FILE) } : {},
|
|
69426
70301
|
prune: project === void 0
|
|
69427
70302
|
});
|
|
69428
70303
|
const report2 = aggregateStats(collected.summaries, {
|
|
@@ -69517,7 +70392,7 @@ async function runSessionsSearch(argv, io) {
|
|
|
69517
70392
|
const sinceRaw = values.get("since");
|
|
69518
70393
|
const sinceIso = sinceRaw === void 0 ? void 0 : (/* @__PURE__ */ new Date(`${parseDaySpec("since", sinceRaw)}T00:00:00`)).toISOString();
|
|
69519
70394
|
const dirFlag = values.get("session-dir");
|
|
69520
|
-
const root = dirFlag !== void 0 ? (0,
|
|
70395
|
+
const root = dirFlag !== void 0 ? (0, import_node_path84.resolve)(io.cwd, expandHome(dirFlag, { env: io.env })) : (0, import_node_path84.join)(resolveDataDir({ env: io.env }), "sessions");
|
|
69521
70396
|
const files = sessionFilesInScope(root, flags2.has("all") ? void 0 : io.cwd);
|
|
69522
70397
|
const { hits, truncated } = searchSessions(files, query, {
|
|
69523
70398
|
limit,
|
|
@@ -69541,9 +70416,9 @@ async function runSessionsSearch(argv, io) {
|
|
|
69541
70416
|
|
|
69542
70417
|
// src/cli/subcommands/sessions-trace.ts
|
|
69543
70418
|
var import_node_child_process15 = require("node:child_process");
|
|
69544
|
-
var
|
|
69545
|
-
var
|
|
69546
|
-
var
|
|
70419
|
+
var import_node_fs65 = require("node:fs");
|
|
70420
|
+
var import_node_os13 = require("node:os");
|
|
70421
|
+
var import_node_path86 = require("node:path");
|
|
69547
70422
|
init_paths();
|
|
69548
70423
|
init_i18n();
|
|
69549
70424
|
init_scan();
|
|
@@ -69979,9 +70854,9 @@ function splitHtmlFlag(argv) {
|
|
|
69979
70854
|
return { rest, html, ...file !== void 0 ? { file } : {} };
|
|
69980
70855
|
}
|
|
69981
70856
|
function locate(io, target, dirFlag) {
|
|
69982
|
-
const asPath = (0,
|
|
69983
|
-
if (/[\\/]|\.jsonl$/.test(target) && (0,
|
|
69984
|
-
const root = dirFlag !== void 0 ? (0,
|
|
70857
|
+
const asPath = (0, import_node_path86.resolve)(io.cwd, expandHome(target, { env: io.env }));
|
|
70858
|
+
if (/[\\/]|\.jsonl$/.test(target) && (0, import_node_fs65.existsSync)(asPath)) return asPath;
|
|
70859
|
+
const root = dirFlag !== void 0 ? (0, import_node_path86.resolve)(io.cwd, expandHome(dirFlag, { env: io.env })) : (0, import_node_path86.join)(resolveDataDir({ env: io.env }), "sessions");
|
|
69985
70860
|
return findSessionFileReadOnly(root, target, io.cwd);
|
|
69986
70861
|
}
|
|
69987
70862
|
async function runSessionsTrace(argv, io, deps = {}) {
|
|
@@ -70046,14 +70921,14 @@ async function runSessionsTrace(argv, io, deps = {}) {
|
|
|
70046
70921
|
}
|
|
70047
70922
|
const outFlag = split.file ?? values.get("output");
|
|
70048
70923
|
const open3 = flags2.has("open");
|
|
70049
|
-
let outPath = outFlag === void 0 ? void 0 : (0,
|
|
70924
|
+
let outPath = outFlag === void 0 ? void 0 : (0, import_node_path86.resolve)(io.cwd, expandHome(outFlag, { env: io.env }));
|
|
70050
70925
|
if (outPath === void 0 && open3)
|
|
70051
|
-
outPath = (0,
|
|
70926
|
+
outPath = (0, import_node_path86.join)((0, import_node_os13.tmpdir)(), `ama-trace-${read2.header.id}.${wantsJson ? "json" : "html"}`);
|
|
70052
70927
|
if (outPath === void 0) {
|
|
70053
70928
|
io.stdout(text);
|
|
70054
70929
|
return ExitCode.Ok;
|
|
70055
70930
|
}
|
|
70056
|
-
(0,
|
|
70931
|
+
(0, import_node_fs65.writeFileSync)(outPath, text, { mode: 384 });
|
|
70057
70932
|
io.stderr(m.wrote(outPath));
|
|
70058
70933
|
if (open3) {
|
|
70059
70934
|
try {
|
|
@@ -70094,7 +70969,7 @@ async function runSessions(argv, io, deps) {
|
|
|
70094
70969
|
return flags2.has("help") ? ExitCode.Ok : ExitCode.Usage;
|
|
70095
70970
|
}
|
|
70096
70971
|
const dirFlag = values.get("session-dir");
|
|
70097
|
-
const sessionDir = dirFlag !== void 0 ? (0,
|
|
70972
|
+
const sessionDir = dirFlag !== void 0 ? (0, import_node_path87.resolve)(io.cwd, expandHome(dirFlag, { env: io.env })) : (0, import_node_path87.resolve)(resolveDataDir({ env: io.env }), "sessions");
|
|
70098
70973
|
const sessions = deps?.sessions;
|
|
70099
70974
|
const scope = flags2.has("all") ? {} : { cwd: io.cwd };
|
|
70100
70975
|
switch (action) {
|
|
@@ -70180,7 +71055,7 @@ async function pruneFileHistory(io, sessionDir, dryRun) {
|
|
|
70180
71055
|
try {
|
|
70181
71056
|
const result = await gcBlobs({
|
|
70182
71057
|
dataDir,
|
|
70183
|
-
sessionRoots: [sessionDir, (0,
|
|
71058
|
+
sessionRoots: [sessionDir, (0, import_node_path87.join)(dataDir, "sessions")],
|
|
70184
71059
|
dryRun
|
|
70185
71060
|
});
|
|
70186
71061
|
if (result.removed.length === 0) return;
|
|
@@ -70254,7 +71129,7 @@ function readStdinDefault() {
|
|
|
70254
71129
|
}
|
|
70255
71130
|
function stdinKindDefault() {
|
|
70256
71131
|
try {
|
|
70257
|
-
const stat16 = (0,
|
|
71132
|
+
const stat16 = (0, import_node_fs75.fstatSync)(0);
|
|
70258
71133
|
if (stat16.isFile()) return "file";
|
|
70259
71134
|
if (stat16.isFIFO()) return "fifo";
|
|
70260
71135
|
if (stat16.isSocket()) return "socket";
|
|
@@ -70314,7 +71189,7 @@ function defaultIo() {
|
|
|
70314
71189
|
}
|
|
70315
71190
|
function peekUserLanguage(env) {
|
|
70316
71191
|
try {
|
|
70317
|
-
const raw = (0,
|
|
71192
|
+
const raw = (0, import_node_fs75.readFileSync)((0, import_node_path104.join)(resolveConfigDir({ env }), "config.json"), "utf8");
|
|
70318
71193
|
const value = JSON.parse(raw).ui?.language;
|
|
70319
71194
|
return value === "auto" || value === "zh" || value === "en" ? value : void 0;
|
|
70320
71195
|
} catch {
|
|
@@ -70402,7 +71277,7 @@ function isDirectRun() {
|
|
|
70402
71277
|
const entry = process.argv[1];
|
|
70403
71278
|
if (entry === void 0) return false;
|
|
70404
71279
|
try {
|
|
70405
|
-
return (0,
|
|
71280
|
+
return (0, import_node_fs75.realpathSync)(entry) === (0, import_node_fs75.realpathSync)((0, import_node_url3.fileURLToPath)(__ama_import_meta_url));
|
|
70406
71281
|
} catch {
|
|
70407
71282
|
return false;
|
|
70408
71283
|
}
|