openfox 2.0.116 → 2.0.118

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/CHANGELOG.md +40 -0
  3. package/dist/{chat-handler-Z6BEY66U.js → chat-handler-KNBP6WVI.js} +10 -10
  4. package/dist/{chunk-HYPXL7K5.js → chunk-45OS4H3L.js} +31 -128
  5. package/dist/{chunk-SQLJRO3J.js → chunk-5E5G3DLI.js} +3 -3
  6. package/dist/{chunk-QJWTBVJO.js → chunk-5ZR5O5GC.js} +3 -3
  7. package/dist/chunk-BSULZIPW.js +7 -0
  8. package/dist/{chunk-X3XKYGUN.js → chunk-CIYA6BNB.js} +3 -3
  9. package/dist/{chunk-U4HMAYAD.js → chunk-CX7UJZA5.js} +17 -12
  10. package/dist/{chunk-4HV3PDEK.js → chunk-IDUXGSQV.js} +173 -111
  11. package/dist/{chunk-TGVDUK4N.js → chunk-JOCR4CF4.js} +1 -1
  12. package/dist/{chunk-ZKLE2Q3I.js → chunk-KSDWQ6IZ.js} +1 -1
  13. package/dist/{chunk-6XHDNSA3.js → chunk-MTFLMNLN.js} +7 -4
  14. package/dist/{chunk-EQ7DK2TG.js → chunk-NP2SV2CX.js} +74 -6
  15. package/dist/{chunk-4E52GUXJ.js → chunk-RXIDGWNV.js} +35 -34
  16. package/dist/{chunk-4GHLULHB.js → chunk-XAAEP5XM.js} +8 -16
  17. package/dist/{chunk-QQVPUZQB.js → chunk-XZGQZ42D.js} +3 -3
  18. package/dist/{chunk-BH3BBUGB.js → chunk-Y6WWEQPC.js} +85 -23
  19. package/dist/cli/dev.js +1 -1
  20. package/dist/cli/index.js +1 -1
  21. package/dist/{compactor-LAXZLPPA.js → compactor-5ATICQ2A.js} +4 -4
  22. package/dist/{dynamic-context-YHWFFP53.js → dynamic-context-4SKLIPJ4.js} +2 -2
  23. package/dist/{events-IVPAMMR5.js → events-KDFMBVP5.js} +2 -2
  24. package/dist/{launch-PAVQAWGP.js → launch-Q6GUJ22H.js} +10 -10
  25. package/dist/{orchestrator-CS3KXLZE.js → orchestrator-DVCGWWNA.js} +9 -9
  26. package/dist/package.json +1 -1
  27. package/dist/{path-security-JTCHWYG3.js → path-security-L4AJJN2V.js} +5 -5
  28. package/dist/{processor-RZD4JRDX.js → processor-G6UJGA2K.js} +20 -9
  29. package/dist/{protocol-CfUkCYxF.d.ts → protocol-DzJrspsl.d.ts} +15 -8
  30. package/dist/{protocol-HYA5BYVN.js → protocol-TLODRZSB.js} +7 -7
  31. package/dist/{serve-KR22J37W.js → serve-23YIIMXH.js} +15 -15
  32. package/dist/server/index.d.ts +1 -1
  33. package/dist/server/index.js +14 -14
  34. package/dist/{server-ESKTIZL5.js → server-IDXIAC5L.js} +13 -13
  35. package/dist/shared/index.d.ts +1 -1
  36. package/dist/shared/index.js +1 -1
  37. package/dist/{tools-KBS6X3EN.js → tools-GOGLGTNV.js} +7 -7
  38. package/dist/{update-TDS6LP5N.js → update-T3YMIWQO.js} +2 -2
  39. package/dist/web/assets/index-BgENxR9h.js +324 -0
  40. package/dist/web/assets/{index-c43YT-4A.css → index-XTp1QlHA.css} +1 -1
  41. package/dist/web/index.html +2 -2
  42. package/dist/web/sw.js +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-HNHSUQCN.js +0 -7
  45. package/dist/web/assets/index-ChtRS33s.js +0 -324
@@ -7,14 +7,18 @@ import {
7
7
  } from "./chunk-2FCLCUVR.js";
