billion-context-pi 0.1.28 → 0.1.30
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 +17 -2
- package/README.zh-CN.md +19 -2
- package/dist/compat.d.ts +23 -0
- package/dist/config.d.ts +3 -1
- package/dist/index.js +296 -99
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +12 -2
- package/dist/runtime.d.ts +4 -2
- package/dist/update.d.ts +1 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -2411,9 +2411,9 @@ function projectMessage(message, id) {
|
|
|
2411
2411
|
if (calls.length === 1) {
|
|
2412
2412
|
const call = calls[0];
|
|
2413
2413
|
const argStr = stringifyArgs(call.arguments);
|
|
2414
|
-
const
|
|
2414
|
+
const text2 = argStr && textParts ? `${textParts}
|
|
2415
2415
|
${argStr}` : argStr || textParts;
|
|
2416
|
-
return [{ id, role: "assistant", contentType: "tool-call", toolName: call.name, toolCallId: call.id, text }];
|
|
2416
|
+
return [{ id, role: "assistant", contentType: "tool-call", toolName: call.name, toolCallId: call.id, text: text2 }];
|
|
2417
2417
|
}
|
|
2418
2418
|
return calls.map((call) => {
|
|
2419
2419
|
const argStr = stringifyArgs(call.arguments);
|
|
@@ -2427,7 +2427,9 @@ ${argStr}` : argStr || textParts;
|
|
|
2427
2427
|
};
|
|
2428
2428
|
});
|
|
2429
2429
|
}
|
|
2430
|
-
|
|
2430
|
+
const text = extractText(msg.content);
|
|
2431
|
+
if (!text.trim()) return [];
|
|
2432
|
+
return [{ id, role: "assistant", contentType: "text", text }];
|
|
2431
2433
|
}
|
|
2432
2434
|
const customText = extractText(msg.content) || fallbackText(msg);
|
|
2433
2435
|
return customText.length > 0 ? [{ id, role: "user", contentType: "text", text: customText }] : [];
|
|
@@ -2574,7 +2576,87 @@ function peelRefTagBlocks(blocks) {
|
|
|
2574
2576
|
|
|
2575
2577
|
// src/state.ts
|
|
2576
2578
|
import { promises as fs } from "fs";
|
|
2579
|
+
import * as path2 from "path";
|
|
2580
|
+
|
|
2581
|
+
// src/log.ts
|
|
2582
|
+
import { appendFileSync, mkdirSync, statSync, renameSync, existsSync } from "fs";
|
|
2577
2583
|
import * as path from "path";
|
|
2584
|
+
import { homedir } from "os";
|
|
2585
|
+
var MAX_BYTES = 10 * 1024 * 1024;
|
|
2586
|
+
var ENV_DEBUG = process.env.ACP_DEBUG === "1" || process.env.ACP_DEBUG === "true";
|
|
2587
|
+
function resolveLogFile() {
|
|
2588
|
+
return process.env.ACP_LOG_FILE ?? path.join(homedir(), ".pi", "acp.log");
|
|
2589
|
+
}
|
|
2590
|
+
var runtimeDebug = null;
|
|
2591
|
+
function setDebugEnabled(enabled) {
|
|
2592
|
+
runtimeDebug = enabled;
|
|
2593
|
+
}
|
|
2594
|
+
function debugOn() {
|
|
2595
|
+
return runtimeDebug ?? ENV_DEBUG;
|
|
2596
|
+
}
|
|
2597
|
+
function fmt(v) {
|
|
2598
|
+
if (typeof v === "string") return v;
|
|
2599
|
+
if (v instanceof Error) return v.stack || String(v);
|
|
2600
|
+
try {
|
|
2601
|
+
return JSON.stringify(v);
|
|
2602
|
+
} catch {
|
|
2603
|
+
return String(v);
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
function ts() {
|
|
2607
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
2608
|
+
}
|
|
2609
|
+
function writeLine(level, scope, fields) {
|
|
2610
|
+
const file = resolveLogFile();
|
|
2611
|
+
try {
|
|
2612
|
+
if (existsSync(file) && statSync(file).size >= MAX_BYTES) {
|
|
2613
|
+
renameSync(file, file + ".old");
|
|
2614
|
+
}
|
|
2615
|
+
} catch {
|
|
2616
|
+
}
|
|
2617
|
+
const body = Object.keys(fields).map((k) => `${k}=${fmt(fields[k])}`).join(" ");
|
|
2618
|
+
const line = `${ts()} [${level}] [${scope}] ${body}
|
|
2619
|
+
`;
|
|
2620
|
+
try {
|
|
2621
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
2622
|
+
appendFileSync(file, line);
|
|
2623
|
+
} catch {
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
function closeLogStream() {
|
|
2627
|
+
}
|
|
2628
|
+
function logError(scope, fields) {
|
|
2629
|
+
writeLine("error", scope, fields);
|
|
2630
|
+
}
|
|
2631
|
+
function logWarn(scope, fields) {
|
|
2632
|
+
writeLine("warn", scope, fields);
|
|
2633
|
+
}
|
|
2634
|
+
function logInfo(scope, fields) {
|
|
2635
|
+
writeLine("info", scope, fields);
|
|
2636
|
+
}
|
|
2637
|
+
function logThrow(scope, err, extra = {}) {
|
|
2638
|
+
const fields = { ...extra };
|
|
2639
|
+
if (err instanceof Error) {
|
|
2640
|
+
fields.error = err.message;
|
|
2641
|
+
fields.stack = err.stack ?? "";
|
|
2642
|
+
} else {
|
|
2643
|
+
fields.error = String(err);
|
|
2644
|
+
}
|
|
2645
|
+
writeLine("error", scope, fields);
|
|
2646
|
+
}
|
|
2647
|
+
var debug = {
|
|
2648
|
+
get enabled() {
|
|
2649
|
+
return debugOn();
|
|
2650
|
+
},
|
|
2651
|
+
get logFile() {
|
|
2652
|
+
return resolveLogFile();
|
|
2653
|
+
},
|
|
2654
|
+
event(scope, fields) {
|
|
2655
|
+
if (debugOn()) writeLine("debug", scope, fields);
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
|
|
2659
|
+
// src/state.ts
|
|
2578
2660
|
var STATE_SUFFIX = ".acp.json";
|
|
2579
2661
|
function stateFileFor(sessionFile) {
|
|
2580
2662
|
if (sessionFile) return sessionFile + STATE_SUFFIX;
|
|
@@ -2592,7 +2674,11 @@ var SessionStateStore = class {
|
|
|
2592
2674
|
const raw = await fs.readFile(file, "utf8");
|
|
2593
2675
|
const parsed = JSON.parse(raw);
|
|
2594
2676
|
if (parsed && Array.isArray(parsed.blocks)) state = mergeInitialState(parsed);
|
|
2595
|
-
} catch {
|
|
2677
|
+
} catch (e) {
|
|
2678
|
+
const code = e.code;
|
|
2679
|
+
if (code !== "ENOENT") {
|
|
2680
|
+
logWarn("state", { event: "load-failed", file, error: e instanceof Error ? e.message : String(e) });
|
|
2681
|
+
}
|
|
2596
2682
|
}
|
|
2597
2683
|
}
|
|
2598
2684
|
this.cache = state;
|
|
@@ -2604,12 +2690,17 @@ var SessionStateStore = class {
|
|
|
2604
2690
|
if (!file) return;
|
|
2605
2691
|
this.cache = state;
|
|
2606
2692
|
this.loadedKey = file;
|
|
2607
|
-
const dir =
|
|
2608
|
-
await fs.mkdir(dir, { recursive: true }).catch(() => {
|
|
2693
|
+
const dir = path2.dirname(file);
|
|
2694
|
+
await fs.mkdir(dir, { recursive: true }).catch((e) => {
|
|
2695
|
+
logError("state", { event: "save-mkdir-failed", dir, error: e instanceof Error ? e.message : String(e) });
|
|
2609
2696
|
});
|
|
2610
|
-
const tmp =
|
|
2611
|
-
|
|
2612
|
-
|
|
2697
|
+
const tmp = path2.join(dir, `.acp-tmp-${path2.basename(file)}`);
|
|
2698
|
+
try {
|
|
2699
|
+
await fs.writeFile(tmp, JSON.stringify(state), "utf8");
|
|
2700
|
+
await fs.rename(tmp, file);
|
|
2701
|
+
} catch (e) {
|
|
2702
|
+
logError("state", { event: "save-failed", file, error: e instanceof Error ? e.message : String(e) });
|
|
2703
|
+
}
|
|
2613
2704
|
}
|
|
2614
2705
|
invalidate() {
|
|
2615
2706
|
this.cache = null;
|
|
@@ -2639,6 +2730,50 @@ function isPiHost(sm) {
|
|
|
2639
2730
|
const source = sm;
|
|
2640
2731
|
return typeof source.buildContextEntries === "function";
|
|
2641
2732
|
}
|
|
2733
|
+
function mergeLiveEntries(entries, live) {
|
|
2734
|
+
const persisted = entries.filter((e) => e.type === "message");
|
|
2735
|
+
const out = [];
|
|
2736
|
+
let p = 0;
|
|
2737
|
+
let unmatched = 0;
|
|
2738
|
+
for (let i = 0; i < live.length; i++) {
|
|
2739
|
+
const msg = live[i];
|
|
2740
|
+
let matched;
|
|
2741
|
+
let j = p;
|
|
2742
|
+
while (j < persisted.length && persisted[j].message.role !== msg.role) j++;
|
|
2743
|
+
if (j < persisted.length && sameMessage(persisted[j].message, msg)) {
|
|
2744
|
+
matched = persisted[j];
|
|
2745
|
+
p = j + 1;
|
|
2746
|
+
}
|
|
2747
|
+
if (matched) {
|
|
2748
|
+
out.push(matched);
|
|
2749
|
+
} else {
|
|
2750
|
+
unmatched++;
|
|
2751
|
+
out.push({
|
|
2752
|
+
type: "message",
|
|
2753
|
+
id: `live-${i}`,
|
|
2754
|
+
parentId: null,
|
|
2755
|
+
timestamp: String(msg.timestamp ?? Date.now()),
|
|
2756
|
+
message: msg
|
|
2757
|
+
});
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
if (unmatched > 0) logInfo("runtime", { event: "merge-live-entries", live: live.length, unmatched });
|
|
2761
|
+
return out;
|
|
2762
|
+
}
|
|
2763
|
+
function sameMessage(a, b) {
|
|
2764
|
+
const ra = a.role;
|
|
2765
|
+
const rb = b.role;
|
|
2766
|
+
if (ra !== rb) return false;
|
|
2767
|
+
const ca = a.content;
|
|
2768
|
+
const cb = b.content;
|
|
2769
|
+
if (ca === void 0 || cb === void 0) return false;
|
|
2770
|
+
try {
|
|
2771
|
+
return JSON.stringify(ca) === JSON.stringify(cb);
|
|
2772
|
+
} catch (e) {
|
|
2773
|
+
logWarn("runtime", { event: "message-compare-failed", error: e instanceof Error ? e.message : String(e) });
|
|
2774
|
+
return a === b;
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2642
2777
|
function createRuntime(adapter) {
|
|
2643
2778
|
const core = createCore({ countTokens: defaultCountTokens });
|
|
2644
2779
|
const store = new SessionStateStore();
|
|
@@ -2667,11 +2802,12 @@ function createRuntime(adapter) {
|
|
|
2667
2802
|
function configFor(ctx) {
|
|
2668
2803
|
return resolveConfig(adapterRef, liveContextLimit(ctx));
|
|
2669
2804
|
}
|
|
2670
|
-
async function stateFor(ctx) {
|
|
2805
|
+
async function stateFor(ctx, liveMessages) {
|
|
2671
2806
|
const sm = ctx.sessionManager;
|
|
2672
2807
|
const state = await store.load(sm.getSessionFile() ?? void 0, sm.getSessionId());
|
|
2673
2808
|
const entries = readContextEntries(sm);
|
|
2674
|
-
|
|
2809
|
+
const merged = isPiHost(sm) || !liveMessages || liveMessages.length === 0 ? entries : mergeLiveEntries(entries, liveMessages);
|
|
2810
|
+
return { state, coreMessages: entriesToCoreMessages(merged), entries: merged };
|
|
2675
2811
|
}
|
|
2676
2812
|
async function save(state, ctx) {
|
|
2677
2813
|
const sm = ctx.sessionManager;
|
|
@@ -7082,64 +7218,6 @@ __export(typebox_exports, {
|
|
|
7082
7218
|
With: () => With2
|
|
7083
7219
|
});
|
|
7084
7220
|
|
|
7085
|
-
// src/log.ts
|
|
7086
|
-
import { promises as fs2 } from "fs";
|
|
7087
|
-
import * as path2 from "path";
|
|
7088
|
-
import { homedir } from "os";
|
|
7089
|
-
var ENV_DEBUG = process.env.ACP_DEBUG === "1" || process.env.ACP_DEBUG === "true";
|
|
7090
|
-
var LOG_FILE = process.env.ACP_LOG_FILE ?? path2.join(homedir(), ".pi", "acp-debug.log");
|
|
7091
|
-
var runtimeDebug = null;
|
|
7092
|
-
var initialized = false;
|
|
7093
|
-
function setDebugEnabled(enabled) {
|
|
7094
|
-
runtimeDebug = enabled;
|
|
7095
|
-
}
|
|
7096
|
-
function debugOn() {
|
|
7097
|
-
return runtimeDebug ?? ENV_DEBUG;
|
|
7098
|
-
}
|
|
7099
|
-
async function write(line) {
|
|
7100
|
-
if (!debugOn()) return;
|
|
7101
|
-
if (!initialized) {
|
|
7102
|
-
initialized = true;
|
|
7103
|
-
await fs2.mkdir(path2.dirname(LOG_FILE), { recursive: true }).catch(() => {
|
|
7104
|
-
});
|
|
7105
|
-
}
|
|
7106
|
-
await fs2.appendFile(LOG_FILE, line, "utf8").catch(() => {
|
|
7107
|
-
});
|
|
7108
|
-
}
|
|
7109
|
-
var debug = {
|
|
7110
|
-
get enabled() {
|
|
7111
|
-
return debugOn();
|
|
7112
|
-
},
|
|
7113
|
-
get logFile() {
|
|
7114
|
-
return LOG_FILE;
|
|
7115
|
-
},
|
|
7116
|
-
event(scope, fields) {
|
|
7117
|
-
if (!debugOn()) return;
|
|
7118
|
-
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7119
|
-
const body = Object.entries(fields).map(([k, v]) => `${k}=${fmt(v)}`).join(" ");
|
|
7120
|
-
void write(`${ts} [${scope}] ${body}
|
|
7121
|
-
`);
|
|
7122
|
-
}
|
|
7123
|
-
};
|
|
7124
|
-
function fmt(v) {
|
|
7125
|
-
if (typeof v === "string") return v;
|
|
7126
|
-
if (Array.isArray(v)) {
|
|
7127
|
-
try {
|
|
7128
|
-
return JSON.stringify(v);
|
|
7129
|
-
} catch {
|
|
7130
|
-
return `[${v.length}]`;
|
|
7131
|
-
}
|
|
7132
|
-
}
|
|
7133
|
-
if (v && typeof v === "object") {
|
|
7134
|
-
try {
|
|
7135
|
-
return JSON.stringify(v);
|
|
7136
|
-
} catch {
|
|
7137
|
-
return String(v);
|
|
7138
|
-
}
|
|
7139
|
-
}
|
|
7140
|
-
return String(v);
|
|
7141
|
-
}
|
|
7142
|
-
|
|
7143
7221
|
// src/tokens.ts
|
|
7144
7222
|
function collectCoveredMessageIds(state) {
|
|
7145
7223
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -7195,7 +7273,13 @@ function makeCompressTool(runtime) {
|
|
|
7195
7273
|
],
|
|
7196
7274
|
parameters: CompressParams,
|
|
7197
7275
|
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
7198
|
-
|
|
7276
|
+
let result;
|
|
7277
|
+
try {
|
|
7278
|
+
result = await handleCompress(params, runtime, ctx, toolCallId);
|
|
7279
|
+
} catch (e) {
|
|
7280
|
+
logThrow("compress", e, { sid: ctx.sessionManager.getSessionId(), ranges: params.content?.length ?? 0 });
|
|
7281
|
+
throw e;
|
|
7282
|
+
}
|
|
7199
7283
|
return { details: void 0, content: [{ type: "text", text: result }] };
|
|
7200
7284
|
}
|
|
7201
7285
|
};
|
|
@@ -7240,6 +7324,24 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
7240
7324
|
activeAfter: applied.state.blocks.filter((b) => b.active).length,
|
|
7241
7325
|
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 }))
|
|
7242
7326
|
});
|
|
7327
|
+
logInfo("compress", {
|
|
7328
|
+
sid: ctx.sessionManager.getSessionId(),
|
|
7329
|
+
event: "applied",
|
|
7330
|
+
ranges: ranges.length,
|
|
7331
|
+
blocksCreated,
|
|
7332
|
+
tokensCompressed,
|
|
7333
|
+
beforeTokens,
|
|
7334
|
+
afterTokens,
|
|
7335
|
+
warnings: warnings.length,
|
|
7336
|
+
errors: errors.length,
|
|
7337
|
+
newBlockIds: newBlocks.map((b) => b.blockId)
|
|
7338
|
+
});
|
|
7339
|
+
if (errors.length > 0) {
|
|
7340
|
+
logError("compress", { sid: ctx.sessionManager.getSessionId(), event: "errors", count: errors.length, errors: errors.slice(0, 5) });
|
|
7341
|
+
}
|
|
7342
|
+
if (warnings.length > 0) {
|
|
7343
|
+
logError("compress", { sid: ctx.sessionManager.getSessionId(), event: "warnings", count: warnings.length, warnings: warnings.slice(0, 5) });
|
|
7344
|
+
}
|
|
7243
7345
|
const lines = [`\u25A3 ACP | ${formatK2(beforeTokens)} \u2192 ${formatK2(afterTokens)} tokens (~${formatK2(tokensCompressed)} reclaimed, ${blocksCreated} block${blocksCreated > 1 ? "s" : ""})`];
|
|
7244
7346
|
if (warnings.length > 0) lines.push("\u26A0\uFE0F " + warnings.join("; "));
|
|
7245
7347
|
if (errors.length > 0) lines.push("Errors: " + errors.join("; "));
|
|
@@ -7273,7 +7375,13 @@ function makeDecompressTool(runtime) {
|
|
|
7273
7375
|
],
|
|
7274
7376
|
parameters: DecompressParams,
|
|
7275
7377
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
7276
|
-
|
|
7378
|
+
let result;
|
|
7379
|
+
try {
|
|
7380
|
+
result = await handleDecompress(params, runtime, ctx);
|
|
7381
|
+
} catch (e) {
|
|
7382
|
+
logThrow("decompress", e, { sid: ctx.sessionManager.getSessionId(), blockId: params.blockId });
|
|
7383
|
+
throw e;
|
|
7384
|
+
}
|
|
7277
7385
|
return { details: void 0, content: [{ type: "text", text: result }] };
|
|
7278
7386
|
}
|
|
7279
7387
|
};
|
|
@@ -7322,16 +7430,21 @@ async function handleMessageRef(ref, ownerBlockId, args, ctx) {
|
|
|
7322
7430
|
const wantFile = args.toFile !== void 0 || args.inline === false || text.length >= MESSAGE_INLINE_THRESHOLD;
|
|
7323
7431
|
if (!wantFile) {
|
|
7324
7432
|
debug.event("decompress-message", { ref, ownerBlockId, mode: "inline", chars: text.length });
|
|
7433
|
+
logInfo("decompress", { sid: ctx.sessionManager.getSessionId(), event: "message", mode: "inline", ref, ownerBlockId, chars: text.length });
|
|
7325
7434
|
return `Message ${ref} (${role}, block ${ownerBlockId}, ${text.length} chars) restored inline:
|
|
7326
7435
|
|
|
7327
7436
|
${text}`;
|
|
7328
7437
|
}
|
|
7329
7438
|
const targetPath = args.toFile ? resolveToFilePath(args.toFile) : autoFilePath(`msg-${ref}`);
|
|
7330
|
-
if (typeof targetPath === "object" && "error" in targetPath)
|
|
7439
|
+
if (typeof targetPath === "object" && "error" in targetPath) {
|
|
7440
|
+
logError("decompress", { sid: ctx.sessionManager.getSessionId(), event: "message-path-rejected", ref, toFile: args.toFile });
|
|
7441
|
+
return targetPath.error;
|
|
7442
|
+
}
|
|
7331
7443
|
await mkdir(AUTO_DIR, { recursive: true }).catch(() => {
|
|
7332
7444
|
});
|
|
7333
7445
|
await writeFile(targetPath, text, "utf8");
|
|
7334
7446
|
debug.event("decompress-message", { ref, ownerBlockId, mode: "file", path: targetPath, chars: text.length });
|
|
7447
|
+
logInfo("decompress", { sid: ctx.sessionManager.getSessionId(), event: "message", mode: "file", ref, ownerBlockId, path: targetPath, chars: text.length });
|
|
7335
7448
|
return [
|
|
7336
7449
|
`Message ${ref} (${role}, block ${ownerBlockId}, ${text.length} chars) written to ${targetPath}.`,
|
|
7337
7450
|
"Block stays compressed \u2014 context unchanged. Use the read tool to access the content.",
|
|
@@ -7359,16 +7472,21 @@ async function handleDecompress(args, runtime, ctx) {
|
|
|
7359
7472
|
if (count === 0) return `Block ${blockId} has no restorable message content.`;
|
|
7360
7473
|
if (args.inline === true && !args.toFile) {
|
|
7361
7474
|
debug.event("decompress", { blockId, full, count, mode: "inline" });
|
|
7475
|
+
logInfo("decompress", { sid: ctx.sessionManager.getSessionId(), event: "block", mode: "inline", blockId, full, count });
|
|
7362
7476
|
return `Restored block ${blockId} (${count} item${count === 1 ? "" : "s"}) inline:
|
|
7363
7477
|
|
|
7364
7478
|
${text}`;
|
|
7365
7479
|
}
|
|
7366
7480
|
const targetPath = args.toFile ? resolveToFilePath(args.toFile) : autoFilePath(blockId);
|
|
7367
|
-
if (typeof targetPath === "object" && "error" in targetPath)
|
|
7481
|
+
if (typeof targetPath === "object" && "error" in targetPath) {
|
|
7482
|
+
logError("decompress", { sid: ctx.sessionManager.getSessionId(), event: "block-path-rejected", blockId, toFile: args.toFile });
|
|
7483
|
+
return targetPath.error;
|
|
7484
|
+
}
|
|
7368
7485
|
await mkdir(AUTO_DIR, { recursive: true }).catch(() => {
|
|
7369
7486
|
});
|
|
7370
7487
|
await writeFile(targetPath, text, "utf8");
|
|
7371
7488
|
debug.event("decompress", { blockId, full, count, mode: "file", path: targetPath, chars: text.length });
|
|
7489
|
+
logInfo("decompress", { sid: ctx.sessionManager.getSessionId(), event: "block", mode: "file", blockId, full, count, path: targetPath, chars: text.length });
|
|
7372
7490
|
const itemWord = count === 1 ? "item" : "items";
|
|
7373
7491
|
const lines = [
|
|
7374
7492
|
`Block ${blockId} (${count} ${itemWord}, ${text.length} chars) written to ${targetPath}.`,
|
|
@@ -7396,7 +7514,7 @@ function buildMessageOwnerMap(state) {
|
|
|
7396
7514
|
return m;
|
|
7397
7515
|
}
|
|
7398
7516
|
function estimateTokens2(text) {
|
|
7399
|
-
if (!text) return 0;
|
|
7517
|
+
if (typeof text !== "string" || !text) return 0;
|
|
7400
7518
|
const cjk = text.match(/[\u4e00-\u9fff\u3040-\u30ff\uac00-\ud7af]/g);
|
|
7401
7519
|
const cjkCount = cjk?.length ?? 0;
|
|
7402
7520
|
return cjkCount + Math.ceil((text.length - cjkCount) / 4);
|
|
@@ -7458,7 +7576,13 @@ function makeSearchTool(runtime) {
|
|
|
7458
7576
|
],
|
|
7459
7577
|
parameters: SearchParams,
|
|
7460
7578
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
7461
|
-
|
|
7579
|
+
let result;
|
|
7580
|
+
try {
|
|
7581
|
+
result = await handleSearch(params, runtime, ctx);
|
|
7582
|
+
} catch (e) {
|
|
7583
|
+
logThrow("search", e, { sid: ctx.sessionManager.getSessionId(), query: params.query });
|
|
7584
|
+
throw e;
|
|
7585
|
+
}
|
|
7462
7586
|
return { details: void 0, content: [{ type: "text", text: result }] };
|
|
7463
7587
|
}
|
|
7464
7588
|
};
|
|
@@ -7523,7 +7647,13 @@ function makeStatusTool(runtime) {
|
|
|
7523
7647
|
],
|
|
7524
7648
|
parameters: StatusParams,
|
|
7525
7649
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
7526
|
-
|
|
7650
|
+
let result;
|
|
7651
|
+
try {
|
|
7652
|
+
result = await handleStatus(params, runtime, ctx);
|
|
7653
|
+
} catch (e) {
|
|
7654
|
+
logThrow("status", e, { sid: ctx.sessionManager.getSessionId(), scope: params.scope ?? null });
|
|
7655
|
+
throw e;
|
|
7656
|
+
}
|
|
7527
7657
|
return { details: void 0, content: [{ type: "text", text: result }] };
|
|
7528
7658
|
}
|
|
7529
7659
|
};
|
|
@@ -8103,6 +8233,7 @@ function makeDelegateCancelTool(_pi) {
|
|
|
8103
8233
|
run.child?.kill("SIGTERM");
|
|
8104
8234
|
} catch (err) {
|
|
8105
8235
|
debug.event("delegate-cancel-kill-error", { runId, error: String(err) });
|
|
8236
|
+
logError("delegate", { event: "cancel-kill-error", runId, error: String(err) });
|
|
8106
8237
|
}
|
|
8107
8238
|
delegateStatusWidget.poke();
|
|
8108
8239
|
return {
|
|
@@ -8133,8 +8264,11 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8133
8264
|
const requestedAsync = args.async !== false;
|
|
8134
8265
|
if (requestedAsync && !isAsync) {
|
|
8135
8266
|
debug.event("delegate-async-downgraded", { reason: `mode=${ctx.mode}` });
|
|
8267
|
+
logInfo("delegate", { event: "async-downgraded", reason: `mode=${ctx.mode}` });
|
|
8136
8268
|
}
|
|
8137
|
-
|
|
8269
|
+
const runId = `del_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
8270
|
+
debug.event("delegate-spawn", { agent: args.agent, runId, cwd, async: isAsync, useJsonStream, cliArgs });
|
|
8271
|
+
logInfo("delegate", { event: "spawn", agent: args.agent, runId, cwd, async: isAsync, useJsonStream, mode: ctx.mode, parentDepth });
|
|
8138
8272
|
const child = spawn(process.execPath, [process.argv[1], ...cliArgs], {
|
|
8139
8273
|
cwd,
|
|
8140
8274
|
env: childEnv,
|
|
@@ -8143,10 +8277,10 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8143
8277
|
});
|
|
8144
8278
|
child.stdin?.once("error", (e) => {
|
|
8145
8279
|
debug.event("delegate-stdin-error", { runId: "pre-spawn", error: String(e) });
|
|
8280
|
+
logError("delegate", { event: "stdin-error", runId, error: String(e) });
|
|
8146
8281
|
});
|
|
8147
8282
|
child.stdin?.end(args.task);
|
|
8148
8283
|
let stderrText = "";
|
|
8149
|
-
const runId = `del_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
8150
8284
|
const startedAt = Date.now();
|
|
8151
8285
|
if (isAsync) {
|
|
8152
8286
|
let settled = false;
|
|
@@ -8278,23 +8412,27 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8278
8412
|
run.finishedAt = Date.now();
|
|
8279
8413
|
if (run.waiter) {
|
|
8280
8414
|
debug.event("delegate-done", { runId, code, status: run.status, injected: false, via: "wait", outLen: output.length, file: file2 });
|
|
8415
|
+
logInfo("delegate", { event: "done", runId, agent: args.agent, code, status: run.status, injected: false, via: "wait", outLen: output.length, file: file2 });
|
|
8281
8416
|
run.waiter();
|
|
8282
8417
|
delegateStatusWidget.poke();
|
|
8283
8418
|
return;
|
|
8284
8419
|
}
|
|
8285
8420
|
if (run.consumed) {
|
|
8286
8421
|
debug.event("delegate-done", { runId, code, status: run.status, injected: false, via: "consumed", outLen: output.length, file: file2 });
|
|
8422
|
+
logInfo("delegate", { event: "done", runId, agent: args.agent, code, status: run.status, injected: false, via: "consumed", outLen: output.length, file: file2 });
|
|
8287
8423
|
delegateStatusWidget.poke();
|
|
8288
8424
|
return;
|
|
8289
8425
|
}
|
|
8290
8426
|
const injected = injectResult(pi, args.agent, runId, args.task, code, file2, run.timedOut);
|
|
8291
8427
|
run.injected = injected;
|
|
8292
8428
|
debug.event("delegate-done", { runId, code, status: run.status, injected, outLen: output.length, file: file2 });
|
|
8429
|
+
logInfo("delegate", { event: "done", runId, agent: args.agent, code, status: run.status, injected, outLen: output.length, file: file2 });
|
|
8293
8430
|
delegateStatusWidget.poke();
|
|
8294
8431
|
} catch (err) {
|
|
8295
8432
|
run.status = "failed";
|
|
8296
8433
|
run.finishedAt = Date.now();
|
|
8297
8434
|
debug.event("delegate-done-error", { runId, error: String(err) });
|
|
8435
|
+
logError("delegate", { event: "done-error", runId, agent: args.agent, error: String(err) });
|
|
8298
8436
|
run.waiter?.();
|
|
8299
8437
|
delegateStatusWidget.poke();
|
|
8300
8438
|
}
|
|
@@ -8315,6 +8453,7 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8315
8453
|
run.finishedAt = Date.now();
|
|
8316
8454
|
run.result = { code: null, file: "", body: `spawn error: ${String(err)}` };
|
|
8317
8455
|
debug.event("delegate-spawn-error", { runId, error: String(err) });
|
|
8456
|
+
logError("delegate", { event: "spawn-error", runId, agent: args.agent, error: String(err) });
|
|
8318
8457
|
run.waiter?.();
|
|
8319
8458
|
delegateStatusWidget.poke();
|
|
8320
8459
|
}
|
|
@@ -8409,6 +8548,7 @@ function injectResult(pi, agent, runId, task, code, file, timedOut) {
|
|
|
8409
8548
|
const send = pi.sendUserMessage;
|
|
8410
8549
|
if (typeof send !== "function") {
|
|
8411
8550
|
debug.event("delegate-inject-skipped", { runId, reason: "sendUserMessage unavailable" });
|
|
8551
|
+
logWarn("delegate", { event: "inject-skipped", runId, reason: "sendUserMessage unavailable" });
|
|
8412
8552
|
return false;
|
|
8413
8553
|
}
|
|
8414
8554
|
const status = code === 0 ? "completed" : "failed";
|
|
@@ -8422,6 +8562,7 @@ function injectResult(pi, agent, runId, task, code, file, timedOut) {
|
|
|
8422
8562
|
return true;
|
|
8423
8563
|
} catch (err) {
|
|
8424
8564
|
debug.event("delegate-inject-error", { runId, error: String(err) });
|
|
8565
|
+
logError("delegate", { event: "inject-error", runId, agent, error: String(err) });
|
|
8425
8566
|
return false;
|
|
8426
8567
|
}
|
|
8427
8568
|
}
|
|
@@ -8449,6 +8590,7 @@ async function persistResult(runId, body) {
|
|
|
8449
8590
|
return file;
|
|
8450
8591
|
} catch (err) {
|
|
8451
8592
|
debug.event("delegate-persist-error", { runId, file, error: String(err) });
|
|
8593
|
+
logError("delegate", { event: "persist-error", runId, file, error: String(err) });
|
|
8452
8594
|
return "";
|
|
8453
8595
|
}
|
|
8454
8596
|
}
|
|
@@ -8464,6 +8606,23 @@ function truncate2(s, n) {
|
|
|
8464
8606
|
return s.slice(0, n - 1) + "\u2026";
|
|
8465
8607
|
}
|
|
8466
8608
|
|
|
8609
|
+
// src/compat.ts
|
|
8610
|
+
function normalizeSystemPrompt(input) {
|
|
8611
|
+
if (input === void 0) return "";
|
|
8612
|
+
if (Array.isArray(input)) return input.join("\n");
|
|
8613
|
+
return input;
|
|
8614
|
+
}
|
|
8615
|
+
function formatSystemPromptForEvent(base, append) {
|
|
8616
|
+
const normalized = normalizeSystemPrompt(base);
|
|
8617
|
+
return `${normalized}
|
|
8618
|
+
|
|
8619
|
+
${append}`;
|
|
8620
|
+
}
|
|
8621
|
+
function getSystemPromptText(ctx) {
|
|
8622
|
+
const result = ctx.getSystemPrompt?.();
|
|
8623
|
+
return normalizeSystemPrompt(result);
|
|
8624
|
+
}
|
|
8625
|
+
|
|
8467
8626
|
// src/commands.ts
|
|
8468
8627
|
function makeCommands(runtime) {
|
|
8469
8628
|
return [
|
|
@@ -8551,7 +8710,7 @@ async function statusReport(runtime, ctx) {
|
|
|
8551
8710
|
const bd = nudge?.contextBreakdown;
|
|
8552
8711
|
const limit = config.modelContextLimit;
|
|
8553
8712
|
const classified = bd ? bd.system + bd.tool + bd.summaries + bd.code + bd.text : 0;
|
|
8554
|
-
const systemPromptText = ctx
|
|
8713
|
+
const systemPromptText = getSystemPromptText(ctx);
|
|
8555
8714
|
const systemPromptTokens = systemPromptText ? defaultCountTokens(systemPromptText) : 0;
|
|
8556
8715
|
const framework = bd ? Math.max(0, tokenCount - classified - systemPromptTokens) : 0;
|
|
8557
8716
|
const displayTotal = tokenCount;
|
|
@@ -8559,7 +8718,7 @@ async function statusReport(runtime, ctx) {
|
|
|
8559
8718
|
const activeBlocksList = state.blocks.filter((b) => b.active);
|
|
8560
8719
|
const totalBlocksList = state.blocks;
|
|
8561
8720
|
const lines = [];
|
|
8562
|
-
const versionStr = "0.1.
|
|
8721
|
+
const versionStr = "0.1.30" ? `billion-context-pi@${"0.1.30"}` : "";
|
|
8563
8722
|
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");
|
|
8564
8723
|
lines.push("\u2502 ACP Context Analysis \u2502");
|
|
8565
8724
|
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");
|
|
@@ -8803,11 +8962,13 @@ function wireToolGuardrails(pi, runtime) {
|
|
|
8803
8962
|
if (next) {
|
|
8804
8963
|
modified = next;
|
|
8805
8964
|
debug.event("guardrail-output-cap", { max, hadPath: !!fullPath });
|
|
8965
|
+
logWarn("guardrail", { event: "output-cap", max, hadPath: !!fullPath });
|
|
8806
8966
|
}
|
|
8807
8967
|
}
|
|
8808
8968
|
if (timeoutSecs !== void 0) {
|
|
8809
8969
|
modified = appendTimeoutNotice(modified ?? event.content, timeoutSecs);
|
|
8810
8970
|
debug.event("guardrail-bash-timeout-notice", { secs: timeoutSecs });
|
|
8971
|
+
logInfo("guardrail", { event: "bash-timeout-notice", secs: timeoutSecs });
|
|
8811
8972
|
}
|
|
8812
8973
|
if (modified) return { content: modified };
|
|
8813
8974
|
});
|
|
@@ -8862,11 +9023,12 @@ async function readPackageJson(path4) {
|
|
|
8862
9023
|
}
|
|
8863
9024
|
function findNpmRoot(extDir) {
|
|
8864
9025
|
let dir = dirname3(extDir);
|
|
8865
|
-
|
|
9026
|
+
for (; ; ) {
|
|
8866
9027
|
if (dir.endsWith("node_modules")) return dirname3(dir);
|
|
8867
|
-
|
|
9028
|
+
const parent = dirname3(dir);
|
|
9029
|
+
if (parent === dir) return void 0;
|
|
9030
|
+
dir = parent;
|
|
8868
9031
|
}
|
|
8869
|
-
return void 0;
|
|
8870
9032
|
}
|
|
8871
9033
|
async function findExtensionDir() {
|
|
8872
9034
|
let dir = dirname3(fileURLToPath(import.meta.url));
|
|
@@ -8915,29 +9077,36 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
8915
9077
|
signal: AbortSignal.timeout(5e3),
|
|
8916
9078
|
headers: { Accept: "application/json" }
|
|
8917
9079
|
});
|
|
8918
|
-
if (!res.ok)
|
|
9080
|
+
if (!res.ok) {
|
|
9081
|
+
logWarn("update", { event: "check-http", status: res.status });
|
|
9082
|
+
return;
|
|
9083
|
+
}
|
|
8919
9084
|
const data = await res.json();
|
|
8920
9085
|
const latest = data.version;
|
|
8921
9086
|
if (!latest) return;
|
|
8922
|
-
const current = runtimeVersion ?? "0.1.
|
|
9087
|
+
const current = runtimeVersion ?? "0.1.30";
|
|
9088
|
+
const hasUpdate = isNewer(latest, current);
|
|
8923
9089
|
debug.event("update-check", {
|
|
8924
9090
|
current,
|
|
8925
9091
|
latest,
|
|
8926
|
-
hasUpdate
|
|
9092
|
+
hasUpdate
|
|
8927
9093
|
});
|
|
8928
|
-
|
|
9094
|
+
logInfo("update", { event: "check", current, latest, hasUpdate });
|
|
9095
|
+
if (hasUpdate) {
|
|
8929
9096
|
const installed = await autoInstallLatest(latest);
|
|
8930
9097
|
if (installed && notify) {
|
|
8931
9098
|
notify(
|
|
8932
9099
|
`\x1B[32m\u2714 ACP auto-updated ${current} \u2192 ${latest}. Restart Pi to finish.\x1B[0m`
|
|
8933
9100
|
);
|
|
9101
|
+
logInfo("update", { event: "auto-installed", from: current, to: latest });
|
|
8934
9102
|
} else if (!installed && notify) {
|
|
8935
9103
|
notify(
|
|
8936
9104
|
`${PACKAGE_NAME} ${latest} available (you have ${current}). Run: pi update --extension npm:${PACKAGE_NAME}`
|
|
8937
9105
|
);
|
|
8938
9106
|
}
|
|
8939
9107
|
}
|
|
8940
|
-
} catch {
|
|
9108
|
+
} catch (e) {
|
|
9109
|
+
logWarn("update", { event: "check-error", error: e instanceof Error ? e.message : String(e) });
|
|
8941
9110
|
} finally {
|
|
8942
9111
|
updateInFlight = false;
|
|
8943
9112
|
}
|
|
@@ -8951,7 +9120,7 @@ async function getRuntimeVersion() {
|
|
|
8951
9120
|
|
|
8952
9121
|
// src/setup-subagent-tools.ts
|
|
8953
9122
|
import { readFile as readFile2, writeFile as writeFile4, stat, copyFile, rename } from "fs/promises";
|
|
8954
|
-
import { existsSync } from "fs";
|
|
9123
|
+
import { existsSync as existsSync2 } from "fs";
|
|
8955
9124
|
import { homedir as homedir4 } from "os";
|
|
8956
9125
|
import { join as join6 } from "path";
|
|
8957
9126
|
var ACP_TOOLS2 = ["compress", "decompress", "search_context", "acp_status"];
|
|
@@ -9015,7 +9184,7 @@ async function ensureSubagentAcpTools(settingsPath) {
|
|
|
9015
9184
|
return { path: path4, action: "skipped", reason: "all builtin agents already have ACP tools" };
|
|
9016
9185
|
}
|
|
9017
9186
|
const backupPath = `${path4}.acp-bak`;
|
|
9018
|
-
if (!
|
|
9187
|
+
if (!existsSync2(backupPath)) {
|
|
9019
9188
|
try {
|
|
9020
9189
|
await copyFile(path4, backupPath);
|
|
9021
9190
|
} catch {
|
|
@@ -9067,15 +9236,19 @@ async function runSetupAndNotify(notify) {
|
|
|
9067
9236
|
if (result.action === "updated" && notify) {
|
|
9068
9237
|
notify(`ACP: enabled context tools (compress/decompress/search_context/acp_status) for subagents`);
|
|
9069
9238
|
}
|
|
9239
|
+
if (result.action === "failed") {
|
|
9240
|
+
logWarn("setup", { event: "subagent-tools", action: result.action, reason: result.reason });
|
|
9241
|
+
}
|
|
9070
9242
|
return result;
|
|
9071
9243
|
} catch (e) {
|
|
9072
9244
|
debug.event("setup-subagent-tools-error", { msg: String(e) });
|
|
9245
|
+
logError("setup", { event: "subagent-tools-error", error: e instanceof Error ? e.message : String(e), stack: e instanceof Error ? e.stack ?? "" : "" });
|
|
9073
9246
|
return { path: "", action: "failed", reason: String(e) };
|
|
9074
9247
|
}
|
|
9075
9248
|
}
|
|
9076
9249
|
|
|
9077
9250
|
// src/user-config.ts
|
|
9078
|
-
import { promises as
|
|
9251
|
+
import { promises as fs2 } from "fs";
|
|
9079
9252
|
import * as path3 from "path";
|
|
9080
9253
|
import { homedir as homedir5 } from "os";
|
|
9081
9254
|
import { CONFIG_DIR_NAME } from "@earendil-works/pi-coding-agent";
|
|
@@ -9085,13 +9258,17 @@ async function loadUserConfig(cwd) {
|
|
|
9085
9258
|
for (const base of [join8(home, CONFIG_DIR_NAME), join8(cwd, CONFIG_DIR_NAME)]) {
|
|
9086
9259
|
const file = join8(base, "acp.json");
|
|
9087
9260
|
try {
|
|
9088
|
-
const raw = await
|
|
9261
|
+
const raw = await fs2.readFile(file, "utf8");
|
|
9089
9262
|
const parsed = JSON.parse(raw);
|
|
9090
9263
|
if (parsed && typeof parsed === "object") {
|
|
9091
9264
|
Object.assign(merged, pickKnown(parsed));
|
|
9092
9265
|
debug.event("config-loaded", { file });
|
|
9093
9266
|
}
|
|
9094
|
-
} catch {
|
|
9267
|
+
} catch (e) {
|
|
9268
|
+
const code = e.code;
|
|
9269
|
+
if (code !== "ENOENT") {
|
|
9270
|
+
logWarn("config", { event: "load-failed", file, error: e instanceof Error ? e.message : String(e) });
|
|
9271
|
+
}
|
|
9095
9272
|
}
|
|
9096
9273
|
}
|
|
9097
9274
|
return merged;
|
|
@@ -9145,11 +9322,14 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
9145
9322
|
pi.on("session_start", async (_event, ctx) => {
|
|
9146
9323
|
runtime.store.invalidate();
|
|
9147
9324
|
runtime.clearNudgeTracking();
|
|
9325
|
+
const sid = ctx.sessionManager.getSessionId();
|
|
9326
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.30" : null });
|
|
9148
9327
|
try {
|
|
9149
9328
|
const user = await loadUserConfig(ctx.cwd);
|
|
9150
9329
|
runtime.setAdapter(applyUserConfig(runtime.adapter, user));
|
|
9151
9330
|
if (runtime.adapter.debug !== void 0) setDebugEnabled(runtime.adapter.debug);
|
|
9152
|
-
} catch {
|
|
9331
|
+
} catch (e) {
|
|
9332
|
+
logThrow("config", e, { sid, phase: "session_start" });
|
|
9153
9333
|
}
|
|
9154
9334
|
if (runtime.adapter.delegate !== false) {
|
|
9155
9335
|
pi.registerTool(makeDelegateTool(pi));
|
|
@@ -9164,6 +9344,7 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
9164
9344
|
});
|
|
9165
9345
|
pi.on("session_shutdown", () => {
|
|
9166
9346
|
delegateStatusWidget.dispose();
|
|
9347
|
+
closeLogStream();
|
|
9167
9348
|
});
|
|
9168
9349
|
}
|
|
9169
9350
|
function wireContextTransform(pi, runtime) {
|
|
@@ -9171,7 +9352,7 @@ function wireContextTransform(pi, runtime) {
|
|
|
9171
9352
|
const sid = ctx.sessionManager.getSessionId();
|
|
9172
9353
|
const release = await runtime.acquireLock(sid);
|
|
9173
9354
|
try {
|
|
9174
|
-
const { state, coreMessages, entries } = await runtime.stateFor(ctx);
|
|
9355
|
+
const { state, coreMessages, entries } = await runtime.stateFor(ctx, event.messages);
|
|
9175
9356
|
const config = runtime.configFor(ctx);
|
|
9176
9357
|
const coveredIds = collectCoveredMessageIds(state);
|
|
9177
9358
|
const realUsage = ctx.getContextUsage?.();
|
|
@@ -9192,6 +9373,18 @@ function wireContextTransform(pi, runtime) {
|
|
|
9192
9373
|
});
|
|
9193
9374
|
const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount });
|
|
9194
9375
|
await runtime.save(turn.state, ctx);
|
|
9376
|
+
logInfo("turn", {
|
|
9377
|
+
sid,
|
|
9378
|
+
inMsgs: coreMessages.length,
|
|
9379
|
+
outMsgs: turn.messages.length,
|
|
9380
|
+
tokens: tokenCount,
|
|
9381
|
+
pct: realUsage?.percent ?? (config.modelContextLimit > 0 ? Math.round(tokenCount / config.modelContextLimit * 100) : null),
|
|
9382
|
+
limit: config.modelContextLimit,
|
|
9383
|
+
nudge: turn.nudge?.shouldInject ? turn.nudge.breakdown?.emergencyOverride === 1 ? "emergency" : "active" : "idle",
|
|
9384
|
+
nudgeReason: turn.nudge?.reason ?? null,
|
|
9385
|
+
blocks: turn.state.blocks.length,
|
|
9386
|
+
activeBlocks: turn.state.blocks.filter((b) => b.active).length
|
|
9387
|
+
});
|
|
9195
9388
|
debug.event("processTurn", {
|
|
9196
9389
|
outMsgs: turn.messages.length,
|
|
9197
9390
|
summaryMsgs: turn.messages.filter((m) => m.id.startsWith("acp_summary")).length,
|
|
@@ -9221,6 +9414,9 @@ function wireContextTransform(pi, runtime) {
|
|
|
9221
9414
|
const example = top ? `
|
|
9222
9415
|
|
|
9223
9416
|
Example: compress({ content: [{ startId: "${top.startRef}", endId: "${top.endRef}", summary: "..." }] })` : "";
|
|
9417
|
+
if (emergency) {
|
|
9418
|
+
logWarn("nudge", { sid: ctx.sessionManager.getSessionId(), event: "emergency-inject", pct: Math.round(turn.nudge.contextUsage * 100), voice: rendered.voice, compressible: turn.nudge.compressibleRanges.length });
|
|
9419
|
+
}
|
|
9224
9420
|
if (debugOn2 && ctx.hasUI) {
|
|
9225
9421
|
ctx.ui.notify(`[ACP nudge \u2192 context]${emergency ? " [EMERGENCY]" : ""}
|
|
9226
9422
|
${rendered.text}${example}`);
|
|
@@ -9236,6 +9432,9 @@ ${rendered.text}${example}`);
|
|
|
9236
9432
|
if (ctx.hasUI) ctx.ui.notify(msg);
|
|
9237
9433
|
});
|
|
9238
9434
|
return { messages: rebuilt };
|
|
9435
|
+
} catch (e) {
|
|
9436
|
+
logThrow("context", e, { sid, phase: "transform" });
|
|
9437
|
+
throw e;
|
|
9239
9438
|
} finally {
|
|
9240
9439
|
release();
|
|
9241
9440
|
}
|
|
@@ -9246,15 +9445,13 @@ function wireSystemPrompt(pi, runtime) {
|
|
|
9246
9445
|
const delegate = runtime.adapter.delegate !== false;
|
|
9247
9446
|
const prompt = delegate ? `${ACP_SYSTEM_PROMPT}
|
|
9248
9447
|
${ACP_DELEGATE_PROMPT}` : ACP_SYSTEM_PROMPT;
|
|
9249
|
-
return { systemPrompt:
|
|
9250
|
-
|
|
9251
|
-
${prompt}` };
|
|
9448
|
+
return { systemPrompt: formatSystemPromptForEvent(event.systemPrompt, prompt) };
|
|
9252
9449
|
});
|
|
9253
9450
|
}
|
|
9254
9451
|
function collectOriginals(entries) {
|
|
9255
9452
|
const map = /* @__PURE__ */ new Map();
|
|
9256
9453
|
for (const entry of entries) {
|
|
9257
|
-
if (entry.type === "message") {
|
|
9454
|
+
if (entry.type === "message" && entry.message) {
|
|
9258
9455
|
map.set(entry.id, entry.message);
|
|
9259
9456
|
} else if (entry.type === "custom_message") {
|
|
9260
9457
|
const content = typeof entry.content === "string" ? [{ type: "text", text: entry.content }] : entry.content;
|