billion-context-pi 0.1.39 → 0.1.40
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 +5 -0
- package/dist/index.js +136 -109
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +4 -1
- package/package.json +1 -1
package/dist/delegate-tool.d.ts
CHANGED
|
@@ -81,6 +81,11 @@ export declare function makeEventApplier(opts: {
|
|
|
81
81
|
onUsage?: (usage: Usage) => void;
|
|
82
82
|
onSettled?: () => void;
|
|
83
83
|
}, writers: EventApplierWriters): EventApplier;
|
|
84
|
+
/** Resolve a wait timeout to ms. Agents frequently pass seconds (e.g. 180)
|
|
85
|
+
* instead of milliseconds; values below the 1s floor make no sense as a wait
|
|
86
|
+
* duration, so rescale them to seconds before clamping — otherwise 180 clamps
|
|
87
|
+
* to 1000ms and the wait times out in 1s. */
|
|
88
|
+
export declare function resolveWaitTimeoutMs(raw: number | undefined): number;
|
|
84
89
|
declare const DelegateParams: Type.TObject<{
|
|
85
90
|
agent: Type.TString;
|
|
86
91
|
task: Type.TString;
|
package/dist/index.js
CHANGED
|
@@ -3341,6 +3341,64 @@ function mergeInitialState(parsed) {
|
|
|
3341
3341
|
};
|
|
3342
3342
|
}
|
|
3343
3343
|
|
|
3344
|
+
// src/user-config.ts
|
|
3345
|
+
import { promises as fs2 } from "fs";
|
|
3346
|
+
import * as path3 from "path";
|
|
3347
|
+
import { homedir as homedir2 } from "os";
|
|
3348
|
+
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME2 } from "@earendil-works/pi-coding-agent";
|
|
3349
|
+
async function loadUserConfig(cwd) {
|
|
3350
|
+
const home = homedir2();
|
|
3351
|
+
const merged = {};
|
|
3352
|
+
for (const base of [join4(home, CONFIG_DIR_NAME2), join4(cwd, CONFIG_DIR_NAME2)]) {
|
|
3353
|
+
const file = join4(base, "acp.json");
|
|
3354
|
+
try {
|
|
3355
|
+
const raw = await fs2.readFile(file, "utf8");
|
|
3356
|
+
const parsed = JSON.parse(raw);
|
|
3357
|
+
if (parsed && typeof parsed === "object") {
|
|
3358
|
+
Object.assign(merged, pickKnown(parsed));
|
|
3359
|
+
debug.event("config-loaded", { file });
|
|
3360
|
+
}
|
|
3361
|
+
} catch (e) {
|
|
3362
|
+
const code = e.code;
|
|
3363
|
+
if (code !== "ENOENT") {
|
|
3364
|
+
logWarn("config", { event: "load-failed", file, error: e instanceof Error ? e.message : String(e) });
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
return merged;
|
|
3369
|
+
}
|
|
3370
|
+
function join4(...parts) {
|
|
3371
|
+
return path3.join(...parts);
|
|
3372
|
+
}
|
|
3373
|
+
var KNOWN = /* @__PURE__ */ new Set([
|
|
3374
|
+
"debug",
|
|
3375
|
+
"autoUpdate",
|
|
3376
|
+
"modelContextLimit",
|
|
3377
|
+
"toolBashDefaultTimeout",
|
|
3378
|
+
"toolOutputMaxBytes",
|
|
3379
|
+
"delegate",
|
|
3380
|
+
"compress",
|
|
3381
|
+
"displayUsage",
|
|
3382
|
+
"prompts",
|
|
3383
|
+
"acknowledgePromptsRisk"
|
|
3384
|
+
]);
|
|
3385
|
+
function pickKnown(parsed) {
|
|
3386
|
+
const out = {};
|
|
3387
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
3388
|
+
if (KNOWN.has(k)) out[k] = v;
|
|
3389
|
+
}
|
|
3390
|
+
return out;
|
|
3391
|
+
}
|
|
3392
|
+
function applyUserConfig(adapter, user) {
|
|
3393
|
+
return {
|
|
3394
|
+
...adapter,
|
|
3395
|
+
...user,
|
|
3396
|
+
coreOverrides: adapter.coreOverrides,
|
|
3397
|
+
protectedTools: adapter.protectedTools,
|
|
3398
|
+
preserveRecentMessages: adapter.preserveRecentMessages
|
|
3399
|
+
};
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3344
3402
|
// src/sequence-match.ts
|
|
3345
3403
|
function findUniqueLongestRun(candidates, live) {
|
|
3346
3404
|
if (candidates.length === 0 || live.length === 0) return void 0;
|
|
@@ -3565,7 +3623,9 @@ function createRuntime(adapter) {
|
|
|
3565
3623
|
const store = new SessionStateStore();
|
|
3566
3624
|
const lastActiveBlockIds = /* @__PURE__ */ new Map();
|
|
3567
3625
|
const locks = /* @__PURE__ */ new Map();
|
|
3626
|
+
const factoryAdapter = adapter;
|
|
3568
3627
|
let adapterRef = adapter;
|
|
3628
|
+
let lastUserConfigKey;
|
|
3569
3629
|
let promptsRef = defaultPrompts;
|
|
3570
3630
|
const nudgeShownTurns = /* @__PURE__ */ new Set();
|
|
3571
3631
|
async function acquireLock(sid) {
|
|
@@ -3591,6 +3651,25 @@ function createRuntime(adapter) {
|
|
|
3591
3651
|
const m = ctx.model;
|
|
3592
3652
|
return resolveConfig(adapterRef, liveContextLimit(ctx), m?.provider, m?.id);
|
|
3593
3653
|
}
|
|
3654
|
+
async function reloadConfig(cwd) {
|
|
3655
|
+
let user;
|
|
3656
|
+
try {
|
|
3657
|
+
user = await loadUserConfig(cwd);
|
|
3658
|
+
} catch (e) {
|
|
3659
|
+
logWarn("runtime", { event: "config-reload-failed", error: e instanceof Error ? e.message : String(e) });
|
|
3660
|
+
return;
|
|
3661
|
+
}
|
|
3662
|
+
try {
|
|
3663
|
+
const key = JSON.stringify(user);
|
|
3664
|
+
if (key === lastUserConfigKey) return;
|
|
3665
|
+
lastUserConfigKey = key;
|
|
3666
|
+
adapterRef = applyUserConfig(factoryAdapter, user);
|
|
3667
|
+
if (adapterRef.debug !== void 0) setDebugEnabled(adapterRef.debug);
|
|
3668
|
+
logInfo("runtime", { event: "config-reloaded", limit: adapterRef.modelContextLimit ?? null });
|
|
3669
|
+
} catch (e) {
|
|
3670
|
+
logWarn("runtime", { event: "config-reload-failed", error: e instanceof Error ? e.message : String(e) });
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3594
3673
|
async function stateFor(ctx, liveMessages) {
|
|
3595
3674
|
const sm = ctx.sessionManager;
|
|
3596
3675
|
const sessionFile = sm.getSessionFile() ?? void 0;
|
|
@@ -3626,8 +3705,6 @@ function createRuntime(adapter) {
|
|
|
3626
3705
|
countModelId = m;
|
|
3627
3706
|
}, noteActiveBlocks, clearSessionTracking, get adapter() {
|
|
3628
3707
|
return adapterRef;
|
|
3629
|
-
}, setAdapter: (a) => {
|
|
3630
|
-
adapterRef = a;
|
|
3631
3708
|
}, get prompts() {
|
|
3632
3709
|
return promptsRef;
|
|
3633
3710
|
}, setPrompts: (p) => {
|
|
@@ -3636,7 +3713,7 @@ function createRuntime(adapter) {
|
|
|
3636
3713
|
nudgeShownTurns.add(k);
|
|
3637
3714
|
}, nudgeShownFor: (k) => nudgeShownTurns.has(k), clearNudgeTracking: () => {
|
|
3638
3715
|
nudgeShownTurns.clear();
|
|
3639
|
-
}, liveContextLimit, configFor, stateFor, save, acquireLock };
|
|
3716
|
+
}, liveContextLimit, configFor, reloadConfig, stateFor, save, acquireLock };
|
|
3640
3717
|
}
|
|
3641
3718
|
|
|
3642
3719
|
// node_modules/typebox/build/system/memory/memory.mjs
|
|
@@ -8159,7 +8236,14 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
8159
8236
|
});
|
|
8160
8237
|
await runtime.save(applied.state, ctx);
|
|
8161
8238
|
const { blocksCreated, tokensCompressed, errors, warnings } = applied.result;
|
|
8162
|
-
const
|
|
8239
|
+
const afterTurn = runtime.core.processTurn({
|
|
8240
|
+
messages: coreMessages,
|
|
8241
|
+
state: applied.state,
|
|
8242
|
+
config,
|
|
8243
|
+
tokenCount: calibrateTokens(sentTokens, density)
|
|
8244
|
+
});
|
|
8245
|
+
const afterTokens = calibrateTokens(estimateTokens(afterTurn.messages, collectCoveredMessageIds(applied.state)), density);
|
|
8246
|
+
const reclaimed = Math.max(0, beforeTokens - afterTokens);
|
|
8163
8247
|
const newBlocks = applied.state.blocks.slice(-blocksCreated);
|
|
8164
8248
|
debug.event("compress-out", {
|
|
8165
8249
|
sid: ctx.sessionManager.getSessionId(),
|
|
@@ -8190,9 +8274,9 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
8190
8274
|
logError("compress", { sid: ctx.sessionManager.getSessionId(), event: "errors", count: errors.length, errors: errors.slice(0, 5) });
|
|
8191
8275
|
}
|
|
8192
8276
|
if (warnings.length > 0) {
|
|
8193
|
-
|
|
8277
|
+
logWarn("compress", { sid: ctx.sessionManager.getSessionId(), event: "warnings", count: warnings.length, warnings: warnings.slice(0, 5) });
|
|
8194
8278
|
}
|
|
8195
|
-
const lines = [`\u25A3 ACP | ${formatK2(beforeTokens)} \u2192 ${formatK2(afterTokens)} tokens (~${formatK2(
|
|
8279
|
+
const lines = [`\u25A3 ACP | ${formatK2(beforeTokens)} \u2192 ${formatK2(afterTokens)} tokens (~${formatK2(reclaimed)} reclaimed, ${blocksCreated} block${blocksCreated > 1 ? "s" : ""})`];
|
|
8196
8280
|
if (warnings.length > 0) lines.push("\u26A0\uFE0F " + warnings.join("; "));
|
|
8197
8281
|
if (errors.length > 0) lines.push("Errors: " + errors.join("; "));
|
|
8198
8282
|
return lines.join("\n");
|
|
@@ -8201,9 +8285,9 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
8201
8285
|
// src/decompress-tool.ts
|
|
8202
8286
|
import { writeFile, mkdir } from "fs/promises";
|
|
8203
8287
|
import { existsSync as existsSync2, lstatSync, readlinkSync, realpathSync } from "fs";
|
|
8204
|
-
import { resolve, relative, isAbsolute, join as
|
|
8205
|
-
import { tmpdir, homedir as
|
|
8206
|
-
var AUTO_DIR =
|
|
8288
|
+
import { resolve, relative, isAbsolute, join as join5, basename as basename2, dirname as dirname3 } from "path";
|
|
8289
|
+
import { tmpdir, homedir as homedir3 } from "os";
|
|
8290
|
+
var AUTO_DIR = join5(homedir3() || tmpdir(), ".cache", "pi", "acp-decompress");
|
|
8207
8291
|
var PREVIEW_CHARS = 600;
|
|
8208
8292
|
var MESSAGE_INLINE_THRESHOLD = 2e3;
|
|
8209
8293
|
var DecompressParams = typebox_exports.Object({
|
|
@@ -8239,11 +8323,11 @@ function makeDecompressTool(runtime) {
|
|
|
8239
8323
|
}
|
|
8240
8324
|
var ALLOWED_DIRS = [
|
|
8241
8325
|
tmpdir(),
|
|
8242
|
-
|
|
8243
|
-
|
|
8326
|
+
join5(homedir3(), ".cache", "opencode"),
|
|
8327
|
+
join5(homedir3(), ".cache", "pi")
|
|
8244
8328
|
];
|
|
8245
8329
|
function resolveToFilePath(targetPath) {
|
|
8246
|
-
const expanded = targetPath.startsWith("~/") ?
|
|
8330
|
+
const expanded = targetPath.startsWith("~/") ? join5(homedir3(), targetPath.slice(2)) : targetPath;
|
|
8247
8331
|
const resolved = resolve(expanded);
|
|
8248
8332
|
let probe = resolved;
|
|
8249
8333
|
const suffix = [];
|
|
@@ -8254,7 +8338,7 @@ function resolveToFilePath(targetPath) {
|
|
|
8254
8338
|
const real = existsSync2(probe) ? realpathSync(probe) : probe;
|
|
8255
8339
|
let checked = real;
|
|
8256
8340
|
for (const part of suffix) {
|
|
8257
|
-
checked =
|
|
8341
|
+
checked = join5(checked, part);
|
|
8258
8342
|
try {
|
|
8259
8343
|
if (lstatSync(checked).isSymbolicLink()) {
|
|
8260
8344
|
const target = readlinkSync(checked);
|
|
@@ -8280,7 +8364,7 @@ function resolveToFilePath(targetPath) {
|
|
|
8280
8364
|
return checked;
|
|
8281
8365
|
}
|
|
8282
8366
|
function autoFilePath(blockId) {
|
|
8283
|
-
return
|
|
8367
|
+
return join5(AUTO_DIR, `${blockId}-${Date.now()}.txt`);
|
|
8284
8368
|
}
|
|
8285
8369
|
function headPreview(text) {
|
|
8286
8370
|
if (text.length <= PREVIEW_CHARS) return text;
|
|
@@ -8627,7 +8711,7 @@ import {
|
|
|
8627
8711
|
import { createWriteStream, existsSync as existsSync3 } from "fs";
|
|
8628
8712
|
import { mkdir as mkdir2, mkdtemp, writeFile as writeFile2, rm, appendFile } from "fs/promises";
|
|
8629
8713
|
import { tmpdir as tmpdir2 } from "os";
|
|
8630
|
-
import { dirname as dirname4, join as
|
|
8714
|
+
import { dirname as dirname4, join as join6, resolve as resolvePath } from "path";
|
|
8631
8715
|
|
|
8632
8716
|
// src/footer-status.ts
|
|
8633
8717
|
var FOOTER_STATUS_KEY = "billion-context-pi";
|
|
@@ -9031,7 +9115,7 @@ var IDLE_GRACE_MS = 5 * 6e4;
|
|
|
9031
9115
|
var ASYNC_TIMEOUT_MS = 30 * 6e4;
|
|
9032
9116
|
var KILL_GRACE_MS = 1e4;
|
|
9033
9117
|
var RESULT_SUMMARY_CHARS = 500;
|
|
9034
|
-
var OUT_DIR =
|
|
9118
|
+
var OUT_DIR = join6(tmpdir2(), "acp-delegate");
|
|
9035
9119
|
function delegateSpawnOptions(cwd, env) {
|
|
9036
9120
|
return {
|
|
9037
9121
|
cwd,
|
|
@@ -9041,11 +9125,11 @@ function delegateSpawnOptions(cwd, env) {
|
|
|
9041
9125
|
};
|
|
9042
9126
|
}
|
|
9043
9127
|
var PI_CLI_ENTRY_RE = /[\\/]pi-coding-agent[\\/]dist[\\/]cli\.js$/;
|
|
9044
|
-
var PI_PACKAGE_REL =
|
|
9128
|
+
var PI_PACKAGE_REL = join6("@earendil-works", "pi-coding-agent", "dist", "cli.js");
|
|
9045
9129
|
function probeUpFromArgv(argv1) {
|
|
9046
9130
|
let dir = resolvePath(dirname4(argv1) || process.cwd());
|
|
9047
9131
|
for (; ; ) {
|
|
9048
|
-
const candidate =
|
|
9132
|
+
const candidate = join6(dir, "node_modules", PI_PACKAGE_REL);
|
|
9049
9133
|
if (existsSync3(candidate)) return candidate;
|
|
9050
9134
|
const parent = dirname4(dir);
|
|
9051
9135
|
if (parent === dir) return null;
|
|
@@ -9055,12 +9139,12 @@ function probeUpFromArgv(argv1) {
|
|
|
9055
9139
|
function piCliGlobalCandidates(env) {
|
|
9056
9140
|
const candidates = [];
|
|
9057
9141
|
if (process.platform === "win32") {
|
|
9058
|
-
if (env.APPDATA) candidates.push(
|
|
9142
|
+
if (env.APPDATA) candidates.push(join6(env.APPDATA, "npm", "node_modules", PI_PACKAGE_REL));
|
|
9059
9143
|
} else {
|
|
9060
9144
|
const home = env.HOME ?? env.USERPROFILE;
|
|
9061
|
-
if (home) candidates.push(
|
|
9062
|
-
candidates.push(
|
|
9063
|
-
candidates.push(
|
|
9145
|
+
if (home) candidates.push(join6(home, ".local", "lib", "node_modules", PI_PACKAGE_REL));
|
|
9146
|
+
candidates.push(join6("/usr/local", "lib", "node_modules", PI_PACKAGE_REL));
|
|
9147
|
+
candidates.push(join6("/usr", "lib", "node_modules", PI_PACKAGE_REL));
|
|
9064
9148
|
}
|
|
9065
9149
|
return candidates;
|
|
9066
9150
|
}
|
|
@@ -9212,6 +9296,11 @@ function makeEventApplier(opts, writers) {
|
|
|
9212
9296
|
}
|
|
9213
9297
|
var WAIT_TIMEOUT_MS_DEFAULT = 1e4;
|
|
9214
9298
|
var WAIT_TIMEOUT_MS_MAX = 3e5;
|
|
9299
|
+
function resolveWaitTimeoutMs(raw) {
|
|
9300
|
+
if (raw === void 0) return WAIT_TIMEOUT_MS_DEFAULT;
|
|
9301
|
+
const ms = raw < 1e3 ? raw * 1e3 : raw;
|
|
9302
|
+
return Math.min(Math.max(ms, 1e3), WAIT_TIMEOUT_MS_MAX);
|
|
9303
|
+
}
|
|
9215
9304
|
var DelegateParams = typebox_exports.Object({
|
|
9216
9305
|
agent: typebox_exports.String({
|
|
9217
9306
|
description: `Role of the delegate. One of: ${AGENT_NAMES.join(", ")}. See tool description for what each does.`
|
|
@@ -9243,7 +9332,7 @@ var WaitParams = typebox_exports.Object({
|
|
|
9243
9332
|
runId: typebox_exports.String({ description: "The runId returned by acp_delegate to wait for." }),
|
|
9244
9333
|
timeout: typebox_exports.Optional(
|
|
9245
9334
|
typebox_exports.Integer({
|
|
9246
|
-
description: `Maximum
|
|
9335
|
+
description: `Maximum time to block waiting for the result, in milliseconds. Default ${WAIT_TIMEOUT_MS_DEFAULT} (10s); max ${WAIT_TIMEOUT_MS_MAX} (300s). Values below 1000 are treated as seconds (so 180 means 180s, not 180ms). If the delegate does not finish in time, returns "failed (not ready)" \u2014 do NOT keep waiting or retry; go do other work, and a completion notification will still be injected when it completes.`
|
|
9247
9336
|
})
|
|
9248
9337
|
)
|
|
9249
9338
|
});
|
|
@@ -9402,10 +9491,7 @@ function makeDelegateWaitTool(_pi) {
|
|
|
9402
9491
|
}
|
|
9403
9492
|
return buildWaitResult(run, formatRunResult(run), displayMode);
|
|
9404
9493
|
}
|
|
9405
|
-
const timeoutMs =
|
|
9406
|
-
Math.max(args.timeout ?? WAIT_TIMEOUT_MS_DEFAULT, 1e3),
|
|
9407
|
-
WAIT_TIMEOUT_MS_MAX
|
|
9408
|
-
);
|
|
9494
|
+
const timeoutMs = resolveWaitTimeoutMs(args.timeout);
|
|
9409
9495
|
if (run.waiter) {
|
|
9410
9496
|
return { details: void 0, content: [{ type: "text", text: `Delegate \`${args.runId}\` already has a wait in progress; do not wait on it twice.` }] };
|
|
9411
9497
|
}
|
|
@@ -9526,8 +9612,8 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
9526
9612
|
},
|
|
9527
9613
|
{ eofGraceMs: EOF_GRACE_MS, idleMs: IDLE_GRACE_MS, timeoutMs: ASYNC_TIMEOUT_MS, killGraceMs: KILL_GRACE_MS }
|
|
9528
9614
|
);
|
|
9529
|
-
const replyFile =
|
|
9530
|
-
const activityFile =
|
|
9615
|
+
const replyFile = join6(OUT_DIR, `${runId}.out`);
|
|
9616
|
+
const activityFile = join6(OUT_DIR, `${runId}.activity`);
|
|
9531
9617
|
await mkdir2(OUT_DIR, { recursive: true });
|
|
9532
9618
|
const replyStream = createWriteStream(replyFile, { flags: "a" });
|
|
9533
9619
|
const activityStream = useJsonStream ? createWriteStream(activityFile, { flags: "a" }) : null;
|
|
@@ -9677,8 +9763,8 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
9677
9763
|
return formatSyncResult(args.agent, runId, args.task, result, file);
|
|
9678
9764
|
}
|
|
9679
9765
|
async function buildChildArgs(args, rolePrompt, ctx) {
|
|
9680
|
-
const tmpDir = await mkdtemp(
|
|
9681
|
-
const promptFile =
|
|
9766
|
+
const tmpDir = await mkdtemp(join6(tmpdir2(), "acp-delegate-"));
|
|
9767
|
+
const promptFile = join6(tmpDir, "role.md");
|
|
9682
9768
|
await writeFile2(promptFile, `${rolePrompt}
|
|
9683
9769
|
|
|
9684
9770
|
---
|
|
@@ -9815,7 +9901,7 @@ async function persistResult(runId, body) {
|
|
|
9815
9901
|
await mkdir2(OUT_DIR, { recursive: true });
|
|
9816
9902
|
} catch {
|
|
9817
9903
|
}
|
|
9818
|
-
const file =
|
|
9904
|
+
const file = join6(OUT_DIR, `${runId}.out`);
|
|
9819
9905
|
try {
|
|
9820
9906
|
await writeFile2(file, body, "utf8");
|
|
9821
9907
|
return file;
|
|
@@ -10002,7 +10088,7 @@ async function statusReport(runtime, ctx) {
|
|
|
10002
10088
|
const modelId = ctx.model?.id ?? "default";
|
|
10003
10089
|
const sentTokens = estimateTokens(coreMessages, coveredIds) + systemPromptTokens;
|
|
10004
10090
|
const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: calibrateTokens(sentTokens, runtime.density.densityFor(modelId)) });
|
|
10005
|
-
const versionStr = "0.1.
|
|
10091
|
+
const versionStr = "0.1.40" ? `billion-context-pi@${"0.1.40"}` : void 0;
|
|
10006
10092
|
let text = buildStatusPanel({
|
|
10007
10093
|
version: versionStr,
|
|
10008
10094
|
tokenCount: sessionTokens,
|
|
@@ -10215,16 +10301,16 @@ function wireToolGuardrails(pi, runtime) {
|
|
|
10215
10301
|
|
|
10216
10302
|
// src/update.ts
|
|
10217
10303
|
import { readFile, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
10218
|
-
import { join as
|
|
10304
|
+
import { join as join7, dirname as dirname5 } from "path";
|
|
10219
10305
|
import { fileURLToPath } from "url";
|
|
10220
10306
|
import { execFile } from "child_process";
|
|
10221
|
-
import { homedir as
|
|
10222
|
-
import { CONFIG_DIR_NAME as
|
|
10307
|
+
import { homedir as homedir4 } from "os";
|
|
10308
|
+
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME3 } from "@earendil-works/pi-coding-agent";
|
|
10223
10309
|
var PACKAGE_NAME = "billion-context-pi";
|
|
10224
10310
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
10225
10311
|
var SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/;
|
|
10226
10312
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
10227
|
-
var THROTTLE_FILE =
|
|
10313
|
+
var THROTTLE_FILE = join7(homedir4(), CONFIG_DIR_NAME3, "agent", ".billion-context-pi-update-check");
|
|
10228
10314
|
var updateInFlight = false;
|
|
10229
10315
|
function parseVersion(v) {
|
|
10230
10316
|
return v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -10273,7 +10359,7 @@ function findNpmRoot(extDir) {
|
|
|
10273
10359
|
async function findExtensionDir() {
|
|
10274
10360
|
let dir = dirname5(fileURLToPath(import.meta.url));
|
|
10275
10361
|
for (; ; ) {
|
|
10276
|
-
const pkg = await readPackageJson(
|
|
10362
|
+
const pkg = await readPackageJson(join7(dir, "package.json"));
|
|
10277
10363
|
if (pkg?.name === PACKAGE_NAME) return dir;
|
|
10278
10364
|
const parent = dirname5(dir);
|
|
10279
10365
|
if (parent === dir) return void 0;
|
|
@@ -10324,7 +10410,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
10324
10410
|
const data = await res.json();
|
|
10325
10411
|
const latest = data.version;
|
|
10326
10412
|
if (!latest) return;
|
|
10327
|
-
const current = runtimeVersion ?? "0.1.
|
|
10413
|
+
const current = runtimeVersion ?? "0.1.40";
|
|
10328
10414
|
const hasUpdate = isNewer(latest, current);
|
|
10329
10415
|
debug.event("update-check", {
|
|
10330
10416
|
current,
|
|
@@ -10354,16 +10440,16 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
10354
10440
|
async function getRuntimeVersion() {
|
|
10355
10441
|
const extDir = await findExtensionDir();
|
|
10356
10442
|
if (!extDir) return void 0;
|
|
10357
|
-
const pkg = await readPackageJson(
|
|
10443
|
+
const pkg = await readPackageJson(join7(extDir, "package.json"));
|
|
10358
10444
|
return pkg?.version;
|
|
10359
10445
|
}
|
|
10360
10446
|
|
|
10361
10447
|
// src/setup-subagent-tools.ts
|
|
10362
10448
|
import { readFile as readFile2, writeFile as writeFile4, stat, copyFile, rename } from "fs/promises";
|
|
10363
10449
|
import { existsSync as existsSync4 } from "fs";
|
|
10364
|
-
import { homedir as
|
|
10365
|
-
import { join as
|
|
10366
|
-
import { CONFIG_DIR_NAME as
|
|
10450
|
+
import { homedir as homedir5 } from "os";
|
|
10451
|
+
import { join as join8 } from "path";
|
|
10452
|
+
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME4 } from "@earendil-works/pi-coding-agent";
|
|
10367
10453
|
var ACP_TOOLS2 = ["compress", "decompress", "search_context", "acp_status"];
|
|
10368
10454
|
var BUILTIN_DEFAULT_TOOLS = {
|
|
10369
10455
|
advisor: ["read", "grep", "find", "ls", "bash", "intercom"],
|
|
@@ -10378,9 +10464,9 @@ var BUILTIN_DEFAULT_TOOLS = {
|
|
|
10378
10464
|
};
|
|
10379
10465
|
function resolveAgentDir() {
|
|
10380
10466
|
const configured = process.env.PI_CODING_AGENT_DIR;
|
|
10381
|
-
if (configured === "~") return
|
|
10382
|
-
if (configured?.startsWith("~/")) return
|
|
10383
|
-
return configured ||
|
|
10467
|
+
if (configured === "~") return homedir5();
|
|
10468
|
+
if (configured?.startsWith("~/")) return join8(homedir5(), configured.slice(2));
|
|
10469
|
+
return configured || join8(homedir5(), CONFIG_DIR_NAME4, "agent");
|
|
10384
10470
|
}
|
|
10385
10471
|
function desiredTools(existing, name) {
|
|
10386
10472
|
const base = Array.isArray(existing?.tools) && existing.tools.length > 0 ? [...existing.tools] : [...BUILTIN_DEFAULT_TOOLS[name] ?? []];
|
|
@@ -10390,7 +10476,7 @@ function desiredTools(existing, name) {
|
|
|
10390
10476
|
return { tools: base, changed: true };
|
|
10391
10477
|
}
|
|
10392
10478
|
async function ensureSubagentAcpTools(settingsPath) {
|
|
10393
|
-
const path4 = settingsPath ??
|
|
10479
|
+
const path4 = settingsPath ?? join8(resolveAgentDir(), "settings.json");
|
|
10394
10480
|
let raw;
|
|
10395
10481
|
let mtimeMs;
|
|
10396
10482
|
try {
|
|
@@ -10488,64 +10574,6 @@ async function runSetupAndNotify(notify) {
|
|
|
10488
10574
|
}
|
|
10489
10575
|
}
|
|
10490
10576
|
|
|
10491
|
-
// src/user-config.ts
|
|
10492
|
-
import { promises as fs2 } from "fs";
|
|
10493
|
-
import * as path3 from "path";
|
|
10494
|
-
import { homedir as homedir5 } from "os";
|
|
10495
|
-
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME4 } from "@earendil-works/pi-coding-agent";
|
|
10496
|
-
async function loadUserConfig(cwd) {
|
|
10497
|
-
const home = homedir5();
|
|
10498
|
-
const merged = {};
|
|
10499
|
-
for (const base of [join8(home, CONFIG_DIR_NAME4), join8(cwd, CONFIG_DIR_NAME4)]) {
|
|
10500
|
-
const file = join8(base, "acp.json");
|
|
10501
|
-
try {
|
|
10502
|
-
const raw = await fs2.readFile(file, "utf8");
|
|
10503
|
-
const parsed = JSON.parse(raw);
|
|
10504
|
-
if (parsed && typeof parsed === "object") {
|
|
10505
|
-
Object.assign(merged, pickKnown(parsed));
|
|
10506
|
-
debug.event("config-loaded", { file });
|
|
10507
|
-
}
|
|
10508
|
-
} catch (e) {
|
|
10509
|
-
const code = e.code;
|
|
10510
|
-
if (code !== "ENOENT") {
|
|
10511
|
-
logWarn("config", { event: "load-failed", file, error: e instanceof Error ? e.message : String(e) });
|
|
10512
|
-
}
|
|
10513
|
-
}
|
|
10514
|
-
}
|
|
10515
|
-
return merged;
|
|
10516
|
-
}
|
|
10517
|
-
function join8(...parts) {
|
|
10518
|
-
return path3.join(...parts);
|
|
10519
|
-
}
|
|
10520
|
-
var KNOWN = /* @__PURE__ */ new Set([
|
|
10521
|
-
"debug",
|
|
10522
|
-
"autoUpdate",
|
|
10523
|
-
"modelContextLimit",
|
|
10524
|
-
"toolBashDefaultTimeout",
|
|
10525
|
-
"toolOutputMaxBytes",
|
|
10526
|
-
"delegate",
|
|
10527
|
-
"compress",
|
|
10528
|
-
"displayUsage",
|
|
10529
|
-
"prompts",
|
|
10530
|
-
"acknowledgePromptsRisk"
|
|
10531
|
-
]);
|
|
10532
|
-
function pickKnown(parsed) {
|
|
10533
|
-
const out = {};
|
|
10534
|
-
for (const [k, v] of Object.entries(parsed)) {
|
|
10535
|
-
if (KNOWN.has(k)) out[k] = v;
|
|
10536
|
-
}
|
|
10537
|
-
return out;
|
|
10538
|
-
}
|
|
10539
|
-
function applyUserConfig(adapter, user) {
|
|
10540
|
-
return {
|
|
10541
|
-
...adapter,
|
|
10542
|
-
...user,
|
|
10543
|
-
coreOverrides: adapter.coreOverrides,
|
|
10544
|
-
protectedTools: adapter.protectedTools,
|
|
10545
|
-
preserveRecentMessages: adapter.preserveRecentMessages
|
|
10546
|
-
};
|
|
10547
|
-
}
|
|
10548
|
-
|
|
10549
10577
|
// src/index.ts
|
|
10550
10578
|
function createAcpExtension(adapter = {}) {
|
|
10551
10579
|
return (pi) => {
|
|
@@ -10579,12 +10607,10 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
10579
10607
|
const sid = ctx.sessionManager.getSessionId();
|
|
10580
10608
|
runtime.clearSessionTracking(sid);
|
|
10581
10609
|
const modelInfo = ctx.model;
|
|
10582
|
-
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.
|
|
10610
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.40" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
|
|
10583
10611
|
try {
|
|
10584
|
-
|
|
10585
|
-
runtime.setAdapter(applyUserConfig(runtime.adapter, user));
|
|
10612
|
+
await runtime.reloadConfig(ctx.cwd);
|
|
10586
10613
|
setDelegateDisplayUsage(resolveDelegate(runtime.adapter).displayUsage);
|
|
10587
|
-
if (runtime.adapter.debug !== void 0) setDebugEnabled(runtime.adapter.debug);
|
|
10588
10614
|
} catch (e) {
|
|
10589
10615
|
logThrow("config", e, { sid, phase: "session_start" });
|
|
10590
10616
|
}
|
|
@@ -10615,6 +10641,7 @@ function wireContextTransform(pi, runtime) {
|
|
|
10615
10641
|
const sid = ctx.sessionManager.getSessionId();
|
|
10616
10642
|
const release = await runtime.acquireLock(sid);
|
|
10617
10643
|
try {
|
|
10644
|
+
await runtime.reloadConfig(ctx.cwd);
|
|
10618
10645
|
const modelId = ctx.model?.id ?? "default";
|
|
10619
10646
|
runtime.setCountModel(modelId);
|
|
10620
10647
|
const { state, coreMessages, entries } = await runtime.stateFor(ctx, event.messages);
|