8
8
  import {
9
9
  TurnMetrics,
10
+ clearLLMFailure,
10
11
  consumeStreamGenerator,
11
12
  createChatDoneEvent,
12
13
  createMessageDoneEvent,
13
14
  createMessageStartEvent,
14
15
  createToolCallEvent,
15
16
  createToolResultEvent,
17
+ evaluateLLMRetry,
18
+ recordLLMFailure,
19
+ sleepThroughRetryBackoff,
16
20
  streamLLMPure
17
- } from "./chunk-EQ7DK2TG.js";
21
+ } from "./chunk-NP2SV2CX.js";
18
22
  import {
19
23
  COMPACTION_PROMPT,
20
24
  buildBasePrompt,
@@ -67,19 +71,21 @@ import {
67
71
  extractSensitivePathsFromCommand,
68
72
  registerPathConfirmation,
69
73
  requestPathAccess
70
- } from "./chunk-QQVPUZQB.js";
74
+ } from "./chunk-XZGQZ42D.js";
71
75
  import {
72
76
  getCurrentContextWindowId,
73
77
  getCurrentWindowMessageOptions,
74
78
  getEventStore
75
- } from "./chunk-TGVDUK4N.js";
79
+ } from "./chunk-JOCR4CF4.js";
76
80
  import {
77
81
  createChatDoneMessage,
82
+ createChatLLMRetryFailedMessage,
83
+ createChatLLMRetryMessage,
78
84
  createChatMessageMessage,
79
85
  createChatMessageUpdatedMessage,
80
86
  createChatPathConfirmationMessage,
81
87
  createQueueStateMessage
82
- } from "./chunk-4GHLULHB.js";
88
+ } from "./chunk-XAAEP5XM.js";
83
89
  import {
84
90
  AskUserInterrupt,
85
91
  askUserTool
@@ -1103,6 +1109,7 @@ function hasTopLevelStatementSeparator(command) {
1103
1109
  continue;
1104
1110
  }
1105
1111
  if (ch === ";" || ch === "\n") return true;
1112
+ if ((ch === "&" || ch === "|") && command[i + 1] === ch) return true;
1106
1113
  }
1107
1114
  return false;
1108
1115
  }
@@ -1759,6 +1766,14 @@ function drainQueue(sessionManager, sessionId, append, onMessage) {
1759
1766
  return { messages: asapMessages, hasMessages: asapMessages.length > 0 };
1760
1767
  }
1761
1768
 
1769
+ // src/server/runner/types.ts
1770
+ var DEFAULT_LLM_RETRY_POLICY = {
1771
+ backoffMs: [1e3, 5e3, 3e4],
1772
+ minIntervalMs: 6e4,
1773
+ maxDurationMs: 30 * 6e4,
1774
+ maxAttempts: 40
1775
+ };
1776
+
1762
1777
  // src/server/chat/agent-loop.ts
