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 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. Precedence: env > acp.json >
151
- * default (same convention as ACP_MODEL_CONTEXT_LIMIT). Invalid values fall
152
- * back to the default with a logged warning — they never fail the session. */
153
- export declare function resolveDelegate(adapter: AdapterConfig): DelegatePolicy;
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. */
@@ -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
- /** Kill when no output for this long. 0/null disables the idle timer. */
5
- idleMs?: number | null;
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
- const cfg = typeof d === "object" && d !== null ? d : {};
3648
- const enabled = typeof d === "object" && d !== null ? d.enabled !== false : d !== false;
3649
- const displayUsage = cfg.displayUsage ?? adapter.displayUsage ?? "separate";
3650
- const maxDepth = resolveMaxDepth(process.env.PI_ACP_DELEGATE_MAX_DEPTH ?? cfg.maxDepth);
3651
- const syncTimeoutMs = resolveTimeoutMinutes(
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 n * 6e4;
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
- if (timeoutMs > 0) {
10097
- timeoutTimer = setTimeout(() => killByWatchdog(`${timeoutMs / 6e4}m limit`), timeoutMs);
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
- const maxDepth = delegatePolicy.maxDepth;
10986
- if (Number.isNaN(parentDepth) || parentDepth >= maxDepth) {
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 = delegateChildEnv(parentDepth, maxDepth);
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: delegatePolicy.idleMs, timeoutMs: delegatePolicy.asyncTimeoutMs, killGraceMs: KILL_GRACE_MS }
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
- asyncWatchdogDescription(),
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, delegatePolicy.syncTimeoutMs);
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, timeoutMs) {
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
- let timer2;
11259
- if (timeoutMs !== null) {
11260
- timer2 = setTimeout(() => {
11261
- child.kill("SIGTERM");
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
- if (timer2) clearTimeout(timer2);
11211
+ clearTimeout(timer2);
11267
11212
  child.kill("SIGTERM");
11268
11213
  };
11269
11214
  signal?.addEventListener("abort", onAbort, { once: true });
11270
11215
  function finish2(r) {
11271
- if (timer2) clearTimeout(timer2);
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
- const delegateCfg = resolveDelegate(runtime.adapter);
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 = resolveDelegate(runtime.adapter).enabled;
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;