@aexol/spectral 0.9.175 → 0.9.177

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.
@@ -186,6 +186,16 @@ export declare class AgentBridge {
186
186
  private promptReject?;
187
187
  /** Per-turn tool execution backstop timer (see TOOL_EXECUTION_TIMEOUT_MS). */
188
188
  private toolExecutionTimer?;
189
+ /**
190
+ * Number of in-flight `subagent` tool calls. While >0 the parent prompt
191
+ * inactivity watchdog is paused: the parent is legitimately waiting on the
192
+ * child agent, and the child carries its own independent deadline
193
+ * (SPECTRAL_SUBAGENT_TIMEOUT_MS). Pausing (rather than just bumping on
194
+ * progress events) prevents a silent subagent phase — a long LLM thinking
195
+ * stretch or a quiet build/test — from tripping the parent watchdog and
196
+ * aborting the whole prompt mid-delegation.
197
+ */
198
+ private activeSubagents;
189
199
  /** Current model's credit rates (from availableAgentModels), used for token_usage. */
190
200
  private activeCreditRates;
191
201
  private memoryPhase;
@@ -393,6 +403,16 @@ export declare class AgentBridge {
393
403
  * streaming tool output is never killed by the inactivity timeout.
394
404
  */
395
405
  private bumpPromptActivity;
406
+ /** Arm a fresh inactivity watchdog timeout (used by bump/resume paths). */
407
+ private schedulePromptActivityTimeout;
408
+ /**
409
+ * Pause the parent inactivity watchdog while a subagent tool is running.
410
+ * Idempotent per active subagent: the watchdog stays cleared until the last
411
+ * in-flight subagent finishes.
412
+ */
413
+ private pausePromptActivityForSubagent;
414
+ /** Re-arm the inactivity watchdog once no subagents remain in flight. */
415
+ private resumePromptActivityAfterSubagent;
396
416
  private clearPromptTimers;
397
417
  /**
398
418
  * Start the per-turn tool execution backstop. Only the first
@@ -1 +1 @@
1
- {"version":3,"file":"agent-bridge.d.ts","sourceRoot":"","sources":["../../src/server/agent-bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-bridge.d.ts","sourceRoot":"","sources":["../../src/server/agent-bridge.ts"],"names":[],"mappings":"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"}
@@ -392,14 +392,22 @@ function inferSyntheticOpenAICompat(model) {
392
392
  supportsDeveloperRole: false,
393
393
  };
394
394
  }
395
- if (model.provider === "built-in" &&
396
- (model.modelId.toLowerCase().includes("gpt-5") ||
397
- bare.toLowerCase().includes("gpt-5"))) {
398
- return {
399
- thinkingFormat: "openai",
400
- supportsReasoningEffort: true,
401
- supportsStore: false,
395
+ if (model.provider === "built-in") {
396
+ const compat = {
397
+ // Built-in models are proxied through the backend, which forwards a
398
+ // session-affinity key to OpenRouter for prompt-cache sticky routing.
399
+ // Sending the real per-session id from the CLI lets the backend use it
400
+ // instead of a coarser machine/team fallback, maximizing cache hits on
401
+ // large multi-turn agentic prompts.
402
+ sendSessionAffinityHeaders: true,
402
403
  };
404
+ if (model.modelId.toLowerCase().includes("gpt-5") ||
405
+ bare.toLowerCase().includes("gpt-5")) {
406
+ compat.thinkingFormat = "openai";
407
+ compat.supportsReasoningEffort = true;
408
+ compat.supportsStore = false;
409
+ }
410
+ return compat;
403
411
  }
404
412
  if (model.provider === "openrouter") {
405
413
  const compat = {
@@ -562,8 +570,13 @@ const PROMPT_INACTIVITY_TIMEOUT_MS = Number(process.env.SPECTRAL_PROMPT_INACTIVI
562
570
  * though those chunks no longer reset the inactivity watchdog, this timer
563
571
  * provides an absolute backstop per tool invocation.
564
572
  *
565
- * Default 60 minutes (raised from 30 — long builds/subagents were hitting it),
573
+ * Default 60 minutes (raised from 30 — long builds were hitting it),
566
574
  * overridable via `SPECTRAL_TOOL_EXECUTION_TIMEOUT_MS`.
575
+ *
576
+ * The `subagent` tool is exempt: it carries its own independent deadline
577
+ * (`SPECTRAL_SUBAGENT_TIMEOUT_MS`, default 4h) and streams progress events
578
+ * that keep the inactivity watchdog fed, so the per-tool backstop must not
579
+ * kill a long-running subagent mid-delegation.
567
580
  * On expiry it forces a prompt reject (same abort path as the inactivity
568
581
  * watchdog) with a descriptive message.
569
582
  */
@@ -601,6 +614,16 @@ export class AgentBridge {
601
614
  promptReject;
602
615
  /** Per-turn tool execution backstop timer (see TOOL_EXECUTION_TIMEOUT_MS). */
603
616
  toolExecutionTimer;
617
+ /**
618
+ * Number of in-flight `subagent` tool calls. While >0 the parent prompt
619
+ * inactivity watchdog is paused: the parent is legitimately waiting on the
620
+ * child agent, and the child carries its own independent deadline
621
+ * (SPECTRAL_SUBAGENT_TIMEOUT_MS). Pausing (rather than just bumping on
622
+ * progress events) prevents a silent subagent phase — a long LLM thinking
623
+ * stretch or a quiet build/test — from tripping the parent watchdog and
624
+ * aborting the whole prompt mid-delegation.
625
+ */
626
+ activeSubagents = 0;
604
627
  /** Current model's credit rates (from availableAgentModels), used for token_usage. */
605
628
  activeCreditRates = null;
606
629
  memoryPhase = "idle";
@@ -1522,10 +1545,33 @@ export class AgentBridge {
1522
1545
  if (!this.promptActivityTimer)
1523
1546
  return;
1524
1547
  clearTimeout(this.promptActivityTimer);
1525
- this.promptActivityTimer = setTimeout(() => {
1548
+ this.promptActivityTimer = this.schedulePromptActivityTimeout();
1549
+ }
1550
+ /** Arm a fresh inactivity watchdog timeout (used by bump/resume paths). */
1551
+ schedulePromptActivityTimeout() {
1552
+ return setTimeout(() => {
1526
1553
  this.promptReject?.(new Error(`Agent prompt inactive for ${PROMPT_INACTIVITY_TIMEOUT_MS / 1000}s`));
1527
1554
  }, PROMPT_INACTIVITY_TIMEOUT_MS);
1528
1555
  }
1556
+ /**
1557
+ * Pause the parent inactivity watchdog while a subagent tool is running.
1558
+ * Idempotent per active subagent: the watchdog stays cleared until the last
1559
+ * in-flight subagent finishes.
1560
+ */
1561
+ pausePromptActivityForSubagent() {
1562
+ this.activeSubagents += 1;
1563
+ if (this.promptActivityTimer) {
1564
+ clearTimeout(this.promptActivityTimer);
1565
+ this.promptActivityTimer = undefined;
1566
+ }
1567
+ }
1568
+ /** Re-arm the inactivity watchdog once no subagents remain in flight. */
1569
+ resumePromptActivityAfterSubagent() {
1570
+ this.activeSubagents = Math.max(0, this.activeSubagents - 1);
1571
+ if (this.activeSubagents === 0 && this.promptReject) {
1572
+ this.promptActivityTimer = this.schedulePromptActivityTimeout();
1573
+ }
1574
+ }
1529
1575
  clearPromptTimers() {
1530
1576
  if (this.promptActivityTimer) {
1531
1577
  clearTimeout(this.promptActivityTimer);
@@ -1533,6 +1579,7 @@ export class AgentBridge {
1533
1579
  }
1534
1580
  this.clearToolExecutionTimer();
1535
1581
  this.promptReject = undefined;
1582
+ this.activeSubagents = 0;
1536
1583
  }
1537
1584
  /**
1538
1585
  * Start the per-turn tool execution backstop. Only the first
@@ -1769,9 +1816,22 @@ export class AgentBridge {
1769
1816
  return;
1770
1817
  }
1771
1818
  case "tool_execution_start": {
1772
- this.startToolExecutionTimer();
1819
+ // Subagents are exempt from the per-tool execution backstop: they run
1820
+ // with their own independent deadline (SPECTRAL_SUBAGENT_TIMEOUT_MS,
1821
+ // default 4h) and stream subagent_progress/subagent_tool_progress
1822
+ // events that already reset the inactivity watchdog. Applying the
1823
+ // shared TOOL_EXECUTION_TIMEOUT_MS ceiling here would abort a
1824
+ // legitimately long-running subagent (and its parent prompt) with a
1825
+ // bare "aborted" result.
1826
+ if (ev.toolName !== "subagent") {
1827
+ this.startToolExecutionTimer();
1828
+ }
1773
1829
  // Emit subagent_start for subagent tool invocations (Option B frontend panels).
1774
1830
  if (ev.toolName === "subagent") {
1831
+ // The parent prompt is now waiting on the child agent. Pause the
1832
+ // inactivity watchdog until the subagent finishes so a silent
1833
+ // subagent phase cannot abort the parent mid-delegation.
1834
+ this.pausePromptActivityForSubagent();
1775
1835
  const args = ev.args;
1776
1836
  const mode = args?.chain?.length > 0
1777
1837
  ? "chain"
@@ -1866,9 +1926,18 @@ export class AgentBridge {
1866
1926
  return;
1867
1927
  }
1868
1928
  case "tool_execution_end": {
1869
- this.clearToolExecutionTimer();
1929
+ // Subagents don't arm the per-tool backstop (see tool_execution_start),
1930
+ // so they must not clear it either — otherwise a subagent ending while
1931
+ // a non-subagent tool is still running would drop that tool's ceiling.
1932
+ if (ev.toolName !== "subagent") {
1933
+ this.clearToolExecutionTimer();
1934
+ }
1870
1935
  // Emit subagent_end for subagent tool completions.
1871
1936
  if (ev.toolName === "subagent") {
1937
+ // Re-arm the parent inactivity watchdog once the last subagent
1938
+ // finishes. The subagent's own timeout already governed the child;
1939
+ // the parent resumes normal silence-based protection from here.
1940
+ this.resumePromptActivityAfterSubagent();
1872
1941
  const result = ev.result;
1873
1942
  const details = result?.details;
1874
1943
  if (details?.results && details.results.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aexol/spectral",
3
- "version": "0.9.175",
3
+ "version": "0.9.177",
4
4
  "description": "AI coding agent for Aexol with relay-based browser access.",
5
5
  "type": "module",
6
6
  "private": false,