1763
1778
  function emitPartialDoneEvents(_sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType) {
1764
1779
  const stats = turnMetrics.buildStats(statsIdentity, mode);
@@ -1791,10 +1806,12 @@ function emitDoneAndBreak(assistantMsgId, segments, statsIdentity, mode, turnMet
1791
1806
  }
1792
1807
  var MAX_TRUNCATION_RETRIES = 3;
1793
1808
  var CONTINUE_PROMPT = "Continue your previous response. Do NOT repeat what you already wrote.";
1809
+ var CONTINUE_AFTER_STREAM_ERROR_PROMPT = "The LLM stream was interrupted mid-response. Continue exactly where you left off \u2014 do not repeat what was already written.";
1794
1810
  async function runTopLevelAgentLoop(config, turnMetrics) {
1795
1811
  const { mode, sessionManager, sessionId, llmClient, signal, onMessage, statsIdentity } = config;
1796
1812
  const append = config.append;
1797
1813
  const agentType = config.subAgentMetadata ? "sub-agent" : void 0;
1814
+ const resolveClient = () => config.getLLMClient?.() ?? llmClient;
1798
1815
  const retryLimiter = createRetryLimiter(config.maxRetriesPerTurn ?? 10);
1799
1816
  let truncationRetryCount = 0;
1800
1817
  let returnValueContent;
@@ -1808,26 +1825,26 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1808
1825
  if (config.warmup) {
1809
1826
  const session2 = sessionManager.requireSession(sessionId);
1810
1827
  const runtimeConfig2 = getRuntimeConfig();
1811
- const configDir2 = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1812
- const skills2 = await getEnabledSkillMetadata(configDir2, sessionManager.getProjectWorkdir(sessionId));
1828
+ const configDir = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1829
+ const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1813
1830
  const { content: instructionContent2 } = await getAllInstructions(session2.workdir, session2.projectId);
1814
1831
  const toolRegistry2 = config.getToolRegistry();
1815
- const assembledRequest2 = await config.assembleRequest({
1832
+ const assembledRequest = await config.assembleRequest({
1816
1833
  workdir: session2.workdir,
1817
1834
  messages: [],
1818
1835
  injectedFiles: [],
1819
1836
  promptTools: toolRegistry2.definitions,
1820
1837
  toolChoice: "none",
1821
1838
  ...instructionContent2 ? { customInstructions: instructionContent2 } : {},
1822
- ...skills2.length > 0 ? { skills: skills2 } : {}
1839
+ ...skills.length > 0 ? { skills } : {}
1823
1840
  });
1824
- const modelSettings2 = sessionManager.getCurrentModelSettings(sessionId);
1825
- await llmClient.complete({
1826
- messages: [{ role: "system", content: assembledRequest2.systemPrompt }],
1827
- tools: assembledRequest2.tools,
1841
+ const modelSettings = sessionManager.getCurrentModelSettings(sessionId);
1842
+ await resolveClient().complete({
1843
+ messages: [{ role: "system", content: assembledRequest.systemPrompt }],
1844
+ tools: assembledRequest.tools,
1828
1845
  maxTokens: 1,
1829
1846
  temperature: 0,
1830
- ...modelSettings2 ? { modelSettings: modelSettings2 } : {}
1847
+ ...modelSettings ? { modelSettings } : {}
1831
1848
  });
1832
1849
  return {};
1833
1850
  }
@@ -1844,71 +1861,125 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1844
1861
  }));
1845
1862
  const toolRegistry = config.getToolRegistry();
1846
1863
  const currentWindowMessageOptions = getCurrentWindowMessageOptions(sessionId);
1847
- const requestMessages = await config.getConversationMessages();
1848
- if (retryLimiter.count() > 0) {
1849
- const continueMsgId = crypto.randomUUID();
1850
- const continueContent = lastPatternMatch ? `Your previous response was interrupted because it matched pattern "${lastPatternMatch.pattern}" in ${lastPatternMatch.field}.
1864
+ const retryPolicy = { ...DEFAULT_LLM_RETRY_POLICY, ...config.llmRetryPolicy };
1865
+ const runtimeConfig = getRuntimeConfig();
1866
+ let requestFailures = 0;
1867
+ let requestFirstFailureAt = 0;
1868
+ let continuationAppended = false;
1869
+ let previousContextTokens;
1870
+ let result;
1871
+ let assistantMsgId;
1872
+ let assistantMessageStarted = false;
1873
+ for (; ; ) {
1874
+ const requestMessages = await config.getConversationMessages();
1875
+ if (requestFailures === 0 && retryLimiter.count() > 0) {
1876
+ const continueMsgId = crypto.randomUUID();
1877
+ const continueContent = lastPatternMatch ? `Your previous response was interrupted because it matched pattern "${lastPatternMatch.pattern}" in ${lastPatternMatch.field}.
1851
1878
  Matched content:
1852
1879
  ${lastPatternMatch.matchedContent}
1853
1880
 
1854
1881
  ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1855
- append(
1856
- createMessageStartEvent(continueMsgId, "user", continueContent, {
1857
- ...currentWindowMessageOptions ?? {},
1858
- isSystemGenerated: true,
1859
- messageKind: "correction"
1860
- })
1861
- );
1862
- append({ type: "message.done", data: { messageId: continueMsgId } });
1863
- requestMessages.push({ role: "user", content: continueContent, source: "history" });
1882
+ append(
1883
+ createMessageStartEvent(continueMsgId, "user", continueContent, {
1884
+ ...currentWindowMessageOptions ?? {},
1885
+ isSystemGenerated: true,
1886
+ messageKind: "correction"
1887
+ })
1888
+ );
1889
+ append({ type: "message.done", data: { messageId: continueMsgId } });
1890
+ requestMessages.push({ role: "user", content: continueContent, source: "history" });
1891
+ }
1892
+ const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1893
+ const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1894
+ if (signal?.aborted) throw new Error("Aborted");
1895
+ const assembledRequest = await config.assembleRequest({
1896
+ workdir: session.workdir,
1897
+ messages: requestMessages,
1898
+ injectedFiles,
1899
+ promptTools: toolRegistry.definitions,
1900
+ toolChoice: "auto",
1901
+ ...instructionContent ? { customInstructions: instructionContent } : {},
1902
+ ...skills.length > 0 ? { skills } : {}
1903
+ });
1904
+ assistantMsgId = crypto.randomUUID();
1905
+ assistantMessageStarted = false;
1906
+ const ensureAssistantMessage = () => {
1907
+ if (assistantMessageStarted) return;
1908
+ assistantMessageStarted = true;
1909
+ append(
1910
+ createMessageStartEvent(assistantMsgId, "assistant", void 0, {
1911
+ ...currentWindowMessageOptions ?? {},
1912
+ ...config.subAgentMetadata ? { subAgentId: config.subAgentMetadata.subAgentId, subAgentType: config.subAgentMetadata.subAgentType } : {}
1913
+ })
1914
+ );
1915
+ };
1916
+ const contextState = sessionManager.getContextState(sessionId);
1917
+ previousContextTokens = contextState.currentTokens;
1918
+ const contextWindow = sessionManager.getCurrentModelContext();
1919
+ const availableForOutput = Math.max(256, contextWindow - contextState.currentTokens);
1920
+ let modelSettings = config.modelSettings ?? (currentMaxTokensOverride !== void 0 ? { ...sessionManager.getCurrentModelSettings(sessionId), maxTokens: currentMaxTokensOverride } : sessionManager.getCurrentModelSettings(sessionId));
1921
+ if (modelSettings) {
1922
+ const requestedMaxTokens = modelSettings.maxTokens ?? 16384;
1923
+ modelSettings = { ...modelSettings, maxTokens: Math.min(requestedMaxTokens, availableForOutput) };
1924
+ }
1925
+ const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
1926
+ const subAgentAliases = new Set(getSubAgents(allAgents).map((a) => a.metadata.id));
1927
+ const streamGen = streamLLMPure({
1928
+ messageId: assistantMsgId,
1929
+ systemPrompt: assembledRequest.systemPrompt,
1930
+ llmClient: resolveClient(),
1931
+ messages: assembledRequest.messages,
1932
+ tools: assembledRequest.tools,
1933
+ toolChoice: "auto",
1934
+ signal,
1935
+ subAgentAliases,
1936
+ ...config.retryPatterns ? { retryPatterns: config.retryPatterns } : {},
1937
+ ...modelSettings && { modelSettings }
1938
+ });
1939
+ const attemptResult = await consumeStreamGenerator(streamGen, (event) => {
1940
+ ensureAssistantMessage();
1941
+ append(event);
1942
+ });
1943
+ if (!attemptResult.error) {
1944
+ result = attemptResult;
1945
+ break;
1946
+ }
1947
+ if (assistantMessageStarted && !continuationAppended) {
1948
+ append(createMessageDoneEvent(assistantMsgId, { partial: true }));
1949
+ onMessage?.(createChatMessageUpdatedMessage(assistantMsgId, { isStreaming: false, partial: true }));
1950
+ const continueMsgId = crypto.randomUUID();
1951
+ append(
1952
+ createMessageStartEvent(continueMsgId, "user", CONTINUE_AFTER_STREAM_ERROR_PROMPT, {
1953
+ ...currentWindowMessageOptions ?? {},
1954
+ isSystemGenerated: true,
1955
+ messageKind: "correction"
1956
+ })
1957
+ );
1958
+ append({ type: "message.done", data: { messageId: continueMsgId } });
1959
+ continuationAppended = true;
1960
+ }
1961
+ if (signal?.aborted) throw new Error("Aborted");
1962
+ requestFailures += 1;
1963
+ if (requestFirstFailureAt === 0) {
1964
+ requestFirstFailureAt = Date.now();
1965
+ }
1966
+ const decision = evaluateLLMRetry(requestFailures, requestFirstFailureAt, Date.now(), retryPolicy);
1967
+ if (!decision.retry) {
1968
+ if (!config.subAgentMetadata) {
1969
+ recordLLMFailure(sessionId);
1970
+ config.onMessage?.(createChatLLMRetryFailedMessage(attemptResult.error, requestFailures));
1971
+ }
1972
+ return { failed: { error: attemptResult.error } };
1973
+ }
1974
+ if (!config.subAgentMetadata) {
1975
+ config.onMessage?.(createChatLLMRetryMessage(decision.attempt, decision.delayMs));
1976
+ }
1977
+ const waitResult = await sleepThroughRetryBackoff(decision.delayMs, sessionId, signal);
1978
+ if (waitResult === "aborted") throw new Error("Aborted");
1979
+ }
1980
+ if (!config.subAgentMetadata) {
1981
+ clearLLMFailure(sessionId);
1864
1982
  }
1865
- const runtimeConfig = getRuntimeConfig();
1866
- const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1867
- const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1868
- if (signal?.aborted) throw new Error("Aborted");
1869
- const assembledRequest = await config.assembleRequest({
1870
- workdir: session.workdir,
1871
- messages: requestMessages,
1872
- injectedFiles,
1873
- promptTools: toolRegistry.definitions,
1874
- toolChoice: "auto",
1875
- ...instructionContent ? { customInstructions: instructionContent } : {},
1876
- ...skills.length > 0 ? { skills } : {}
1877
- });
1878
- const assistantMsgId = crypto.randomUUID();
1879
- append(
1880
- createMessageStartEvent(assistantMsgId, "assistant", void 0, {
1881
- ...currentWindowMessageOptions ?? {},
1882
- ...config.subAgentMetadata ? { subAgentId: config.subAgentMetadata.subAgentId, subAgentType: config.subAgentMetadata.subAgentType } : {}
1883
- })
1884
- );
1885
- const contextState = sessionManager.getContextState(sessionId);
1886
- const previousContextTokens = contextState.currentTokens;
1887
- const contextWindow = sessionManager.getCurrentModelContext();
1888
- const availableForOutput = Math.max(256, contextWindow - contextState.currentTokens);
1889
- let modelSettings = config.modelSettings ?? (currentMaxTokensOverride !== void 0 ? { ...sessionManager.getCurrentModelSettings(sessionId), maxTokens: currentMaxTokensOverride } : sessionManager.getCurrentModelSettings(sessionId));
1890
- if (modelSettings) {
1891
- const requestedMaxTokens = modelSettings.maxTokens ?? 16384;
1892
- modelSettings = { ...modelSettings, maxTokens: Math.min(requestedMaxTokens, availableForOutput) };
1893
- }
1894
- const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
1895
- const subAgentAliases = new Set(getSubAgents(allAgents).map((a) => a.metadata.id));
1896
- const streamGen = streamLLMPure({
1897
- messageId: assistantMsgId,
1898
- systemPrompt: assembledRequest.systemPrompt,
1899
- llmClient,
1900
- messages: assembledRequest.messages,
1901
- tools: assembledRequest.tools,
1902
- toolChoice: "auto",
1903
- signal,
1904
- subAgentAliases,
1905
- ...config.retryPatterns ? { retryPatterns: config.retryPatterns } : {},
1906
- ...config.suppressChatError ? { suppressChatError: true } : {},
1907
- ...modelSettings && { modelSettings }
1908
- });
1909
- const result = await consumeStreamGenerator(streamGen, (event) => {
1910
- append(event);
1911
- });
1912
1983
  if (result.patternMatch) {
1913
1984
  if (!retryLimiter.canRetry()) {
1914
1985
  append({
@@ -1948,41 +2019,30 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1948
2019
  continue;
1949
2020
  }
1950
2021
  if (result.aborted) {
1951
- emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2022
+ if (assistantMessageStarted) {
2023
+ emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2024
+ }
1952
2025
  throw new Error("Aborted");
1953
2026
  }
1954
- if (result.error) {
1955
- const stats2 = turnMetrics.buildStats(statsIdentity, mode);
1956
- append(
1957
- createMessageDoneEvent(assistantMsgId, {
1958
- segments: result.segments,
1959
- stats: stats2
1960
- })
1961
- );
1962
- append(createChatDoneEvent(assistantMsgId, "error", stats2, agentType));
1963
- return { failed: { error: result.error } };
1964
- }
1965
- if (!result.error) {
1966
- turnMetrics.addLLMCall(
1967
- result.timing,
1968
- result.usage.promptTokens,
1969
- result.usage.completionTokens,
1970
- previousContextTokens,
1971
- result.modelParams
1972
- );
1973
- sessionManager.setCurrentContextSize(
1974
- sessionId,
1975
- result.usage.promptTokens,
1976
- result.usage.completionTokens,
1977
- config.subAgentMetadata?.subAgentId
1978
- );
1979
- }
2027
+ turnMetrics.addLLMCall(
2028
+ result.timing,
2029
+ result.usage.promptTokens,
2030
+ result.usage.completionTokens,
2031
+ previousContextTokens,
2032
+ result.modelParams
2033
+ );
2034
+ sessionManager.setCurrentContextSize(
2035
+ sessionId,
2036
+ result.usage.promptTokens,
2037
+ result.usage.completionTokens,
2038
+ config.subAgentMetadata?.subAgentId
2039
+ );
1980
2040
  if (!compacting) {
1981
- const contextState2 = sessionManager.getContextState(sessionId);
1982
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-LAXZLPPA.js");
2041
+ const contextState = sessionManager.getContextState(sessionId);
2042
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-5ATICQ2A.js");
1983
2043
  if (shouldCompact(
1984
- contextState2.currentTokens,
1985
- contextState2.maxTokens,
2044
+ contextState.currentTokens,
2045
+ contextState.maxTokens,
1986
2046
  sessionManager.getModelCompactionThreshold(sessionId) ?? runtimeConfig.context.compactionThreshold
1987
2047
  )) {
1988
2048
  appendCompactionPrompt(sessionId, append);
@@ -1995,8 +2055,8 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1995
2055
  truncationRetryCount += 1;
1996
2056
  const currentMaxTokens = result.modelParams?.maxTokens ?? 16384;
1997
2057
  const promptTokens = result.usage.promptTokens;
1998
- const contextWindow2 = sessionManager.getCurrentModelContext();
1999
- const newMaxTokens = Math.min(Math.floor(currentMaxTokens * 1.5), contextWindow2 - promptTokens - 2048);
2058
+ const contextWindow = sessionManager.getCurrentModelContext();
2059
+ const newMaxTokens = Math.min(Math.floor(currentMaxTokens * 1.5), contextWindow - promptTokens - 2048);
2000
2060
  currentMaxTokensOverride = newMaxTokens;
2001
2061
  const interimStats = turnMetrics.buildStats(statsIdentity, mode);
2002
2062
  append(
@@ -2068,7 +2128,7 @@ ${COMPACTION_PROMPT}`,
2068
2128
  turnMetrics,
2069
2129
  signal,
2070
2130
  onMessage,
2071
- llmClient,
2131
+ llmClient: resolveClient(),
2072
2132
  statsIdentity,
2073
2133
  onToolExecuted: config.onToolExecuted
2074
2134
  };
@@ -2129,7 +2189,9 @@ ${COMPACTION_PROMPT}`,
2129
2189
  emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2130
2190
  throw new Error("Aborted");
2131
2191
  }
2132
- void drainQueue(sessionManager, sessionId, append, onMessage);
2192
+ if (!config.subAgentMetadata) {
2193
+ void drainQueue(sessionManager, sessionId, append, onMessage);
2194
+ }
2133
2195
  retryLimiter.reset();
2134
2196
  continue;
2135
2197
  }
@@ -2967,7 +3029,7 @@ var callSubAgentTool = {
2967
3029
  };
2968
3030
  }
2969
3031
  try {
2970
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-KBS6X3EN.js");
3032
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-GOGLGTNV.js");
2971
3033
  const toolRegistry = getToolRegistryForAgent2(agentDef);
2972
3034
  const turnMetrics = new TurnMetrics();
2973
3035
  const result = await executeSubAgent({
@@ -3989,7 +4051,7 @@ var mcpConfigTool = createTool(
3989
4051
  mcpNotifyChanged?.(sessionId);
3990
4052
  }
3991
4053
  async function rebuildTools() {
3992
- const { setMcpTools: setMcpTools2 } = await import("./tools-KBS6X3EN.js");
4054
+ const { setMcpTools: setMcpTools2 } = await import("./tools-GOGLGTNV.js");
3993
4055
  const mcpTools = createMcpTools(mcpManagerForTools);
3994
4056
  setMcpTools2(mcpTools);
3995
4057
  }
@@ -4873,4 +4935,4 @@ export {
4873
4935
  getToolRegistryForAgent,
4874
4936
  createToolRegistry
4875
4937
  };
4876
- //# sourceMappingURL=chunk-4HV3PDEK.js.map
4938
+ //# sourceMappingURL=chunk-IDUXGSQV.js.map
@@ -1465,4 +1465,4 @@ export {
1465
1465
  truncateSessionMessages,
1466
1466
  getRecentUserPromptsForSession
1467
1467
  };
1468
- //# sourceMappingURL=chunk-TGVDUK4N.js.map
1468
+ //# sourceMappingURL=chunk-JOCR4CF4.js.map
@@ -26,4 +26,4 @@ export {
26
26
  isClientMessage,
27
27
  isServerMessage
28
28
  };
29
- //# sourceMappingURL=chunk-ZKLE2Q3I.js.map
29
+ //# sourceMappingURL=chunk-KSDWQ6IZ.js.map
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  combineEventsWithSnapshot,
3
3
  getEventStore
4
- } from "./chunk-TGVDUK4N.js";
4
+ } from "./chunk-JOCR4CF4.js";
5
5
  import {
6
6
  updateSessionMetadata
7
7
  } from "./chunk-KLQEL2DZ.js";
8
8
  import {
9
9
  createContextStateMessage,
10
10
  createSessionStateMessage
11
- } from "./chunk-4GHLULHB.js";
11
+ } from "./chunk-XAAEP5XM.js";
12
12
  import {
13
13
  getPendingQuestionsForSession
14
14
  } from "./chunk-JURM3RPZ.js";
@@ -51,6 +51,7 @@ function buildRunChatTurnParams(params) {
51
51
  sessionManager: params.sessionManager,
52
52
  sessionId: params.sessionId,
53
53
  llmClient: params.llmClient,
54
+ ...params.getSessionLLMClient ? { getSessionLLMClient: params.getSessionLLMClient } : {},
54
55
  signal: params.signal,
55
56
  onMessage: params.onMessage,
56
57
  ...params.statsIdentity ? { statsIdentity: params.statsIdentity } : {}
@@ -103,6 +104,7 @@ function applyGeneratedSessionName(sessionId, name, deps) {
103
104
  const { messages, hiddenCount } = buildMessagesFromStoredEvents(events, maxVisibleItems || void 0);
104
105
  const pendingConfirmations = foldPendingConfirmations(events);
105
106
  const pendingQuestions = getPendingQuestionsForSession(sessionId);
107
+ const activeWorkflowExecution = deps.sessionManager.getDisplayWorkflowExecution?.(sessionId) ?? void 0;
106
108
  deps.broadcastForSession(
107
109
  sessionId,
108
110
  createSessionStateMessage(
@@ -112,7 +114,8 @@ function applyGeneratedSessionName(sessionId, name, deps) {
112
114
  pendingQuestions,
113
115
  void 0,
114
116
  void 0,
115
- hiddenCount
117
+ hiddenCount,
118
+ activeWorkflowExecution
116
119
  )
117
120
  );
118
121
  }
@@ -204,4 +207,4 @@ export {
204
207
  needsNameGeneration,
205
208
  generateSessionNameForSession
206
209
  };
207
- //# sourceMappingURL=chunk-6XHDNSA3.js.map
210
+ //# sourceMappingURL=chunk-MTFLMNLN.js.map
@@ -244,11 +244,6 @@ async function* streamLLMPure(options) {
244
244
  case "error":
245
245
  if (signal?.aborted) break;
246
246
  streamError = value.error;
247
- if (options.suppressChatError) break;
248
- yield {
249
- type: "chat.error",
250
- data: { error: value.error, recoverable: true }
251
- };
252
247
  break;
253
248
  }
254
249
  if (activePatterns.length > 0 && (accumulatedContent || accumulatedThinking)) {
@@ -291,6 +286,73 @@ async function* streamLLMPure(options) {
291
286
  }
292
287
  return baseResult;
293
288
  }
289
+ function evaluateLLMRetry(failures, firstFailureAt, now, policy) {
290
+ if (now - firstFailureAt >= policy.maxDurationMs) return { retry: false };
291
+ if (failures >= policy.maxAttempts) return { retry: false };
292
+ const delayMs = failures <= policy.backoffMs.length ? policy.backoffMs[failures - 1] : policy.minIntervalMs;
293
+ return { retry: true, delayMs, attempt: failures + 1 };
294
+ }
295
+ var retryWaiters = /* @__PURE__ */ new Map();
296
+ var llmFailures = /* @__PURE__ */ new Map();
297
+ function hasRecentLLMFailure(sessionId, withinMs) {
298
+ const at = llmFailures.get(sessionId);
299
+ if (at === void 0) return false;
300
+ if (Date.now() - at <= withinMs) return true;
301
+ llmFailures.delete(sessionId);
302
+ return false;
303
+ }
304
+ function interruptLLMRetryWait(sessionId) {
305
+ const controller = retryWaiters.get(sessionId);
306
+ if (!controller) return false;
307
+ controller.abort();
308
+ return true;
309
+ }
310
+ function sleepWithRetryInterrupt(ms, signal, retryNowSignal) {
311
+ return new Promise((resolve) => {
312
+ if (signal?.aborted) {
313
+ resolve("aborted");
314
+ return;
315
+ }
316
+ if (retryNowSignal?.aborted) {
317
+ resolve("retry-now");
318
+ return;
319
+ }
320
+ const cleanup = () => {
321
+ clearTimeout(timer);
322
+ signal?.removeEventListener("abort", onAbort);
323
+ retryNowSignal?.removeEventListener("abort", onRetryNow);
324
+ };
325
+ const onAbort = () => {
326
+ cleanup();
327
+ resolve("aborted");
328
+ };
329
+ const onRetryNow = () => {
330
+ cleanup();
331
+ resolve("retry-now");
332
+ };
333
+ const timer = setTimeout(() => {
334
+ cleanup();
335
+ resolve("waited");
336
+ }, ms);
337
+ signal?.addEventListener("abort", onAbort, { once: true });
338
+ retryNowSignal?.addEventListener("abort", onRetryNow, { once: true });
339
+ });
340
+ }
341
+ async function sleepThroughRetryBackoff(ms, sessionId, signal) {
342
+ const retryNowController = new AbortController();
343
+ retryWaiters.set(sessionId, retryNowController);
344
+ try {
345
+ return await sleepWithRetryInterrupt(ms, signal, retryNowController.signal);
346
+ } finally {
347
+ retryWaiters.delete(sessionId);
348
+ }
349
+ }
350
+ function recordLLMFailure(sessionId) {
351
+ llmFailures.set(sessionId, Date.now());
352
+ }
353
+ function clearLLMFailure(sessionId) {
354
+ llmFailures.delete(sessionId);
355
+ }
294
356
  var TurnMetrics = class {
295
357
  startTime;
296
358
  totalPrefillTokens = 0;
@@ -434,6 +496,12 @@ async function consumeStreamGenerator(gen, onEvent) {
434
496
 
435
497
  export {
436
498
  streamLLMPure,
499
+ evaluateLLMRetry,
500
+ hasRecentLLMFailure,
501
+ interruptLLMRetryWait,
502
+ sleepThroughRetryBackoff,
503
+ recordLLMFailure,
504
+ clearLLMFailure,
437
505
  TurnMetrics,
438
506
  createMessageStartEvent,
439
507
  createMessageDoneEvent,
@@ -442,4 +510,4 @@ export {
442
510
  createChatDoneEvent,
443
511
  consumeStreamGenerator
444
512
  };
445
- //# sourceMappingURL=chunk-EQ7DK2TG.js.map
513
+ //# sourceMappingURL=chunk-NP2SV2CX.js.map