billion-context-pi 0.1.56-pr.287.77 → 0.1.56
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/config.d.ts +5 -34
- package/dist/delegate-tool.d.ts +0 -10
- package/dist/delegate-watchdog.d.ts +2 -4
- package/dist/index.js +115 -185
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -12,37 +12,7 @@ export interface DelegateConfig {
|
|
|
12
12
|
* "merged" — delegate token usage folded into the tool-result usage field,
|
|
13
13
|
* counted as part of the main session totals. */
|
|
14
14
|
displayUsage?: "merged" | "separate";
|
|
15
|
-
/** Maximum acp_delegate nesting depth. Default: 2 (main → child → grandchild;
|
|
16
|
-
* the grandchild cannot delegate further). Set 1 to forbid nested delegation
|
|
17
|
-
* (orchestrator → leaf workers only). The resolved value is propagated to
|
|
18
|
-
* child processes via PI_ACP_DELEGATE_MAX_DEPTH so the cap follows the whole
|
|
19
|
-
* delegation tree, even when a child loads a different project acp.json. */
|
|
20
|
-
maxDepth?: number;
|
|
21
|
-
/** Hard timeout for synchronous delegates (async=false, or async auto-downgraded
|
|
22
|
-
* on one-shot hosts), in minutes. Default: 5. 0 or null disables the timeout
|
|
23
|
-
* (the run blocks until the child exits or the tool call is cancelled). */
|
|
24
|
-
syncTimeoutMinutes?: number | null;
|
|
25
|
-
/** Idle watchdog for async delegates: kill when no output arrives for this many
|
|
26
|
-
* minutes. Default: 5. This is the main defense against a stuck child holding
|
|
27
|
-
* its stdout fd open, so disabling it (0/null) logs a warning — use
|
|
28
|
-
* acp_delegate_cancel as the manual escape hatch. */
|
|
29
|
-
idleTimeoutMinutes?: number | null;
|
|
30
|
-
/** Hard time limit for async delegates, in minutes. Default: 30. 0 or null
|
|
31
|
-
* disables the limit. */
|
|
32
|
-
asyncTimeoutMinutes?: number | null;
|
|
33
15
|
}
|
|
34
|
-
/** Resolved delegate policy: what actually takes effect after merging acp.json,
|
|
35
|
-
* env overrides and defaults. Timeout fields are milliseconds; null means the
|
|
36
|
-
* corresponding timeout/watchdog is disabled. */
|
|
37
|
-
export interface DelegatePolicy {
|
|
38
|
-
enabled: boolean;
|
|
39
|
-
displayUsage: "merged" | "separate";
|
|
40
|
-
maxDepth: number;
|
|
41
|
-
syncTimeoutMs: number | null;
|
|
42
|
-
idleMs: number | null;
|
|
43
|
-
asyncTimeoutMs: number | null;
|
|
44
|
-
}
|
|
45
|
-
export declare const DEFAULT_DELEGATE_POLICY: DelegatePolicy;
|
|
46
16
|
/** Compression tuning fields, shared by all three levels (global, provider,
|
|
47
17
|
* model). Percentage fields accept a ratio (0.75) or percent string ("75%").
|
|
48
18
|
* Resolution is per-field, deepest-wins (model > provider > global); an
|
|
@@ -147,10 +117,11 @@ export interface AdapterConfig {
|
|
|
147
117
|
export declare const DEFAULT_TOOL_BASH_TIMEOUT = 60;
|
|
148
118
|
export declare const DEFAULT_TOOL_OUTPUT_MAX_BYTES = 200000;
|
|
149
119
|
/** Resolve delegate config from the adapter, handling the boolean shorthand
|
|
150
|
-
* and the legacy flat `displayUsage` alias.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
120
|
+
* and the legacy flat `displayUsage` alias. */
|
|
121
|
+
export declare function resolveDelegate(adapter: AdapterConfig): {
|
|
122
|
+
enabled: boolean;
|
|
123
|
+
displayUsage: "merged" | "separate";
|
|
124
|
+
};
|
|
154
125
|
/** Per-field deepest-wins merge of the three compression levels (global →
|
|
155
126
|
* provider → model). An undefined field at a deeper level does NOT clear a
|
|
156
127
|
* value set at a shallower level — only a defined value overrides. */
|
package/dist/delegate-tool.d.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { type ChildProcess, type SpawnOptions } from "node:child_process";
|
|
2
2
|
import { Type, type Static } from "typebox";
|
|
3
3
|
import type { AgentToolResult, ExtensionAPI, ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
import { type DelegatePolicy } from "./config.js";
|
|
5
4
|
import { type Usage } from "./delegate-events.js";
|
|
6
5
|
export declare function delegateStdinText(resumeFrom: boolean, task: string | undefined): string;
|
|
7
6
|
export declare function delegateSpawnOptions(cwd: string, env: NodeJS.ProcessEnv): SpawnOptions;
|
|
8
|
-
/** Child process env for a nested delegate: depth increments by one, and the
|
|
9
|
-
* resolved maxDepth rides along so the cap binds the whole delegation tree
|
|
10
|
-
* even when the child loads a different project acp.json. */
|
|
11
|
-
export declare function delegateChildEnv(parentDepth: number, maxDepth: number): NodeJS.ProcessEnv;
|
|
12
7
|
/** Resolve the pi CLI entry for delegate child processes.
|
|
13
8
|
* argv[1] is only the pi CLI under a CLI host; embedded hosts (e.g. pi-web)
|
|
14
9
|
* run the SDK inside another node process, so probe instead. Non-pi hosts
|
|
@@ -59,7 +54,6 @@ export declare function addDelegateUsage(u: Usage): void;
|
|
|
59
54
|
export declare function getDelegateUsage(): Usage | undefined;
|
|
60
55
|
export declare function resetDelegateUsage(): void;
|
|
61
56
|
export declare function setDelegateDisplayUsage(mode: "merged" | "separate"): void;
|
|
62
|
-
export declare function setDelegatePolicy(policy: DelegatePolicy): void;
|
|
63
57
|
/** Snapshot of currently-running delegate runs, for the TUI status widget. */
|
|
64
58
|
export declare function runningRunsSnapshot(): {
|
|
65
59
|
runId: string;
|
|
@@ -202,10 +196,6 @@ export declare function buildChildArgs(args: DelegateArgs, rolePrompt: string, c
|
|
|
202
196
|
useJsonStream: boolean;
|
|
203
197
|
sessionFile: string | null;
|
|
204
198
|
}>;
|
|
205
|
-
/** Model-facing summary of the ACTIVE async watchdog limits — built from the
|
|
206
|
-
* resolved policy so it stays truthful when timeouts are customized or
|
|
207
|
-
* disabled via acp.json/env. */
|
|
208
|
-
export declare function asyncWatchdogDescription(): string;
|
|
209
199
|
/** Watchdog/EOF finalize arrives with code === null (the child was killed or
|
|
210
200
|
* never exited). If a result was delivered (non-empty reply or stderr), the
|
|
211
201
|
* run counts as completed (0); otherwise it stays null = genuine failure. */
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { Readable } from "node:stream";
|
|
2
2
|
export interface WatchdogOptions {
|
|
3
3
|
eofGraceMs: number;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/** Hard time limit. 0/null disables the limit timer. */
|
|
7
|
-
timeoutMs?: number | null;
|
|
4
|
+
idleMs: number;
|
|
5
|
+
timeoutMs: number;
|
|
8
6
|
killGraceMs: number;
|
|
9
7
|
}
|
|
10
8
|
export interface WatchdogHooks {
|
package/dist/index.js
CHANGED
|
@@ -3552,144 +3552,21 @@ function makePreview(text, query, len) {
|
|
|
3552
3552
|
return prefix + text.slice(start, end).trim() + suffix;
|
|
3553
3553
|
}
|
|
3554
3554
|
|
|
3555
|
-
// src/log.ts
|
|
3556
|
-
import { appendFileSync, mkdirSync, statSync, renameSync, existsSync } from "fs";
|
|
3557
|
-
import * as path from "path";
|
|
3558
|
-
import { homedir } from "os";
|
|
3559
|
-
import { CONFIG_DIR_NAME } from "@earendil-works/pi-coding-agent";
|
|
3560
|
-
var MAX_BYTES = 10 * 1024 * 1024;
|
|
3561
|
-
var ENV_DEBUG = process.env.ACP_DEBUG === "1" || process.env.ACP_DEBUG === "true";
|
|
3562
|
-
function resolveLogFile() {
|
|
3563
|
-
return process.env.ACP_LOG_FILE ?? path.join(homedir(), CONFIG_DIR_NAME, "acp.log");
|
|
3564
|
-
}
|
|
3565
|
-
var runtimeDebug = null;
|
|
3566
|
-
function setDebugEnabled(enabled) {
|
|
3567
|
-
runtimeDebug = enabled;
|
|
3568
|
-
}
|
|
3569
|
-
function debugOn() {
|
|
3570
|
-
return runtimeDebug ?? ENV_DEBUG;
|
|
3571
|
-
}
|
|
3572
|
-
function fmt(v) {
|
|
3573
|
-
if (typeof v === "string") return v;
|
|
3574
|
-
if (v instanceof Error) return v.stack || String(v);
|
|
3575
|
-
try {
|
|
3576
|
-
return JSON.stringify(v);
|
|
3577
|
-
} catch {
|
|
3578
|
-
return String(v);
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
function ts() {
|
|
3582
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3583
|
-
}
|
|
3584
|
-
function writeLine(level, scope, fields) {
|
|
3585
|
-
const file = resolveLogFile();
|
|
3586
|
-
try {
|
|
3587
|
-
if (existsSync(file) && statSync(file).size >= MAX_BYTES) {
|
|
3588
|
-
renameSync(file, file + ".old");
|
|
3589
|
-
}
|
|
3590
|
-
} catch {
|
|
3591
|
-
}
|
|
3592
|
-
const body = Object.keys(fields).map((k) => `${k}=${fmt(fields[k])}`).join(" ");
|
|
3593
|
-
const line = `${ts()} [${level}] [${scope}] ${body}
|
|
3594
|
-
`;
|
|
3595
|
-
try {
|
|
3596
|
-
mkdirSync(path.dirname(file), { recursive: true });
|
|
3597
|
-
appendFileSync(file, line);
|
|
3598
|
-
} catch {
|
|
3599
|
-
}
|
|
3600
|
-
}
|
|
3601
|
-
function closeLogStream() {
|
|
3602
|
-
}
|
|
3603
|
-
function logError(scope, fields) {
|
|
3604
|
-
writeLine("error", scope, fields);
|
|
3605
|
-
}
|
|
3606
|
-
function logWarn(scope, fields) {
|
|
3607
|
-
writeLine("warn", scope, fields);
|
|
3608
|
-
}
|
|
3609
|
-
function logInfo(scope, fields) {
|
|
3610
|
-
writeLine("info", scope, fields);
|
|
3611
|
-
}
|
|
3612
|
-
function logThrow(scope, err, extra = {}) {
|
|
3613
|
-
const fields = { ...extra };
|
|
3614
|
-
if (err instanceof Error) {
|
|
3615
|
-
fields.error = err.message;
|
|
3616
|
-
fields.stack = err.stack ?? "";
|
|
3617
|
-
} else {
|
|
3618
|
-
fields.error = String(err);
|
|
3619
|
-
}
|
|
3620
|
-
writeLine("error", scope, fields);
|
|
3621
|
-
}
|
|
3622
|
-
var debug = {
|
|
3623
|
-
get enabled() {
|
|
3624
|
-
return debugOn();
|
|
3625
|
-
},
|
|
3626
|
-
get logFile() {
|
|
3627
|
-
return resolveLogFile();
|
|
3628
|
-
},
|
|
3629
|
-
event(scope, fields) {
|
|
3630
|
-
if (debugOn()) writeLine("debug", scope, fields);
|
|
3631
|
-
}
|
|
3632
|
-
};
|
|
3633
|
-
|
|
3634
3555
|
// src/config.ts
|
|
3635
|
-
var DEFAULT_DELEGATE_POLICY = {
|
|
3636
|
-
enabled: true,
|
|
3637
|
-
displayUsage: "separate",
|
|
3638
|
-
maxDepth: 2,
|
|
3639
|
-
syncTimeoutMs: 5 * 6e4,
|
|
3640
|
-
idleMs: 5 * 6e4,
|
|
3641
|
-
asyncTimeoutMs: 30 * 6e4
|
|
3642
|
-
};
|
|
3643
3556
|
var DEFAULT_TOOL_BASH_TIMEOUT = 60;
|
|
3644
3557
|
var DEFAULT_TOOL_OUTPUT_MAX_BYTES = 2e5;
|
|
3645
3558
|
function resolveDelegate(adapter) {
|
|
3646
3559
|
const d = adapter.delegate;
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
process.env.PI_ACP_DELEGATE_SYNC_TIMEOUT_MINUTES ?? cfg.syncTimeoutMinutes,
|
|
3653
|
-
"syncTimeoutMinutes",
|
|
3654
|
-
DEFAULT_DELEGATE_POLICY.syncTimeoutMs
|
|
3655
|
-
);
|
|
3656
|
-
const idleMs = resolveTimeoutMinutes(
|
|
3657
|
-
process.env.PI_ACP_DELEGATE_IDLE_TIMEOUT_MINUTES ?? cfg.idleTimeoutMinutes,
|
|
3658
|
-
"idleTimeoutMinutes",
|
|
3659
|
-
DEFAULT_DELEGATE_POLICY.idleMs
|
|
3660
|
-
);
|
|
3661
|
-
const asyncTimeoutMs = resolveTimeoutMinutes(
|
|
3662
|
-
process.env.PI_ACP_DELEGATE_ASYNC_TIMEOUT_MINUTES ?? cfg.asyncTimeoutMinutes,
|
|
3663
|
-
"asyncTimeoutMinutes",
|
|
3664
|
-
DEFAULT_DELEGATE_POLICY.asyncTimeoutMs
|
|
3665
|
-
);
|
|
3666
|
-
if (idleMs === null) {
|
|
3667
|
-
logWarn("config", {
|
|
3668
|
-
event: "delegate-idle-watchdog-disabled",
|
|
3669
|
-
hint: "no-output watchdog is off; hung async runs must be cancelled manually via acp_delegate_cancel"
|
|
3670
|
-
});
|
|
3671
|
-
}
|
|
3672
|
-
return { enabled, displayUsage, maxDepth, syncTimeoutMs, idleMs, asyncTimeoutMs };
|
|
3673
|
-
}
|
|
3674
|
-
function resolveMaxDepth(value) {
|
|
3675
|
-
if (value === void 0) return DEFAULT_DELEGATE_POLICY.maxDepth;
|
|
3676
|
-
const n = Number(value);
|
|
3677
|
-
if (!Number.isInteger(n) || n < 1) {
|
|
3678
|
-
logWarn("config", { event: "delegate-config-invalid", field: "maxDepth", value, fallback: DEFAULT_DELEGATE_POLICY.maxDepth });
|
|
3679
|
-
return DEFAULT_DELEGATE_POLICY.maxDepth;
|
|
3680
|
-
}
|
|
3681
|
-
return n;
|
|
3682
|
-
}
|
|
3683
|
-
function resolveTimeoutMinutes(value, field, defaultMs) {
|
|
3684
|
-
if (value === void 0) return defaultMs;
|
|
3685
|
-
if (value === null) return null;
|
|
3686
|
-
const n = Number(value);
|
|
3687
|
-
if (n === 0) return null;
|
|
3688
|
-
if (!Number.isFinite(n) || n < 0) {
|
|
3689
|
-
logWarn("config", { event: "delegate-config-invalid", field, value, fallback: `${defaultMs / 6e4}m` });
|
|
3690
|
-
return defaultMs;
|
|
3560
|
+
if (typeof d === "object" && d !== null) {
|
|
3561
|
+
return {
|
|
3562
|
+
enabled: d.enabled !== false,
|
|
3563
|
+
displayUsage: d.displayUsage ?? adapter.displayUsage ?? "separate"
|
|
3564
|
+
};
|
|
3691
3565
|
}
|
|
3692
|
-
return
|
|
3566
|
+
return {
|
|
3567
|
+
enabled: d !== false,
|
|
3568
|
+
displayUsage: adapter.displayUsage ?? "separate"
|
|
3569
|
+
};
|
|
3693
3570
|
}
|
|
3694
3571
|
function mergeCompress(global, provider, model) {
|
|
3695
3572
|
return {
|
|
@@ -4055,6 +3932,87 @@ function peelRefTagBlocks(blocks) {
|
|
|
4055
3932
|
// src/state.ts
|
|
4056
3933
|
import { promises as fs } from "fs";
|
|
4057
3934
|
import * as path2 from "path";
|
|
3935
|
+
|
|
3936
|
+
// src/log.ts
|
|
3937
|
+
import { appendFileSync, mkdirSync, statSync, renameSync, existsSync } from "fs";
|
|
3938
|
+
import * as path from "path";
|
|
3939
|
+
import { homedir } from "os";
|
|
3940
|
+
import { CONFIG_DIR_NAME } from "@earendil-works/pi-coding-agent";
|
|
3941
|
+
var MAX_BYTES = 10 * 1024 * 1024;
|
|
3942
|
+
var ENV_DEBUG = process.env.ACP_DEBUG === "1" || process.env.ACP_DEBUG === "true";
|
|
3943
|
+
function resolveLogFile() {
|
|
3944
|
+
return process.env.ACP_LOG_FILE ?? path.join(homedir(), CONFIG_DIR_NAME, "acp.log");
|
|
3945
|
+
}
|
|
3946
|
+
var runtimeDebug = null;
|
|
3947
|
+
function setDebugEnabled(enabled) {
|
|
3948
|
+
runtimeDebug = enabled;
|
|
3949
|
+
}
|
|
3950
|
+
function debugOn() {
|
|
3951
|
+
return runtimeDebug ?? ENV_DEBUG;
|
|
3952
|
+
}
|
|
3953
|
+
function fmt(v) {
|
|
3954
|
+
if (typeof v === "string") return v;
|
|
3955
|
+
if (v instanceof Error) return v.stack || String(v);
|
|
3956
|
+
try {
|
|
3957
|
+
return JSON.stringify(v);
|
|
3958
|
+
} catch {
|
|
3959
|
+
return String(v);
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
function ts() {
|
|
3963
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3964
|
+
}
|
|
3965
|
+
function writeLine(level, scope, fields) {
|
|
3966
|
+
const file = resolveLogFile();
|
|
3967
|
+
try {
|
|
3968
|
+
if (existsSync(file) && statSync(file).size >= MAX_BYTES) {
|
|
3969
|
+
renameSync(file, file + ".old");
|
|
3970
|
+
}
|
|
3971
|
+
} catch {
|
|
3972
|
+
}
|
|
3973
|
+
const body = Object.keys(fields).map((k) => `${k}=${fmt(fields[k])}`).join(" ");
|
|
3974
|
+
const line = `${ts()} [${level}] [${scope}] ${body}
|
|
3975
|
+
`;
|
|
3976
|
+
try {
|
|
3977
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
3978
|
+
appendFileSync(file, line);
|
|
3979
|
+
} catch {
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
function closeLogStream() {
|
|
3983
|
+
}
|
|
3984
|
+
function logError(scope, fields) {
|
|
3985
|
+
writeLine("error", scope, fields);
|
|
3986
|
+
}
|
|
3987
|
+
function logWarn(scope, fields) {
|
|
3988
|
+
writeLine("warn", scope, fields);
|
|
3989
|
+
}
|
|
3990
|
+
function logInfo(scope, fields) {
|
|
3991
|
+
writeLine("info", scope, fields);
|
|
3992
|
+
}
|
|
3993
|
+
function logThrow(scope, err, extra = {}) {
|
|
3994
|
+
const fields = { ...extra };
|
|
3995
|
+
if (err instanceof Error) {
|
|
3996
|
+
fields.error = err.message;
|
|
3997
|
+
fields.stack = err.stack ?? "";
|
|
3998
|
+
} else {
|
|
3999
|
+
fields.error = String(err);
|
|
4000
|
+
}
|
|
4001
|
+
writeLine("error", scope, fields);
|
|
4002
|
+
}
|
|
4003
|
+
var debug = {
|
|
4004
|
+
get enabled() {
|
|
4005
|
+
return debugOn();
|
|
4006
|
+
},
|
|
4007
|
+
get logFile() {
|
|
4008
|
+
return resolveLogFile();
|
|
4009
|
+
},
|
|
4010
|
+
event(scope, fields) {
|
|
4011
|
+
if (debugOn()) writeLine("debug", scope, fields);
|
|
4012
|
+
}
|
|
4013
|
+
};
|
|
4014
|
+
|
|
4015
|
+
// src/state.ts
|
|
4058
4016
|
var STATE_SUFFIX = ".acp.json";
|
|
4059
4017
|
function stateFileFor(sessionFile) {
|
|
4060
4018
|
if (sessionFile) return sessionFile + STATE_SUFFIX;
|
|
@@ -10084,19 +10042,14 @@ function attachWatchdogs(child, hooks, opts) {
|
|
|
10084
10042
|
}, graceMs);
|
|
10085
10043
|
settledGraceTimer.unref?.();
|
|
10086
10044
|
};
|
|
10087
|
-
const idleMs = opts.idleMs ?? 0;
|
|
10088
|
-
const timeoutMs = opts.timeoutMs ?? 0;
|
|
10089
10045
|
const poke = () => {
|
|
10090
|
-
if (idleMs <= 0) return;
|
|
10091
10046
|
if (idleTimer) clearTimeout(idleTimer);
|
|
10092
|
-
idleTimer = setTimeout(() => killByWatchdog(`no output for ${idleMs / 6e4}m`), idleMs);
|
|
10047
|
+
idleTimer = setTimeout(() => killByWatchdog(`no output for ${opts.idleMs / 6e4}m`), opts.idleMs);
|
|
10093
10048
|
idleTimer.unref?.();
|
|
10094
10049
|
};
|
|
10095
10050
|
poke();
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
timeoutTimer.unref?.();
|
|
10099
|
-
}
|
|
10051
|
+
timeoutTimer = setTimeout(() => killByWatchdog(`${opts.timeoutMs / 6e4}m limit`), opts.timeoutMs);
|
|
10052
|
+
timeoutTimer.unref?.();
|
|
10100
10053
|
const onStdoutEnd = () => {
|
|
10101
10054
|
if (hooks.isSettled()) return;
|
|
10102
10055
|
eofTimer = setTimeout(() => {
|
|
@@ -10312,8 +10265,12 @@ function newPortion(text, prev) {
|
|
|
10312
10265
|
}
|
|
10313
10266
|
|
|
10314
10267
|
// src/delegate-tool.ts
|
|
10268
|
+
var MAX_DEPTH = 2;
|
|
10269
|
+
var SYNC_TIMEOUT_MS = 5 * 6e4;
|
|
10315
10270
|
var EOF_GRACE_MS = 1e4;
|
|
10316
10271
|
var SETTLED_GRACE_MS = 1e4;
|
|
10272
|
+
var IDLE_GRACE_MS = 5 * 6e4;
|
|
10273
|
+
var ASYNC_TIMEOUT_MS = 30 * 6e4;
|
|
10317
10274
|
var KILL_GRACE_MS = 1e4;
|
|
10318
10275
|
var RESULT_SUMMARY_CHARS = 500;
|
|
10319
10276
|
var OUT_DIR = join6(tmpdir2(), "acp-delegate");
|
|
@@ -10338,13 +10295,6 @@ function delegateSpawnOptions(cwd, env) {
|
|
|
10338
10295
|
shell: false
|
|
10339
10296
|
};
|
|
10340
10297
|
}
|
|
10341
|
-
function delegateChildEnv(parentDepth, maxDepth) {
|
|
10342
|
-
return {
|
|
10343
|
-
...process.env,
|
|
10344
|
-
PI_ACP_DELEGATE_DEPTH: String(parentDepth + 1),
|
|
10345
|
-
PI_ACP_DELEGATE_MAX_DEPTH: String(maxDepth)
|
|
10346
|
-
};
|
|
10347
|
-
}
|
|
10348
10298
|
var PI_CLI_ENTRY_RE = /[\\/]pi-coding-agent[\\/]dist[\\/]cli\.js$/;
|
|
10349
10299
|
var PI_PACKAGE_REL = join6("@earendil-works", "pi-coding-agent", "dist", "cli.js");
|
|
10350
10300
|
function probeUpFromArgv(argv1) {
|
|
@@ -10436,10 +10386,6 @@ var delegateDisplayUsage = "separate";
|
|
|
10436
10386
|
function setDelegateDisplayUsage(mode) {
|
|
10437
10387
|
delegateDisplayUsage = mode;
|
|
10438
10388
|
}
|
|
10439
|
-
var delegatePolicy = DEFAULT_DELEGATE_POLICY;
|
|
10440
|
-
function setDelegatePolicy(policy) {
|
|
10441
|
-
delegatePolicy = policy;
|
|
10442
|
-
}
|
|
10443
10389
|
function runningRunsSnapshot() {
|
|
10444
10390
|
const out = [];
|
|
10445
10391
|
for (const r of runs.values()) {
|
|
@@ -10982,9 +10928,8 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
10982
10928
|
return `Unknown agent "${args.agent}". Choose one of: ${AGENT_NAMES.join(", ")}.`;
|
|
10983
10929
|
}
|
|
10984
10930
|
const parentDepth = Number(process.env.PI_ACP_DELEGATE_DEPTH ?? "0");
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
return `Delegate nesting limit reached (depth ${parentDepth}, max ${maxDepth}). The delegate cannot spawn further delegates.`;
|
|
10931
|
+
if (Number.isNaN(parentDepth) || parentDepth >= MAX_DEPTH) {
|
|
10932
|
+
return `Delegate nesting limit reached (depth ${parentDepth}, max ${MAX_DEPTH}). The delegate cannot spawn further delegates.`;
|
|
10988
10933
|
}
|
|
10989
10934
|
if (!args.task || !args.task.trim()) {
|
|
10990
10935
|
if (!args.resumeFrom) {
|
|
@@ -11007,7 +10952,10 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
11007
10952
|
}
|
|
11008
10953
|
const taskText = args.task?.trim() || (args.resumeFrom ? "(resumed \u2014 the original task is in the session history)" : "");
|
|
11009
10954
|
const cwd = args.cwd && args.cwd.trim() ? args.cwd : ctx.cwd;
|
|
11010
|
-
const childEnv =
|
|
10955
|
+
const childEnv = {
|
|
10956
|
+
...process.env,
|
|
10957
|
+
PI_ACP_DELEGATE_DEPTH: String(parentDepth + 1)
|
|
10958
|
+
};
|
|
11011
10959
|
const runId = `del_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
11012
10960
|
const { cliArgs, tmpDir, isAsync, useJsonStream, sessionFile } = await buildChildArgs(args, agent.prompt, ctx, runId);
|
|
11013
10961
|
const requestedAsync = args.async !== false;
|
|
@@ -11048,7 +10996,7 @@ async function runDelegate(pi, args, ctx, signal) {
|
|
|
11048
10996
|
debug.event("delegate-eof-grace", { runId, ms: EOF_GRACE_MS });
|
|
11049
10997
|
}
|
|
11050
10998
|
},
|
|
11051
|
-
{ eofGraceMs: EOF_GRACE_MS, idleMs:
|
|
10999
|
+
{ eofGraceMs: EOF_GRACE_MS, idleMs: IDLE_GRACE_MS, timeoutMs: ASYNC_TIMEOUT_MS, killGraceMs: KILL_GRACE_MS }
|
|
11052
11000
|
);
|
|
11053
11001
|
const replyFile = join6(OUT_DIR, `${runId}.out`);
|
|
11054
11002
|
const activityFile = join6(OUT_DIR, `${runId}.activity`);
|
|
@@ -11208,12 +11156,12 @@ ${output}`);
|
|
|
11208
11156
|
`Task: ${truncate2(taskText, 160)}`,
|
|
11209
11157
|
`Running in the background at \`${cwd}\`.`,
|
|
11210
11158
|
useJsonStream ? `Live activity is streaming to \`${activityFile}\` \u2014 read it anytime to watch the delegate work (tool calls and their output${args.showThinking ? ", plus thinking" : ""}).` : `The reply is streaming to \`${replyFile}\` \u2014 read it anytime to see partial output (this host has no json event mode, so tool activity is not visible).`,
|
|
11211
|
-
|
|
11159
|
+
`A watchdog force-finishes a hung run: no output for ${IDLE_GRACE_MS / 6e4}m, 10s after output ends, or a ${ASYNC_TIMEOUT_MS / 6e4}m hard limit \u2014 the result reflects whatever was produced.`,
|
|
11212
11160
|
``,
|
|
11213
11161
|
`Call acp_delegate_wait({ runId: "${runId}" }) to block for the result (default 10s timeout). If the wait times out, or you skip it, a completion notification (with the result file path) is still injected here automatically when the delegate finishes \u2014 so you may also just continue other work now and let the result find you.`
|
|
11214
11162
|
].join("\n");
|
|
11215
11163
|
}
|
|
11216
|
-
const result = await waitForChild(child, signal
|
|
11164
|
+
const result = await waitForChild(child, signal);
|
|
11217
11165
|
void cleanupTmp(tmpDir);
|
|
11218
11166
|
const body = result.timedOut || result.code !== 0 ? result.stderr.trim() || "(no stderr)" : result.stdout || "(no output)";
|
|
11219
11167
|
const file = await persistResult(runId, body);
|
|
@@ -11247,7 +11195,7 @@ Complete the task below.`, "utf8");
|
|
|
11247
11195
|
}
|
|
11248
11196
|
return { cliArgs, tmpDir, isAsync, useJsonStream, sessionFile };
|
|
11249
11197
|
}
|
|
11250
|
-
function waitForChild(child, signal
|
|
11198
|
+
function waitForChild(child, signal) {
|
|
11251
11199
|
return new Promise((resolve3) => {
|
|
11252
11200
|
const stdoutChunks = [];
|
|
11253
11201
|
let stderrText = "";
|
|
@@ -11255,20 +11203,17 @@ function waitForChild(child, signal, timeoutMs) {
|
|
|
11255
11203
|
child.stderr?.on("data", (c) => {
|
|
11256
11204
|
stderrText += c.toString("utf8");
|
|
11257
11205
|
});
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
finish2({ code: null, stdout: "", stderr: stderrText, timedOut: true });
|
|
11263
|
-
}, timeoutMs);
|
|
11264
|
-
}
|
|
11206
|
+
const timer2 = setTimeout(() => {
|
|
11207
|
+
child.kill("SIGTERM");
|
|
11208
|
+
finish2({ code: null, stdout: "", stderr: stderrText, timedOut: true });
|
|
11209
|
+
}, SYNC_TIMEOUT_MS);
|
|
11265
11210
|
const onAbort = () => {
|
|
11266
|
-
|
|
11211
|
+
clearTimeout(timer2);
|
|
11267
11212
|
child.kill("SIGTERM");
|
|
11268
11213
|
};
|
|
11269
11214
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
11270
11215
|
function finish2(r) {
|
|
11271
|
-
|
|
11216
|
+
clearTimeout(timer2);
|
|
11272
11217
|
signal?.removeEventListener("abort", onAbort);
|
|
11273
11218
|
resolve3(r);
|
|
11274
11219
|
}
|
|
@@ -11286,18 +11231,6 @@ function waitForChild(child, signal, timeoutMs) {
|
|
|
11286
11231
|
});
|
|
11287
11232
|
});
|
|
11288
11233
|
}
|
|
11289
|
-
function fmtMinutes(ms) {
|
|
11290
|
-
const m = ms / 6e4;
|
|
11291
|
-
return Number.isInteger(m) ? `${m}m` : `${m.toFixed(1)}m`;
|
|
11292
|
-
}
|
|
11293
|
-
function asyncWatchdogDescription() {
|
|
11294
|
-
const parts = [];
|
|
11295
|
-
if (delegatePolicy.idleMs !== null) parts.push(`no output for ${fmtMinutes(delegatePolicy.idleMs)}`);
|
|
11296
|
-
parts.push(`${EOF_GRACE_MS / 1e3}s after output ends`);
|
|
11297
|
-
if (delegatePolicy.asyncTimeoutMs !== null) parts.push(`a ${fmtMinutes(delegatePolicy.asyncTimeoutMs)} hard limit`);
|
|
11298
|
-
const joined = parts.length > 1 ? `${parts.slice(0, -1).join(", ")}, or ${parts[parts.length - 1]}` : parts[0];
|
|
11299
|
-
return `A watchdog force-finishes a hung run: ${joined} \u2014 the result reflects whatever was produced.`;
|
|
11300
|
-
}
|
|
11301
11234
|
function formatSyncResult(agent, runId, task, r, file) {
|
|
11302
11235
|
const status = r.timedOut ? "timed out" : r.code === 0 ? "completed" : "FAILED \u26A0\uFE0F";
|
|
11303
11236
|
const header = `Delegate **${agent}** ${status} (runId \`${runId}\`, ${exitLabel(r.code, r.signal)}).`;
|
|
@@ -12520,15 +12453,12 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
12520
12453
|
runtime.clearCompressRetryTracking();
|
|
12521
12454
|
resetDelegateUsage();
|
|
12522
12455
|
setDelegateDisplayUsage("separate");
|
|
12523
|
-
setDelegatePolicy(DEFAULT_DELEGATE_POLICY);
|
|
12524
12456
|
const sid = ctx.sessionManager.getSessionId();
|
|
12525
12457
|
const modelInfo = ctx.model;
|
|
12526
12458
|
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.56" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
|
|
12527
12459
|
try {
|
|
12528
12460
|
await runtime.reloadConfig(ctx.cwd);
|
|
12529
|
-
|
|
12530
|
-
setDelegateDisplayUsage(delegateCfg.displayUsage);
|
|
12531
|
-
setDelegatePolicy(delegateCfg);
|
|
12461
|
+
setDelegateDisplayUsage(resolveDelegate(runtime.adapter).displayUsage);
|
|
12532
12462
|
} catch (e) {
|
|
12533
12463
|
logThrow("config", e, { sid, phase: "session_start" });
|
|
12534
12464
|
}
|
|
@@ -12697,7 +12627,7 @@ ${rendered.text}${example}`);
|
|
|
12697
12627
|
function wireSystemPrompt(pi, runtime) {
|
|
12698
12628
|
pi.on("before_agent_start", (event) => {
|
|
12699
12629
|
if (runtime.refused) return;
|
|
12700
|
-
const delegate =
|
|
12630
|
+
const delegate = runtime.adapter.delegate !== false;
|
|
12701
12631
|
const acp = buildAcpSystemPrompt(runtime.prompts);
|
|
12702
12632
|
const prompt = delegate ? `${acp}
|
|
12703
12633
|
${ACP_DELEGATE_PROMPT}` : acp;
|