billion-context-pi 0.1.32 → 0.1.34
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/dist/delegate-tool.d.ts +30 -0
- package/dist/index.js +95 -61
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/delegate-tool.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { type SpawnOptions } from "node:child_process";
|
|
1
2
|
import { Type, type Static } from "typebox";
|
|
2
3
|
import type { ExtensionAPI, ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
export declare function delegateSpawnOptions(cwd: string, env: NodeJS.ProcessEnv): SpawnOptions;
|
|
3
5
|
/** Snapshot of currently-running delegate runs, for the TUI status widget. */
|
|
4
6
|
export declare function runningRunsSnapshot(): {
|
|
5
7
|
runId: string;
|
|
@@ -7,6 +9,34 @@ export declare function runningRunsSnapshot(): {
|
|
|
7
9
|
task: string;
|
|
8
10
|
startedAt: number;
|
|
9
11
|
}[];
|
|
12
|
+
/** Minimal writable surface accepted by makeEventApplier — real WriteStreams
|
|
13
|
+
* in production, in-memory collectors in tests. */
|
|
14
|
+
export interface EventApplierWriters {
|
|
15
|
+
reply: {
|
|
16
|
+
write(chunk: string): void;
|
|
17
|
+
};
|
|
18
|
+
activity: {
|
|
19
|
+
write(chunk: string): void;
|
|
20
|
+
} | null;
|
|
21
|
+
}
|
|
22
|
+
export interface EventApplier {
|
|
23
|
+
handleEventLine(line: string): void;
|
|
24
|
+
getReplyText(): string;
|
|
25
|
+
/** omp fallback: `-p` prints the plain reply as raw stdout; append it
|
|
26
|
+
* straight through (no event parsing). */
|
|
27
|
+
appendRaw(text: string): void;
|
|
28
|
+
}
|
|
29
|
+
/** Applies parsed delegate JSON-event lines to the live reply/activity files.
|
|
30
|
+
* Extracted from the spawn closure so the write logic is unit-testable.
|
|
31
|
+
*
|
|
32
|
+
* reply-delta (text_delta) is streamed to the reply file as it arrives;
|
|
33
|
+
* reply-complete (text_end) carries the authoritative full content of the
|
|
34
|
+
* text block — any portion not already written is appended (tracked via
|
|
35
|
+
* msgWritten) so a final answer that arrives without preceding deltas is
|
|
36
|
+
* never lost from the file. */
|
|
37
|
+
export declare function makeEventApplier(opts: {
|
|
38
|
+
showThinking: boolean;
|
|
39
|
+
}, writers: EventApplierWriters): EventApplier;
|
|
10
40
|
declare const DelegateParams: Type.TObject<{
|
|
11
41
|
agent: Type.TString;
|
|
12
42
|
task: Type.TString;
|
package/dist/index.js
CHANGED
|
@@ -269,7 +269,7 @@ function defaultConfig(modelContextLimit, overrides = {}) {
|
|
|
269
269
|
iterationThreshold: 15,
|
|
270
270
|
force: "soft",
|
|
271
271
|
growthRatio: 0.05,
|
|
272
|
-
growthFloor:
|
|
272
|
+
growthFloor: 5e4,
|
|
273
273
|
growthCap: 5e4,
|
|
274
274
|
minGrowthFloor: 2e4,
|
|
275
275
|
minGrowthRatio: 0.45,
|
|
@@ -2654,10 +2654,11 @@ import * as path2 from "path";
|
|
|
2654
2654
|
import { appendFileSync, mkdirSync, statSync, renameSync, existsSync } from "fs";
|
|
2655
2655
|
import * as path from "path";
|
|
2656
2656
|
import { homedir } from "os";
|
|
2657
|
+
import { CONFIG_DIR_NAME } from "@earendil-works/pi-coding-agent";
|
|
2657
2658
|
var MAX_BYTES = 10 * 1024 * 1024;
|
|
2658
2659
|
var ENV_DEBUG = process.env.ACP_DEBUG === "1" || process.env.ACP_DEBUG === "true";
|
|
2659
2660
|
function resolveLogFile() {
|
|
2660
|
-
return process.env.ACP_LOG_FILE ?? path.join(homedir(),
|
|
2661
|
+
return process.env.ACP_LOG_FILE ?? path.join(homedir(), CONFIG_DIR_NAME, "acp.log");
|
|
2661
2662
|
}
|
|
2662
2663
|
var runtimeDebug = null;
|
|
2663
2664
|
function setDebugEnabled(enabled) {
|
|
@@ -8064,6 +8065,14 @@ var ASYNC_TIMEOUT_MS = 30 * 6e4;
|
|
|
8064
8065
|
var KILL_GRACE_MS = 1e4;
|
|
8065
8066
|
var RESULT_SUMMARY_CHARS = 500;
|
|
8066
8067
|
var OUT_DIR = join4(tmpdir2(), "acp-delegate");
|
|
8068
|
+
function delegateSpawnOptions(cwd, env) {
|
|
8069
|
+
return {
|
|
8070
|
+
cwd,
|
|
8071
|
+
env,
|
|
8072
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
8073
|
+
shell: false
|
|
8074
|
+
};
|
|
8075
|
+
}
|
|
8067
8076
|
var ACP_TOOLS = ["compress", "decompress", "search_context", "acp_status"];
|
|
8068
8077
|
var RESTRICTED_TOOLS = "read,bash,grep,find,ls";
|
|
8069
8078
|
var AGENTS = {
|
|
@@ -8110,6 +8119,69 @@ function runningRunsSnapshot() {
|
|
|
8110
8119
|
}
|
|
8111
8120
|
return out;
|
|
8112
8121
|
}
|
|
8122
|
+
function makeEventApplier(opts, writers) {
|
|
8123
|
+
let replyText = "";
|
|
8124
|
+
let msgWritten = 0;
|
|
8125
|
+
const lastToolText = /* @__PURE__ */ new Map();
|
|
8126
|
+
const thinking = new ThinkingCollector(opts.showThinking);
|
|
8127
|
+
const flushThinking = () => {
|
|
8128
|
+
const line = thinking.flush();
|
|
8129
|
+
if (line) writers.activity?.write(line);
|
|
8130
|
+
};
|
|
8131
|
+
const handleEventLine = (line) => {
|
|
8132
|
+
const ev = parseEventLine(line);
|
|
8133
|
+
if (!ev) return;
|
|
8134
|
+
if (ev.kind === "thinking-delta") {
|
|
8135
|
+
thinking.push(ev.delta);
|
|
8136
|
+
return;
|
|
8137
|
+
}
|
|
8138
|
+
if (ev.kind === "thinking-end") {
|
|
8139
|
+
flushThinking();
|
|
8140
|
+
return;
|
|
8141
|
+
}
|
|
8142
|
+
if (ev.kind === "reply-delta") {
|
|
8143
|
+
flushThinking();
|
|
8144
|
+
replyText += ev.delta;
|
|
8145
|
+
msgWritten += ev.delta.length;
|
|
8146
|
+
writers.reply.write(ev.delta);
|
|
8147
|
+
return;
|
|
8148
|
+
}
|
|
8149
|
+
if (ev.kind === "reply-complete") {
|
|
8150
|
+
flushThinking();
|
|
8151
|
+
const tail = ev.content.slice(msgWritten);
|
|
8152
|
+
if (tail) {
|
|
8153
|
+
writers.reply.write(tail);
|
|
8154
|
+
debug.event("reply-complete-tail", { tailLen: tail.length, contentLen: ev.content.length });
|
|
8155
|
+
}
|
|
8156
|
+
if (ev.content.length < msgWritten) {
|
|
8157
|
+
logWarn("delegate", { event: "reply-content-shorter-than-delta", contentLen: ev.content.length, written: msgWritten });
|
|
8158
|
+
}
|
|
8159
|
+
msgWritten = 0;
|
|
8160
|
+
replyText = ev.content;
|
|
8161
|
+
return;
|
|
8162
|
+
}
|
|
8163
|
+
if (ev.kind === "tool-update") {
|
|
8164
|
+
flushThinking();
|
|
8165
|
+
const prev = lastToolText.get(ev.toolCallId) ?? "";
|
|
8166
|
+
const add = newPortion(ev.text, prev);
|
|
8167
|
+
lastToolText.set(ev.toolCallId, ev.text);
|
|
8168
|
+
if (add) writers.activity?.write(add.endsWith("\n") ? add : `${add}
|
|
8169
|
+
`);
|
|
8170
|
+
return;
|
|
8171
|
+
}
|
|
8172
|
+
flushThinking();
|
|
8173
|
+
const lines = activityLines(ev, { showThinking: opts.showThinking });
|
|
8174
|
+
if (lines.length) writers.activity?.write(lines.join(""));
|
|
8175
|
+
};
|
|
8176
|
+
return {
|
|
8177
|
+
handleEventLine,
|
|
8178
|
+
getReplyText: () => replyText,
|
|
8179
|
+
appendRaw(text) {
|
|
8180
|
+
replyText += text;
|
|
8181
|
+
writers.reply.write(text);
|
|
8182
|
+
}
|
|
8183
|
+
};
|
|
8184
|
+
}
|
|
8113
8185
|
var WAIT_TIMEOUT_MS_DEFAULT = 1e4;
|
|
8114
8186
|
var WAIT_TIMEOUT_MS_MAX = 3e5;
|
|
8115
8187
|
var DelegateParams = typebox_exports.Object({
|
|
@@ -8341,12 +8413,11 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8341
8413
|
const runId = `del_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
8342
8414
|
debug.event("delegate-spawn", { agent: args.agent, runId, cwd, async: isAsync, useJsonStream, cliArgs });
|
|
8343
8415
|
logInfo("delegate", { event: "spawn", agent: args.agent, runId, cwd, async: isAsync, useJsonStream, mode: ctx.mode, parentDepth });
|
|
8344
|
-
const child = spawn(
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
});
|
|
8416
|
+
const child = spawn(
|
|
8417
|
+
process.execPath,
|
|
8418
|
+
[process.argv[1], ...cliArgs],
|
|
8419
|
+
delegateSpawnOptions(cwd, childEnv)
|
|
8420
|
+
);
|
|
8350
8421
|
child.stdin?.once("error", (e) => {
|
|
8351
8422
|
debug.event("delegate-stdin-error", { runId: "pre-spawn", error: String(e) });
|
|
8352
8423
|
logError("delegate", { event: "stdin-error", runId, error: String(e) });
|
|
@@ -8380,49 +8451,11 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8380
8451
|
if (!s || s.destroyed || s.closed) return resolve2();
|
|
8381
8452
|
s.end(() => resolve2());
|
|
8382
8453
|
});
|
|
8383
|
-
let replyText = "";
|
|
8384
8454
|
let stdoutBuf = "";
|
|
8385
|
-
const
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
if (line) activityStream?.write(line);
|
|
8390
|
-
};
|
|
8391
|
-
const handleEventLine = (line) => {
|
|
8392
|
-
const ev = parseEventLine(line);
|
|
8393
|
-
if (!ev) return;
|
|
8394
|
-
if (ev.kind === "thinking-delta") {
|
|
8395
|
-
thinking.push(ev.delta);
|
|
8396
|
-
return;
|
|
8397
|
-
}
|
|
8398
|
-
if (ev.kind === "thinking-end") {
|
|
8399
|
-
flushThinking();
|
|
8400
|
-
return;
|
|
8401
|
-
}
|
|
8402
|
-
if (ev.kind === "reply-delta") {
|
|
8403
|
-
flushThinking();
|
|
8404
|
-
replyText += ev.delta;
|
|
8405
|
-
replyStream.write(ev.delta);
|
|
8406
|
-
return;
|
|
8407
|
-
}
|
|
8408
|
-
if (ev.kind === "reply-complete") {
|
|
8409
|
-
flushThinking();
|
|
8410
|
-
replyText = ev.content;
|
|
8411
|
-
return;
|
|
8412
|
-
}
|
|
8413
|
-
if (ev.kind === "tool-update") {
|
|
8414
|
-
flushThinking();
|
|
8415
|
-
const prev = lastToolText.get(ev.toolCallId) ?? "";
|
|
8416
|
-
const add = newPortion(ev.text, prev);
|
|
8417
|
-
lastToolText.set(ev.toolCallId, ev.text);
|
|
8418
|
-
if (add) activityStream?.write(add.endsWith("\n") ? add : `${add}
|
|
8419
|
-
`);
|
|
8420
|
-
return;
|
|
8421
|
-
}
|
|
8422
|
-
flushThinking();
|
|
8423
|
-
const lines = activityLines(ev, { showThinking: args.showThinking === true });
|
|
8424
|
-
if (lines.length) activityStream?.write(lines.join(""));
|
|
8425
|
-
};
|
|
8455
|
+
const applier = makeEventApplier(
|
|
8456
|
+
{ showThinking: args.showThinking === true },
|
|
8457
|
+
{ reply: replyStream, activity: activityStream }
|
|
8458
|
+
);
|
|
8426
8459
|
child.stdout?.on("data", (c) => {
|
|
8427
8460
|
watchdog.poke();
|
|
8428
8461
|
if (useJsonStream) {
|
|
@@ -8431,12 +8464,11 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8431
8464
|
while ((nl = stdoutBuf.indexOf("\n")) >= 0) {
|
|
8432
8465
|
const line = stdoutBuf.slice(0, nl);
|
|
8433
8466
|
stdoutBuf = stdoutBuf.slice(nl + 1);
|
|
8434
|
-
handleEventLine(line);
|
|
8467
|
+
applier.handleEventLine(line);
|
|
8435
8468
|
}
|
|
8436
8469
|
} else {
|
|
8437
8470
|
const text = c.toString("utf8");
|
|
8438
|
-
|
|
8439
|
-
replyStream.write(text);
|
|
8471
|
+
applier.appendRaw(text);
|
|
8440
8472
|
}
|
|
8441
8473
|
});
|
|
8442
8474
|
child.stderr?.on("data", (c) => {
|
|
@@ -8461,7 +8493,7 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
8461
8493
|
void cleanupTmp(tmpDir);
|
|
8462
8494
|
await Promise.all([endStream(replyStream), endStream(activityStream)]);
|
|
8463
8495
|
run.exitCode = code;
|
|
8464
|
-
const output =
|
|
8496
|
+
const output = applier.getReplyText().trim();
|
|
8465
8497
|
const body2 = code === 0 ? output || "(no output)" : stderrText.trim() || output || "(no output)";
|
|
8466
8498
|
if (run.status === "cancelled") {
|
|
8467
8499
|
await Promise.all([rm(replyFile, { force: true }), rm(activityFile, { force: true })]);
|
|
@@ -8790,7 +8822,7 @@ async function statusReport(runtime, ctx) {
|
|
|
8790
8822
|
const activeBlocksList = state.blocks.filter((b) => b.active);
|
|
8791
8823
|
const totalBlocksList = state.blocks;
|
|
8792
8824
|
const lines = [];
|
|
8793
|
-
const versionStr = "0.1.
|
|
8825
|
+
const versionStr = "0.1.34" ? `billion-context-pi@${"0.1.34"}` : "";
|
|
8794
8826
|
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");
|
|
8795
8827
|
lines.push("\u2502 ACP Context Analysis \u2502");
|
|
8796
8828
|
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");
|
|
@@ -9052,11 +9084,12 @@ import { join as join5, dirname as dirname3 } from "path";
|
|
|
9052
9084
|
import { fileURLToPath } from "url";
|
|
9053
9085
|
import { execFile } from "child_process";
|
|
9054
9086
|
import { homedir as homedir3 } from "os";
|
|
9087
|
+
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME2 } from "@earendil-works/pi-coding-agent";
|
|
9055
9088
|
var PACKAGE_NAME = "billion-context-pi";
|
|
9056
9089
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
9057
9090
|
var SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/;
|
|
9058
9091
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
9059
|
-
var THROTTLE_FILE = join5(homedir3(),
|
|
9092
|
+
var THROTTLE_FILE = join5(homedir3(), CONFIG_DIR_NAME2, "agent", ".billion-context-pi-update-check");
|
|
9060
9093
|
var updateInFlight = false;
|
|
9061
9094
|
function parseVersion(v) {
|
|
9062
9095
|
return v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -9156,7 +9189,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
9156
9189
|
const data = await res.json();
|
|
9157
9190
|
const latest = data.version;
|
|
9158
9191
|
if (!latest) return;
|
|
9159
|
-
const current = runtimeVersion ?? "0.1.
|
|
9192
|
+
const current = runtimeVersion ?? "0.1.34";
|
|
9160
9193
|
const hasUpdate = isNewer(latest, current);
|
|
9161
9194
|
debug.event("update-check", {
|
|
9162
9195
|
current,
|
|
@@ -9195,6 +9228,7 @@ import { readFile as readFile2, writeFile as writeFile4, stat, copyFile, rename
|
|
|
9195
9228
|
import { existsSync as existsSync2 } from "fs";
|
|
9196
9229
|
import { homedir as homedir4 } from "os";
|
|
9197
9230
|
import { join as join6 } from "path";
|
|
9231
|
+
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME3 } from "@earendil-works/pi-coding-agent";
|
|
9198
9232
|
var ACP_TOOLS2 = ["compress", "decompress", "search_context", "acp_status"];
|
|
9199
9233
|
var BUILTIN_DEFAULT_TOOLS = {
|
|
9200
9234
|
advisor: ["read", "grep", "find", "ls", "bash", "intercom"],
|
|
@@ -9211,7 +9245,7 @@ function resolveAgentDir() {
|
|
|
9211
9245
|
const configured = process.env.PI_CODING_AGENT_DIR;
|
|
9212
9246
|
if (configured === "~") return homedir4();
|
|
9213
9247
|
if (configured?.startsWith("~/")) return join6(homedir4(), configured.slice(2));
|
|
9214
|
-
return configured || join6(homedir4(),
|
|
9248
|
+
return configured || join6(homedir4(), CONFIG_DIR_NAME3, "agent");
|
|
9215
9249
|
}
|
|
9216
9250
|
function desiredTools(existing, name) {
|
|
9217
9251
|
const base = Array.isArray(existing?.tools) && existing.tools.length > 0 ? [...existing.tools] : [...BUILTIN_DEFAULT_TOOLS[name] ?? []];
|
|
@@ -9323,11 +9357,11 @@ async function runSetupAndNotify(notify) {
|
|
|
9323
9357
|
import { promises as fs2 } from "fs";
|
|
9324
9358
|
import * as path3 from "path";
|
|
9325
9359
|
import { homedir as homedir5 } from "os";
|
|
9326
|
-
import { CONFIG_DIR_NAME } from "@earendil-works/pi-coding-agent";
|
|
9360
|
+
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME4 } from "@earendil-works/pi-coding-agent";
|
|
9327
9361
|
async function loadUserConfig(cwd) {
|
|
9328
9362
|
const home = homedir5();
|
|
9329
9363
|
const merged = {};
|
|
9330
|
-
for (const base of [join8(home,
|
|
9364
|
+
for (const base of [join8(home, CONFIG_DIR_NAME4), join8(cwd, CONFIG_DIR_NAME4)]) {
|
|
9331
9365
|
const file = join8(base, "acp.json");
|
|
9332
9366
|
try {
|
|
9333
9367
|
const raw = await fs2.readFile(file, "utf8");
|
|
@@ -9395,7 +9429,7 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
9395
9429
|
runtime.store.invalidate();
|
|
9396
9430
|
runtime.clearNudgeTracking();
|
|
9397
9431
|
const sid = ctx.sessionManager.getSessionId();
|
|
9398
|
-
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.
|
|
9432
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.34" : null });
|
|
9399
9433
|
try {
|
|
9400
9434
|
const user = await loadUserConfig(ctx.cwd);
|
|
9401
9435
|
runtime.setAdapter(applyUserConfig(runtime.adapter, user));
|