billion-context-pi 0.1.24 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -14
- package/README.zh-CN.md +33 -15
- package/dist/config.d.ts +18 -0
- package/dist/delegate-tool.d.ts +19 -2
- package/dist/index.js +194 -31
- package/dist/index.js.map +1 -1
- package/dist/tool-guardrails.d.ts +9 -0
- package/dist/user-config.d.ts +2 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -611,9 +611,13 @@ var TAG_CLOSE = LT + "/acp" + GT;
|
|
|
611
611
|
function acpTag(ref, tokens, type) {
|
|
612
612
|
return TAG_OPEN + 'tokens="' + formatTokens(tokens) + '" type="' + type + '"' + GT + ref + TAG_CLOSE;
|
|
613
613
|
}
|
|
614
|
-
function renderMessage(message, map, countTokens) {
|
|
614
|
+
function renderMessage(message, map, countTokens, strategy) {
|
|
615
615
|
const ref = refForRaw(map, message.id);
|
|
616
616
|
if (!ref || ref === BLOCKED_REF) return message;
|
|
617
|
+
if (strategy === "none") return message;
|
|
618
|
+
if (strategy === "text-only" && message.contentType !== "text") {
|
|
619
|
+
return message;
|
|
620
|
+
}
|
|
617
621
|
const ownTagRe = new RegExp(
|
|
618
622
|
"^" + escapeRegex(TAG_OPEN) + "[^>]*" + GT + escapeRegex(ref) + escapeRegex(TAG_CLOSE) + "\\n?"
|
|
619
623
|
);
|
|
@@ -624,21 +628,24 @@ function renderMessage(message, map, countTokens) {
|
|
|
624
628
|
if (!cleanText) return { ...message, text: prefix };
|
|
625
629
|
return { ...message, text: prefix + cleanText };
|
|
626
630
|
}
|
|
627
|
-
function renderVisibleRefs(messages, state, countTokens = (text) => Math.ceil(text.length / 4)) {
|
|
631
|
+
function renderVisibleRefs(messages, state, countTokens = (text) => Math.ceil(text.length / 4), strategy = "all") {
|
|
628
632
|
const map = state.messageRefs;
|
|
629
633
|
return messages.map(
|
|
630
|
-
(message) => renderMessage(message, map, countTokens)
|
|
634
|
+
(message) => renderMessage(message, map, countTokens, strategy)
|
|
631
635
|
);
|
|
632
636
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
637
|
+
function createRenderRefsNode(strategy) {
|
|
638
|
+
return {
|
|
639
|
+
name: "render-refs",
|
|
640
|
+
run(io, ctx) {
|
|
641
|
+
return {
|
|
642
|
+
...io,
|
|
643
|
+
messages: renderVisibleRefs(io.messages, io.state, ctx.countTokens, strategy)
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
var renderRefsNode = createRenderRefsNode("all");
|
|
642
649
|
var ALWAYS_PROTECTED_TOOLS = ["compress"];
|
|
643
650
|
var NEVER_PRESERVE_RECENT_TOOLS = [
|
|
644
651
|
"decompress",
|
|
@@ -1009,7 +1016,9 @@ function createCore(ports = {}) {
|
|
|
1009
1016
|
state: input.state,
|
|
1010
1017
|
effects: {}
|
|
1011
1018
|
};
|
|
1012
|
-
const
|
|
1019
|
+
const strategy = input.renderTags ?? "all";
|
|
1020
|
+
const nodes = buildNodes(strategy);
|
|
1021
|
+
const result = runPipeline(nodes, initial, ctx);
|
|
1013
1022
|
return {
|
|
1014
1023
|
messages: result.messages,
|
|
1015
1024
|
state: result.state,
|
|
@@ -1039,7 +1048,10 @@ function createCore(ports = {}) {
|
|
|
1039
1048
|
};
|
|
1040
1049
|
}
|
|
1041
1050
|
function defaultNodes() {
|
|
1042
|
-
return
|
|
1051
|
+
return buildNodes("all");
|
|
1052
|
+
}
|
|
1053
|
+
function buildNodes(strategy) {
|
|
1054
|
+
const base = [
|
|
1043
1055
|
assignRefsNode,
|
|
1044
1056
|
syncBlocksNode,
|
|
1045
1057
|
pruneNode,
|
|
@@ -1047,9 +1059,10 @@ function createCore(ports = {}) {
|
|
|
1047
1059
|
hideCompressCallsNode,
|
|
1048
1060
|
recommendNode,
|
|
1049
1061
|
nudgeNode,
|
|
1050
|
-
emergencyTruncateNode
|
|
1051
|
-
renderRefsNode
|
|
1062
|
+
emergencyTruncateNode
|
|
1052
1063
|
];
|
|
1064
|
+
if (strategy === "none") return base;
|
|
1065
|
+
return [...base, createRenderRefsNode(strategy)];
|
|
1053
1066
|
}
|
|
1054
1067
|
return { processTurn, applyCompression, defaultNodes, decompress, search, status };
|
|
1055
1068
|
}
|
|
@@ -2342,6 +2355,8 @@ function makePreview(text, query, len) {
|
|
|
2342
2355
|
}
|
|
2343
2356
|
|
|
2344
2357
|
// src/config.ts
|
|
2358
|
+
var DEFAULT_TOOL_BASH_TIMEOUT = 60;
|
|
2359
|
+
var DEFAULT_TOOL_OUTPUT_MAX_BYTES = 2e5;
|
|
2345
2360
|
function resolveConfig(adapter, liveContextLimit) {
|
|
2346
2361
|
const envLimit = process.env.ACP_MODEL_CONTEXT_LIMIT;
|
|
2347
2362
|
const envLimitNum = envLimit ? Number(envLimit) : NaN;
|
|
@@ -2359,7 +2374,15 @@ var REF_TAG = new RegExp("^(?:<acp\\s[^>]*>m\\d{5}</acp>|\\[m\\d{1,5}\\])\\s?\\n
|
|
|
2359
2374
|
function entriesToCoreMessages(entries) {
|
|
2360
2375
|
const out = [];
|
|
2361
2376
|
for (const entry of entries) {
|
|
2362
|
-
if (entry.type !== "message")
|
|
2377
|
+
if (entry.type !== "message") {
|
|
2378
|
+
if (entry.type === "custom_message") {
|
|
2379
|
+
const text = extractText(entry.content);
|
|
2380
|
+
if (text.length > 0) {
|
|
2381
|
+
out.push({ id: entry.id, role: "user", contentType: "text", text });
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
continue;
|
|
2385
|
+
}
|
|
2363
2386
|
const cores = projectMessage(entry.message, entry.id);
|
|
2364
2387
|
out.push(...cores);
|
|
2365
2388
|
}
|
|
@@ -7183,7 +7206,7 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
7183
7206
|
config
|
|
7184
7207
|
});
|
|
7185
7208
|
await runtime.save(applied.state, ctx);
|
|
7186
|
-
const { blocksCreated, tokensCompressed, errors } = applied.result;
|
|
7209
|
+
const { blocksCreated, tokensCompressed, errors, warnings } = applied.result;
|
|
7187
7210
|
const afterTokens = Math.max(0, beforeTokens - tokensCompressed);
|
|
7188
7211
|
const newBlocks = applied.state.blocks.slice(-blocksCreated);
|
|
7189
7212
|
debug.event("compress-out", {
|
|
@@ -7200,6 +7223,7 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
7200
7223
|
newBlocks: newBlocks.map((b) => ({ blockId: b.blockId, tier: b.tier, summaryLen: b.summary.length, directMsgCount: b.directMessageIds.length, effectiveMsgCount: b.effectiveMessageIds.length, summary: b.summary }))
|
|
7201
7224
|
});
|
|
7202
7225
|
const lines = [`\u25A3 ACP | ${formatK2(beforeTokens)} \u2192 ${formatK2(afterTokens)} tokens (~${formatK2(tokensCompressed)} reclaimed, ${blocksCreated} block${blocksCreated > 1 ? "s" : ""})`];
|
|
7226
|
+
if (warnings.length > 0) lines.push("\u26A0\uFE0F " + warnings.join("; "));
|
|
7203
7227
|
if (errors.length > 0) lines.push("Errors: " + errors.join("; "));
|
|
7204
7228
|
return lines.join("\n");
|
|
7205
7229
|
}
|
|
@@ -7625,15 +7649,19 @@ var MAX_DEPTH = 2;
|
|
|
7625
7649
|
var SYNC_TIMEOUT_MS = 5 * 6e4;
|
|
7626
7650
|
var RESULT_SUMMARY_CHARS = 500;
|
|
7627
7651
|
var OUT_DIR = join4(tmpdir2(), "acp-delegate");
|
|
7652
|
+
var ACP_TOOLS = ["compress", "decompress", "search_context", "acp_status"];
|
|
7653
|
+
var RESTRICTED_TOOLS = "read,bash,grep,find,ls";
|
|
7628
7654
|
var AGENTS = {
|
|
7629
7655
|
reviewer: {
|
|
7630
|
-
tools:
|
|
7656
|
+
tools: RESTRICTED_TOOLS,
|
|
7657
|
+
restricted: true,
|
|
7631
7658
|
prompt: `You are a senior code reviewer with read-only access.
|
|
7632
7659
|
Read the given code and report: bugs, security/safety risks, correctness issues, and concrete improvement suggestions.
|
|
7633
7660
|
Be specific \u2014 cite file:line for every finding. Do NOT modify any files; only read and report.`
|
|
7634
7661
|
},
|
|
7635
7662
|
researcher: {
|
|
7636
|
-
tools:
|
|
7663
|
+
tools: RESTRICTED_TOOLS,
|
|
7664
|
+
restricted: true,
|
|
7637
7665
|
prompt: `You are a code researcher with read-only access.
|
|
7638
7666
|
Investigate the codebase to answer the question thoroughly. Report findings with exact file:line references, function/type signatures, and relevant code snippets.
|
|
7639
7667
|
Do NOT modify any files; only read and report.`
|
|
@@ -7645,13 +7673,15 @@ Make exactly the requested code changes \u2014 minimal, focused, following exist
|
|
|
7645
7673
|
After editing, briefly summarize what you changed and why. Do not expand scope.`
|
|
7646
7674
|
},
|
|
7647
7675
|
planner: {
|
|
7648
|
-
tools:
|
|
7676
|
+
tools: RESTRICTED_TOOLS,
|
|
7677
|
+
restricted: true,
|
|
7649
7678
|
prompt: `You are a technical planner with read-only access.
|
|
7650
7679
|
Analyze the task and produce a concrete, ordered step-by-step implementation plan with rationale for each step.
|
|
7651
7680
|
Cite file:line for code you reference. Do NOT modify any files; only read and propose.`
|
|
7652
7681
|
},
|
|
7653
7682
|
oracle: {
|
|
7654
|
-
tools:
|
|
7683
|
+
tools: RESTRICTED_TOOLS,
|
|
7684
|
+
restricted: true,
|
|
7655
7685
|
prompt: `You are an expert advisor with read-only access.
|
|
7656
7686
|
Answer the question concisely with clear reasoning. Cite file:line when referencing code. Do NOT modify any files.`
|
|
7657
7687
|
}
|
|
@@ -7707,7 +7737,7 @@ var agentListLine = (name) => {
|
|
|
7707
7737
|
planner: "analyze + propose step-by-step plan (read-only)",
|
|
7708
7738
|
oracle: "answer questions / advise (read-only)"
|
|
7709
7739
|
};
|
|
7710
|
-
return ` \u2022 ${name}
|
|
7740
|
+
return ` \u2022 ${name} - ${blurb[name]} [tools: ${def.tools}${def.restricted ? " + ACP context tools" : ""}]`;
|
|
7711
7741
|
};
|
|
7712
7742
|
function makeDelegateTool(pi) {
|
|
7713
7743
|
return {
|
|
@@ -7748,6 +7778,12 @@ function remainingLineForWait(selfRunId) {
|
|
|
7748
7778
|
const remaining = Array.from(runs.values()).filter((r) => r.status === "running" && r.runId !== selfRunId).length;
|
|
7749
7779
|
return remaining > 0 ? ` ${remaining} delegate${remaining === 1 ? " is" : "s are"} still running.` : "";
|
|
7750
7780
|
}
|
|
7781
|
+
function injectedWaitMessage(run, runId, remainingLine) {
|
|
7782
|
+
if (!run.injected) return null;
|
|
7783
|
+
const file = run.result?.file;
|
|
7784
|
+
const fileLine = file ? ` If you need details, read the result file: \`${file}\`.` : "";
|
|
7785
|
+
return `Delegate \`${runId}\` already delivered its result via a system notification when it finished \u2014 no need to wait on it again.${remainingLine}${fileLine}`;
|
|
7786
|
+
}
|
|
7751
7787
|
function makeDelegateWaitTool(_pi) {
|
|
7752
7788
|
return {
|
|
7753
7789
|
name: "acp_delegate_wait",
|
|
@@ -7770,6 +7806,11 @@ function makeDelegateWaitTool(_pi) {
|
|
|
7770
7806
|
return { details: void 0, content: [{ type: "text", text: `Delegate \`${args.runId}\` was cancelled (no result).${remainingLineForWait(args.runId)}` }] };
|
|
7771
7807
|
}
|
|
7772
7808
|
if (run.status !== "running") {
|
|
7809
|
+
const dedup = injectedWaitMessage(run, args.runId, remainingLineForWait(args.runId));
|
|
7810
|
+
if (dedup) {
|
|
7811
|
+
run.consumed = true;
|
|
7812
|
+
return { details: void 0, content: [{ type: "text", text: dedup }] };
|
|
7813
|
+
}
|
|
7773
7814
|
run.consumed = true;
|
|
7774
7815
|
if (!run.result) {
|
|
7775
7816
|
return { details: void 0, content: [{ type: "text", text: `Delegate \`${args.runId}\` finished but no result is available (persist error).` }] };
|
|
@@ -7934,6 +7975,7 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
7934
7975
|
return;
|
|
7935
7976
|
}
|
|
7936
7977
|
const injected = injectResult(pi, args.agent, runId, args.task, code, file2);
|
|
7978
|
+
run.injected = injected;
|
|
7937
7979
|
debug.event("delegate-done", { runId, code, status: run.status, injected, outLen: output.length, file: file2 });
|
|
7938
7980
|
delegateStatusWidget.poke();
|
|
7939
7981
|
}).catch((err) => {
|
|
@@ -7979,6 +8021,11 @@ async function buildChildArgs(args, rolePrompt, ctx) {
|
|
|
7979
8021
|
|
|
7980
8022
|
Complete the task below.`, "utf8");
|
|
7981
8023
|
const cliArgs = ["-p", "--no-session", "--append-system-prompt", promptFile];
|
|
8024
|
+
const agentDef = AGENTS[args.agent];
|
|
8025
|
+
if (agentDef?.restricted) {
|
|
8026
|
+
const merged = [.../* @__PURE__ */ new Set([...agentDef.tools.split(",").map((s) => s.trim()), ...ACP_TOOLS])];
|
|
8027
|
+
cliArgs.push("--tools", merged.join(","));
|
|
8028
|
+
}
|
|
7982
8029
|
if (args.model && args.model.includes("/")) {
|
|
7983
8030
|
const [providerId, ...rest] = args.model.split("/");
|
|
7984
8031
|
const modelId = rest.join("/");
|
|
@@ -8185,7 +8232,7 @@ async function statusReport(runtime, ctx) {
|
|
|
8185
8232
|
const activeBlocksList = state.blocks.filter((b) => b.active);
|
|
8186
8233
|
const totalBlocksList = state.blocks;
|
|
8187
8234
|
const lines = [];
|
|
8188
|
-
const versionStr = "0.1.
|
|
8235
|
+
const versionStr = "0.1.26" ? `billion-context-pi@${"0.1.26"}` : "";
|
|
8189
8236
|
lines.push("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E");
|
|
8190
8237
|
lines.push("\u2502 ACP Context Analysis \u2502");
|
|
8191
8238
|
lines.push("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F");
|
|
@@ -8327,6 +8374,116 @@ When a background delegate finishes, an automated completion notification is inj
|
|
|
8327
8374
|
- Arrive asynchronously: if you have moved on to other work, only act on a notification if it is relevant to the current task; otherwise note it and continue.
|
|
8328
8375
|
`;
|
|
8329
8376
|
|
|
8377
|
+
// src/tool-guardrails.ts
|
|
8378
|
+
import {
|
|
8379
|
+
isBashToolResult,
|
|
8380
|
+
isToolCallEventType
|
|
8381
|
+
} from "@earendil-works/pi-coding-agent";
|
|
8382
|
+
function resolveBashTimeout(input, defaultTimeout) {
|
|
8383
|
+
if (input.timeout !== void 0) return void 0;
|
|
8384
|
+
const d = defaultTimeout ?? DEFAULT_TOOL_BASH_TIMEOUT;
|
|
8385
|
+
if (!Number.isFinite(d) || d <= 0) return void 0;
|
|
8386
|
+
return d;
|
|
8387
|
+
}
|
|
8388
|
+
function capToolOutput(content, maxBytes, fullPath) {
|
|
8389
|
+
const max = maxBytes ?? DEFAULT_TOOL_OUTPUT_MAX_BYTES;
|
|
8390
|
+
if (!Number.isFinite(max) || max <= 0) return void 0;
|
|
8391
|
+
const kept = [];
|
|
8392
|
+
const texts = [];
|
|
8393
|
+
for (const c of content) {
|
|
8394
|
+
if (c.type === "text") texts.push(c.text);
|
|
8395
|
+
else kept.push(c);
|
|
8396
|
+
}
|
|
8397
|
+
if (texts.length === 0) return void 0;
|
|
8398
|
+
const combined = texts.join("\n");
|
|
8399
|
+
const total = Buffer.byteLength(combined, "utf8");
|
|
8400
|
+
if (total <= max) return void 0;
|
|
8401
|
+
const head = keepHead(combined, max);
|
|
8402
|
+
const dropped = total - Buffer.byteLength(head, "utf8");
|
|
8403
|
+
kept.push({ type: "text", text: head + buildCapNotice(dropped, max, fullPath) });
|
|
8404
|
+
return kept;
|
|
8405
|
+
}
|
|
8406
|
+
var TIMEOUT_RE = /Command timed out after (\d+) seconds/;
|
|
8407
|
+
function detectBashTimeout(content) {
|
|
8408
|
+
for (const c of content) {
|
|
8409
|
+
if (c.type !== "text") continue;
|
|
8410
|
+
const m = c.text.match(TIMEOUT_RE);
|
|
8411
|
+
if (m) return Number(m[1]);
|
|
8412
|
+
}
|
|
8413
|
+
return void 0;
|
|
8414
|
+
}
|
|
8415
|
+
function appendTimeoutNotice(content, secs) {
|
|
8416
|
+
const notice = buildTimeoutNotice(secs);
|
|
8417
|
+
const next = [...content];
|
|
8418
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
8419
|
+
const part = next[i];
|
|
8420
|
+
if (part && part.type === "text") {
|
|
8421
|
+
next[i] = { type: "text", text: part.text + notice };
|
|
8422
|
+
return next;
|
|
8423
|
+
}
|
|
8424
|
+
}
|
|
8425
|
+
next.push({ type: "text", text: notice });
|
|
8426
|
+
return next;
|
|
8427
|
+
}
|
|
8428
|
+
function keepHead(str, maxBytes) {
|
|
8429
|
+
const buf = Buffer.from(str, "utf8");
|
|
8430
|
+
if (buf.length <= maxBytes) return str;
|
|
8431
|
+
let end = maxBytes;
|
|
8432
|
+
while (end > 0) {
|
|
8433
|
+
const b = buf[end];
|
|
8434
|
+
if (b === void 0 || (b & 192) !== 128) break;
|
|
8435
|
+
end--;
|
|
8436
|
+
}
|
|
8437
|
+
let head = buf.subarray(0, end).toString("utf8");
|
|
8438
|
+
const nl = head.lastIndexOf("\n");
|
|
8439
|
+
if (nl >= Math.floor(maxBytes / 2)) head = head.slice(0, nl);
|
|
8440
|
+
return head;
|
|
8441
|
+
}
|
|
8442
|
+
function buildCapNotice(dropped, maxBytes, fullPath) {
|
|
8443
|
+
const where = fullPath ? `Full output saved to: ${fullPath} \u2014 read it to see everything.` : "To see more, narrow the query or redirect output to a file and read the relevant slice.";
|
|
8444
|
+
return `
|
|
8445
|
+
|
|
8446
|
+
[ACP guardrail: output capped at ${formatBytes(maxBytes)} (~${formatBytes(dropped)} dropped). ${where}]`;
|
|
8447
|
+
}
|
|
8448
|
+
function buildTimeoutNotice(secs) {
|
|
8449
|
+
const suggested = Math.min(Math.max(Math.ceil(secs * 2), 120), 3600);
|
|
8450
|
+
return `
|
|
8451
|
+
|
|
8452
|
+
[ACP guardrail: command killed after ${secs}s. To give it more time, re-run the bash tool with a larger \`timeout\` argument (e.g. \`"timeout": ${suggested}\`).]`;
|
|
8453
|
+
}
|
|
8454
|
+
function formatBytes(n) {
|
|
8455
|
+
return n >= 1024 ? `${(n / 1024).toFixed(1)}KB` : `${n}B`;
|
|
8456
|
+
}
|
|
8457
|
+
function wireToolGuardrails(pi, runtime) {
|
|
8458
|
+
pi.on("tool_call", (event) => {
|
|
8459
|
+
if (!isToolCallEventType("bash", event)) return;
|
|
8460
|
+
const t = resolveBashTimeout(event.input, runtime.adapter.toolBashDefaultTimeout);
|
|
8461
|
+
if (t !== void 0) {
|
|
8462
|
+
event.input.timeout = t;
|
|
8463
|
+
debug.event("guardrail-bash-timeout", { applied: t });
|
|
8464
|
+
}
|
|
8465
|
+
});
|
|
8466
|
+
pi.on("tool_result", (event) => {
|
|
8467
|
+
const isBash = isBashToolResult(event);
|
|
8468
|
+
const fullPath = isBash ? event.details?.fullOutputPath : void 0;
|
|
8469
|
+
const timeoutSecs = isBash && event.isError ? detectBashTimeout(event.content) : void 0;
|
|
8470
|
+
let modified;
|
|
8471
|
+
const max = runtime.adapter.toolOutputMaxBytes;
|
|
8472
|
+
if (max !== void 0 && max > 0) {
|
|
8473
|
+
const next = capToolOutput(event.content, max, fullPath);
|
|
8474
|
+
if (next) {
|
|
8475
|
+
modified = next;
|
|
8476
|
+
debug.event("guardrail-output-cap", { max, hadPath: !!fullPath });
|
|
8477
|
+
}
|
|
8478
|
+
}
|
|
8479
|
+
if (timeoutSecs !== void 0) {
|
|
8480
|
+
modified = appendTimeoutNotice(modified ?? event.content, timeoutSecs);
|
|
8481
|
+
debug.event("guardrail-bash-timeout-notice", { secs: timeoutSecs });
|
|
8482
|
+
}
|
|
8483
|
+
if (modified) return { content: modified };
|
|
8484
|
+
});
|
|
8485
|
+
}
|
|
8486
|
+
|
|
8330
8487
|
// src/update.ts
|
|
8331
8488
|
import { readFile, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
8332
8489
|
import { join as join5, dirname as dirname3 } from "path";
|
|
@@ -8433,7 +8590,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
8433
8590
|
const data = await res.json();
|
|
8434
8591
|
const latest = data.version;
|
|
8435
8592
|
if (!latest) return;
|
|
8436
|
-
const current = runtimeVersion ?? "0.1.
|
|
8593
|
+
const current = runtimeVersion ?? "0.1.26";
|
|
8437
8594
|
debug.event("update-check", {
|
|
8438
8595
|
current,
|
|
8439
8596
|
latest,
|
|
@@ -8468,7 +8625,7 @@ import { readFile as readFile2, writeFile as writeFile4, stat, copyFile, rename
|
|
|
8468
8625
|
import { existsSync } from "fs";
|
|
8469
8626
|
import { homedir as homedir4 } from "os";
|
|
8470
8627
|
import { join as join6 } from "path";
|
|
8471
|
-
var
|
|
8628
|
+
var ACP_TOOLS2 = ["compress", "decompress", "search_context", "acp_status"];
|
|
8472
8629
|
var BUILTIN_DEFAULT_TOOLS = {
|
|
8473
8630
|
advisor: ["read", "grep", "find", "ls", "bash", "intercom"],
|
|
8474
8631
|
"context-builder": ["read", "grep", "find", "ls", "bash", "write", "web_search", "intercom"],
|
|
@@ -8488,9 +8645,9 @@ function resolveAgentDir() {
|
|
|
8488
8645
|
}
|
|
8489
8646
|
function desiredTools(existing, name) {
|
|
8490
8647
|
const base = Array.isArray(existing?.tools) && existing.tools.length > 0 ? [...existing.tools] : [...BUILTIN_DEFAULT_TOOLS[name] ?? []];
|
|
8491
|
-
const hasAll =
|
|
8648
|
+
const hasAll = ACP_TOOLS2.every((t) => base.includes(t));
|
|
8492
8649
|
if (hasAll) return { tools: base, changed: false };
|
|
8493
|
-
for (const t of
|
|
8650
|
+
for (const t of ACP_TOOLS2) if (!base.includes(t)) base.push(t);
|
|
8494
8651
|
return { tools: base, changed: true };
|
|
8495
8652
|
}
|
|
8496
8653
|
async function ensureSubagentAcpTools(settingsPath) {
|
|
@@ -8561,7 +8718,7 @@ async function ensureSubagentAcpTools(settingsPath) {
|
|
|
8561
8718
|
if (typeof v !== "object" || v === null) throw new Error("agentOverrides missing after write");
|
|
8562
8719
|
for (const name of Object.keys(BUILTIN_DEFAULT_TOOLS)) {
|
|
8563
8720
|
const tools = v[name]?.tools;
|
|
8564
|
-
if (!Array.isArray(tools) || !
|
|
8721
|
+
if (!Array.isArray(tools) || !ACP_TOOLS2.every((t) => tools.includes(t))) {
|
|
8565
8722
|
throw new Error(`${name} missing ACP tools after write`);
|
|
8566
8723
|
}
|
|
8567
8724
|
}
|
|
@@ -8613,7 +8770,7 @@ async function loadUserConfig(cwd) {
|
|
|
8613
8770
|
function join8(...parts) {
|
|
8614
8771
|
return path3.join(...parts);
|
|
8615
8772
|
}
|
|
8616
|
-
var KNOWN = /* @__PURE__ */ new Set(["debug", "autoUpdate", "modelContextLimit", "delegate"]);
|
|
8773
|
+
var KNOWN = /* @__PURE__ */ new Set(["debug", "autoUpdate", "modelContextLimit", "delegate", "toolBashDefaultTimeout", "toolOutputMaxBytes"]);
|
|
8617
8774
|
function pickKnown(parsed) {
|
|
8618
8775
|
const out = {};
|
|
8619
8776
|
for (const [k, v] of Object.entries(parsed)) {
|
|
@@ -8641,6 +8798,7 @@ function createAcpExtension(adapter = {}) {
|
|
|
8641
8798
|
wireSessionLifecycle(pi, runtime);
|
|
8642
8799
|
wireContextTransform(pi, runtime);
|
|
8643
8800
|
wireSystemPrompt(pi, runtime);
|
|
8801
|
+
wireToolGuardrails(pi, runtime);
|
|
8644
8802
|
pi.registerTool(makeCompressTool(runtime));
|
|
8645
8803
|
pi.registerTool(makeDecompressTool(runtime));
|
|
8646
8804
|
pi.registerTool(makeSearchTool(runtime));
|
|
@@ -8767,7 +8925,12 @@ ${prompt}` };
|
|
|
8767
8925
|
function collectOriginals(entries) {
|
|
8768
8926
|
const map = /* @__PURE__ */ new Map();
|
|
8769
8927
|
for (const entry of entries) {
|
|
8770
|
-
if (entry.type === "message")
|
|
8928
|
+
if (entry.type === "message") {
|
|
8929
|
+
map.set(entry.id, entry.message);
|
|
8930
|
+
} else if (entry.type === "custom_message") {
|
|
8931
|
+
const content = typeof entry.content === "string" ? [{ type: "text", text: entry.content }] : entry.content;
|
|
8932
|
+
map.set(entry.id, { role: "user", content });
|
|
8933
|
+
}
|
|
8771
8934
|
}
|
|
8772
8935
|
return map;
|
|
8773
8936
|
}
|