openfox 2.0.117 → 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 +16 -0
  2. package/dist/CHANGELOG.md +16 -0
  3. package/dist/{chat-handler-URSNELCE.js → chat-handler-KNBP6WVI.js} +10 -10
  4. package/dist/{chunk-7SDJXHJH.js → chunk-45OS4H3L.js} +31 -128
  5. package/dist/{chunk-3PEYTWCS.js → chunk-5E5G3DLI.js} +3 -3
  6. package/dist/{chunk-ZS6MW2WM.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-I6MY65LO.js → chunk-CX7UJZA5.js} +17 -12
  10. package/dist/{chunk-2PQA3DHY.js → chunk-IDUXGSQV.js} +169 -110
  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-ECCSVMRT.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-EZD7WFBZ.js → chunk-Y6WWEQPC.js} +71 -11
  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-NNBVVFBT.js → dynamic-context-4SKLIPJ4.js} +2 -2
  23. package/dist/{events-IVPAMMR5.js → events-KDFMBVP5.js} +2 -2
  24. package/dist/{launch-HSSFGQ5A.js → launch-Q6GUJ22H.js} +10 -10
  25. package/dist/{orchestrator-FVXUJW3K.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-JRVW5QBA.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-CW6PR3M2.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-V46SOIGP.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-2Q3GRECI.js → tools-GOGLGTNV.js} +7 -7
  38. package/dist/{update-YP7IRT6M.js → update-T3YMIWQO.js} +2 -2
  39. package/dist/web/assets/index-BgENxR9h.js +324 -0
  40. package/dist/web/assets/{index-DTiVSJJu.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-NPTI5RCQ.js +0 -7
  45. package/dist/web/assets/index-C58KXxRi.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
@@ -1760,6 +1766,14 @@ function drainQueue(sessionManager, sessionId, append, onMessage) {
1760
1766
  return { messages: asapMessages, hasMessages: asapMessages.length > 0 };
1761
1767
  }
1762
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
+
1763
1777
  // src/server/chat/agent-loop.ts
1764
1778
  function emitPartialDoneEvents(_sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType) {
1765
1779
  const stats = turnMetrics.buildStats(statsIdentity, mode);
@@ -1792,10 +1806,12 @@ function emitDoneAndBreak(assistantMsgId, segments, statsIdentity, mode, turnMet
1792
1806
  }
1793
1807
  var MAX_TRUNCATION_RETRIES = 3;
1794
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.";
1795
1810
  async function runTopLevelAgentLoop(config, turnMetrics) {
1796
1811
  const { mode, sessionManager, sessionId, llmClient, signal, onMessage, statsIdentity } = config;
1797
1812
  const append = config.append;
1798
1813
  const agentType = config.subAgentMetadata ? "sub-agent" : void 0;
1814
+ const resolveClient = () => config.getLLMClient?.() ?? llmClient;
1799
1815
  const retryLimiter = createRetryLimiter(config.maxRetriesPerTurn ?? 10);
1800
1816
  let truncationRetryCount = 0;
1801
1817
  let returnValueContent;
@@ -1809,26 +1825,26 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1809
1825
  if (config.warmup) {
1810
1826
  const session2 = sessionManager.requireSession(sessionId);
1811
1827
  const runtimeConfig2 = getRuntimeConfig();
1812
- const configDir2 = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1813
- const skills2 = await getEnabledSkillMetadata(configDir2, sessionManager.getProjectWorkdir(sessionId));
1828
+ const configDir = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1829
+ const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1814
1830
  const { content: instructionContent2 } = await getAllInstructions(session2.workdir, session2.projectId);
1815
1831
  const toolRegistry2 = config.getToolRegistry();
1816
- const assembledRequest2 = await config.assembleRequest({
1832
+ const assembledRequest = await config.assembleRequest({
1817
1833
  workdir: session2.workdir,
1818
1834
  messages: [],
1819
1835
  injectedFiles: [],
1820
1836
  promptTools: toolRegistry2.definitions,
1821
1837
  toolChoice: "none",
1822
1838
  ...instructionContent2 ? { customInstructions: instructionContent2 } : {},
1823
- ...skills2.length > 0 ? { skills: skills2 } : {}
1839
+ ...skills.length > 0 ? { skills } : {}
1824
1840
  });
1825
- const modelSettings2 = sessionManager.getCurrentModelSettings(sessionId);
1826
- await llmClient.complete({
1827
- messages: [{ role: "system", content: assembledRequest2.systemPrompt }],
1828
- tools: assembledRequest2.tools,
1841
+ const modelSettings = sessionManager.getCurrentModelSettings(sessionId);
1842
+ await resolveClient().complete({
1843
+ messages: [{ role: "system", content: assembledRequest.systemPrompt }],
1844
+ tools: assembledRequest.tools,
1829
1845
  maxTokens: 1,
1830
1846
  temperature: 0,
1831
- ...modelSettings2 ? { modelSettings: modelSettings2 } : {}
1847
+ ...modelSettings ? { modelSettings } : {}
1832
1848
  });
1833
1849
  return {};
1834
1850
  }
@@ -1845,71 +1861,125 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1845
1861
  }));
1846
1862
  const toolRegistry = config.getToolRegistry();
1847
1863
  const currentWindowMessageOptions = getCurrentWindowMessageOptions(sessionId);
1848
- const requestMessages = await config.getConversationMessages();
1849
- if (retryLimiter.count() > 0) {
1850
- const continueMsgId = crypto.randomUUID();
1851
- 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}.
1852
1878
  Matched content:
1853
1879
  ${lastPatternMatch.matchedContent}
1854
1880
 
1855
1881
  ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1856
- append(
1857
- createMessageStartEvent(continueMsgId, "user", continueContent, {
1858
- ...currentWindowMessageOptions ?? {},
1859
- isSystemGenerated: true,
1860
- messageKind: "correction"
1861
- })
1862
- );
1863
- append({ type: "message.done", data: { messageId: continueMsgId } });
1864
- 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);
1865
1982
  }
1866
- const runtimeConfig = getRuntimeConfig();
1867
- const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1868
- const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1869
- if (signal?.aborted) throw new Error("Aborted");
1870
- const assembledRequest = await config.assembleRequest({
1871
- workdir: session.workdir,
1872
- messages: requestMessages,
1873
- injectedFiles,
1874
- promptTools: toolRegistry.definitions,
1875
- toolChoice: "auto",
1876
- ...instructionContent ? { customInstructions: instructionContent } : {},
1877
- ...skills.length > 0 ? { skills } : {}
1878
- });
1879
- const assistantMsgId = crypto.randomUUID();
1880
- append(
1881
- createMessageStartEvent(assistantMsgId, "assistant", void 0, {
1882
- ...currentWindowMessageOptions ?? {},
1883
- ...config.subAgentMetadata ? { subAgentId: config.subAgentMetadata.subAgentId, subAgentType: config.subAgentMetadata.subAgentType } : {}
1884
- })
1885
- );
1886
- const contextState = sessionManager.getContextState(sessionId);
1887
- const previousContextTokens = contextState.currentTokens;
1888
- const contextWindow = sessionManager.getCurrentModelContext();
1889
- const availableForOutput = Math.max(256, contextWindow - contextState.currentTokens);
1890
- let modelSettings = config.modelSettings ?? (currentMaxTokensOverride !== void 0 ? { ...sessionManager.getCurrentModelSettings(sessionId), maxTokens: currentMaxTokensOverride } : sessionManager.getCurrentModelSettings(sessionId));
1891
- if (modelSettings) {
1892
- const requestedMaxTokens = modelSettings.maxTokens ?? 16384;
1893
- modelSettings = { ...modelSettings, maxTokens: Math.min(requestedMaxTokens, availableForOutput) };
1894
- }
1895
- const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
1896
- const subAgentAliases = new Set(getSubAgents(allAgents).map((a) => a.metadata.id));
1897
- const streamGen = streamLLMPure({
1898
- messageId: assistantMsgId,
1899
- systemPrompt: assembledRequest.systemPrompt,
1900
- llmClient,
1901
- messages: assembledRequest.messages,
1902
- tools: assembledRequest.tools,
1903
- toolChoice: "auto",
1904
- signal,
1905
- subAgentAliases,
1906
- ...config.retryPatterns ? { retryPatterns: config.retryPatterns } : {},
1907
- ...config.suppressChatError ? { suppressChatError: true } : {},
1908
- ...modelSettings && { modelSettings }
1909
- });
1910
- const result = await consumeStreamGenerator(streamGen, (event) => {
1911
- append(event);
1912
- });
1913
1983
  if (result.patternMatch) {
1914
1984
  if (!retryLimiter.canRetry()) {
1915
1985
  append({
@@ -1949,41 +2019,30 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1949
2019
  continue;
1950
2020
  }
1951
2021
  if (result.aborted) {
1952
- emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2022
+ if (assistantMessageStarted) {
2023
+ emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2024
+ }
1953
2025
  throw new Error("Aborted");
1954
2026
  }
1955
- if (result.error) {
1956
- const stats2 = turnMetrics.buildStats(statsIdentity, mode);
1957
- append(
1958
- createMessageDoneEvent(assistantMsgId, {
1959
- segments: result.segments,
1960
- stats: stats2
1961
- })
1962
- );
1963
- append(createChatDoneEvent(assistantMsgId, "error", stats2, agentType));
1964
- return { failed: { error: result.error } };
1965
- }
1966
- if (!result.error) {
1967
- turnMetrics.addLLMCall(
1968
- result.timing,
1969
- result.usage.promptTokens,
1970
- result.usage.completionTokens,
1971
- previousContextTokens,
1972
- result.modelParams
1973
- );
1974
- sessionManager.setCurrentContextSize(
1975
- sessionId,
1976
- result.usage.promptTokens,
1977
- result.usage.completionTokens,
1978
- config.subAgentMetadata?.subAgentId
1979
- );
1980
- }
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
+ );
1981
2040
  if (!compacting) {
1982
- const contextState2 = sessionManager.getContextState(sessionId);
1983
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-LAXZLPPA.js");
2041
+ const contextState = sessionManager.getContextState(sessionId);
2042
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-5ATICQ2A.js");
1984
2043
  if (shouldCompact(
1985
- contextState2.currentTokens,
1986
- contextState2.maxTokens,
2044
+ contextState.currentTokens,
2045
+ contextState.maxTokens,
1987
2046
  sessionManager.getModelCompactionThreshold(sessionId) ?? runtimeConfig.context.compactionThreshold
1988
2047
  )) {
1989
2048
  appendCompactionPrompt(sessionId, append);
@@ -1996,8 +2055,8 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1996
2055
  truncationRetryCount += 1;
1997
2056
  const currentMaxTokens = result.modelParams?.maxTokens ?? 16384;
1998
2057
  const promptTokens = result.usage.promptTokens;
1999
- const contextWindow2 = sessionManager.getCurrentModelContext();
2000
- 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);
2001
2060
  currentMaxTokensOverride = newMaxTokens;
2002
2061
  const interimStats = turnMetrics.buildStats(statsIdentity, mode);
2003
2062
  append(
@@ -2069,7 +2128,7 @@ ${COMPACTION_PROMPT}`,
2069
2128
  turnMetrics,
2070
2129
  signal,
2071
2130
  onMessage,
2072
- llmClient,
2131
+ llmClient: resolveClient(),
2073
2132
  statsIdentity,
2074
2133
  onToolExecuted: config.onToolExecuted
2075
2134
  };
@@ -2970,7 +3029,7 @@ var callSubAgentTool = {
2970
3029
  };
2971
3030
  }
2972
3031
  try {
2973
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-2Q3GRECI.js");
3032
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-GOGLGTNV.js");
2974
3033
  const toolRegistry = getToolRegistryForAgent2(agentDef);
2975
3034
  const turnMetrics = new TurnMetrics();
2976
3035
  const result = await executeSubAgent({
@@ -3992,7 +4051,7 @@ var mcpConfigTool = createTool(
3992
4051
  mcpNotifyChanged?.(sessionId);
3993
4052
  }
3994
4053
  async function rebuildTools() {
3995
- const { setMcpTools: setMcpTools2 } = await import("./tools-2Q3GRECI.js");
4054
+ const { setMcpTools: setMcpTools2 } = await import("./tools-GOGLGTNV.js");
3996
4055
  const mcpTools = createMcpTools(mcpManagerForTools);
3997
4056
  setMcpTools2(mcpTools);
3998
4057
  }
@@ -4876,4 +4935,4 @@ export {
4876
4935
  getToolRegistryForAgent,
4877
4936
  createToolRegistry
4878
4937
  };
4879
- //# sourceMappingURL=chunk-2PQA3DHY.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