openfox 2.0.117 → 2.0.119

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 (63) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/CHANGELOG.md +42 -0
  3. package/dist/agent-defaults/code-reviewer.agent.md +8 -3
  4. package/dist/{auto-config-AAUO4PKW.js → auto-config-YXNCBYEY.js} +125 -11
  5. package/dist/{chat-handler-URSNELCE.js → chat-handler-M54IWF5Y.js} +15 -14
  6. package/dist/{chunk-HZSKKJHQ.js → chunk-5FAPM2GM.js} +28 -9
  7. package/dist/{chunk-I6MY65LO.js → chunk-6DDB67FN.js} +17 -12
  8. package/dist/{chunk-ZS6MW2WM.js → chunk-AIFZNTUJ.js} +4 -4
  9. package/dist/{chunk-7SDJXHJH.js → chunk-AVQCOSOF.js} +34 -131
  10. package/dist/chunk-EW25UQG3.js +7 -0
  11. package/dist/{chunk-MKWS7TQH.js → chunk-J6KFWVZ3.js} +21 -15
  12. package/dist/{chunk-TGVDUK4N.js → chunk-JOCR4CF4.js} +1 -1
  13. package/dist/chunk-K2QKX4ZJ.js +31 -0
  14. package/dist/{chunk-ZKLE2Q3I.js → chunk-KSDWQ6IZ.js} +1 -1
  15. package/dist/{chunk-TOKQ2UVG.js → chunk-MIPQOHWS.js} +20 -6
  16. package/dist/{chunk-EQ7DK2TG.js → chunk-SE62ZBNX.js} +82 -8
  17. package/dist/{chunk-GZTMCTUS.js → chunk-U6JMRMBW.js} +17 -21
  18. package/dist/{chunk-3PEYTWCS.js → chunk-UNNCD7A3.js} +3 -3
  19. package/dist/{chunk-2PQA3DHY.js → chunk-V5XWUVF5.js} +175 -112
  20. package/dist/{chunk-6XHDNSA3.js → chunk-VFS7TFA7.js} +8 -5
  21. package/dist/{chunk-4GHLULHB.js → chunk-XAAEP5XM.js} +8 -16
  22. package/dist/{chunk-EZD7WFBZ.js → chunk-XB7IXMUI.js} +73 -13
  23. package/dist/{chunk-ECCSVMRT.js → chunk-XZ2WAI66.js} +72 -41
  24. package/dist/{chunk-QQVPUZQB.js → chunk-XZGQZ42D.js} +3 -3
  25. package/dist/{chunk-X3XKYGUN.js → chunk-YHAE2SJI.js} +3 -3
  26. package/dist/cli/dev.js +1 -1
  27. package/dist/cli/index.js +1 -1
  28. package/dist/{client-KCNTDTIR.js → client-R4PI64IL.js} +3 -3
  29. package/dist/{client-pure-B5DHEKQJ.js → client-pure-QSY7TJGK.js} +2 -2
  30. package/dist/{compactor-LAXZLPPA.js → compactor-F6XMYVHL.js} +5 -5
  31. package/dist/{dynamic-context-NNBVVFBT.js → dynamic-context-NXQ2TFAZ.js} +2 -2
  32. package/dist/{events-IVPAMMR5.js → events-KDFMBVP5.js} +2 -2
  33. package/dist/{launch-HSSFGQ5A.js → launch-I5XBYRSJ.js} +15 -14
  34. package/dist/{orchestrator-FVXUJW3K.js → orchestrator-MNON5G7R.js} +14 -13
  35. package/dist/package.json +1 -1
  36. package/dist/{path-security-JTCHWYG3.js → path-security-L4AJJN2V.js} +5 -5
  37. package/dist/{processor-JRVW5QBA.js → processor-OZSK7RUD.js} +25 -13
  38. package/dist/{protocol-CfUkCYxF.d.ts → protocol-D5kJLGWy.d.ts} +16 -9
  39. package/dist/{protocol-HYA5BYVN.js → protocol-TLODRZSB.js} +7 -7
  40. package/dist/provider/index.d.ts +4 -4
  41. package/dist/{provider-Q7J4UFTS.js → provider-7YF42S7C.js} +5 -4
  42. package/dist/{provider-manager-TMBO4DFG.js → provider-manager-FJIPQJMX.js} +5 -4
  43. package/dist/{serve-CW6PR3M2.js → serve-V34QG72C.js} +20 -19
  44. package/dist/server/index.d.ts +5 -3
  45. package/dist/server/index.js +19 -18
  46. package/dist/{server-V46SOIGP.js → server-XZQLWIVD.js} +18 -17
  47. package/dist/{service-M7XJHAK4.js → service-ZKH465DA.js} +6 -5
  48. package/dist/session-status-6Q5B5PEN.js +35 -0
  49. package/dist/shared/index.d.ts +3 -3
  50. package/dist/shared/index.js +1 -1
  51. package/dist/{tasks-X5H5HM4J.js → tasks-I766NBPW.js} +8 -6
  52. package/dist/{tools-2Q3GRECI.js → tools-ZJXDZLRH.js} +12 -11
  53. package/dist/{types-CIVhQMvD.d.ts → types-B5CI_Ql3.d.ts} +3 -1
  54. package/dist/{types-Df7NM9b5.d.ts → types-CZlj7ufS.d.ts} +2 -0
  55. package/dist/{update-YP7IRT6M.js → update-C3YVPKCR.js} +2 -2
  56. package/dist/web/assets/index-BlYcAqzD.js +324 -0
  57. package/dist/web/assets/{index-DTiVSJJu.css → index-D9sfxcRH.css} +1 -1
  58. package/dist/web/index.html +2 -2
  59. package/dist/web/sw.js +1 -1
  60. package/dist/workflow-defaults/default.workflow.json +1 -1
  61. package/package.json +1 -1
  62. package/dist/chunk-NPTI5RCQ.js +0 -7
  63. package/dist/web/assets/index-C58KXxRi.js +0 -324
@@ -1,6 +1,9 @@
1
+ import {
2
+ parseLmStudioModels
3
+ } from "./chunk-K2QKX4ZJ.js";
1
4
  import {
2
5
  createLLMClient
3
- } from "./chunk-MKWS7TQH.js";
6
+ } from "./chunk-J6KFWVZ3.js";
4
7
  import {
5
8
  getModelProfile
6
9
  } from "./chunk-W7VIYHPQ.js";
@@ -14,7 +17,7 @@ import {
14
17
  } from "./chunk-HNCM3D7Y.js";
15
18
  import {
16
19
  resolveAttachmentsInMessages
17
- } from "./chunk-TOKQ2UVG.js";
20
+ } from "./chunk-MIPQOHWS.js";
18
21
  import {
19
22
  logger
20
23
  } from "./chunk-K44MW7JJ.js";
@@ -328,29 +331,18 @@ async function fetchLmStudioModelsWithContext(baseUrl, _apiKey) {
328
331
  logger.info("LM Studio native endpoint returned error", { url: nativeUrl, status: response.status });
329
332
  return [];
330
333
  }
331
- const raw = await response.json();
332
- const rawArray = Array.isArray(raw) ? raw : Array.isArray(raw.models) ? raw.models : Array.isArray(raw.data) ? raw.data : [];
333
- const modelList = rawArray;
334
+ const modelList = parseLmStudioModels(await response.json());
334
335
  if (modelList.length === 0) {
335
336
  logger.info("LM Studio native endpoint returned no models", { url: nativeUrl });
336
337
  return [];
337
338
  }
338
339
  logger.info("LM Studio native models found", { count: modelList.length });
339
340
  return modelList.map((model) => {
340
- const modelId = model.key ?? model.id ?? "";
341
- const loadedContext = model.loaded_instances?.[0]?.config?.context_length;
342
- const maxContext = model.max_context_length;
343
- const contextWindow = loadedContext ?? maxContext ?? 2e5;
344
- logger.info("LM Studio model detected", {
345
- modelId,
346
- loadedContext,
347
- maxContext,
348
- contextWindow
349
- });
341
+ logger.info("LM Studio model detected", { modelId: model.id, contextWindow: model.contextWindow });
350
342
  return {
351
- id: modelId,
352
- contextWindow,
353
- source: loadedContext || maxContext ? "backend" : "default"
343
+ id: model.id,
344
+ contextWindow: model.contextWindow ?? 2e5,
345
+ source: model.contextWindow ? "backend" : "default"
354
346
  };
355
347
  });
356
348
  } catch (error) {
@@ -703,7 +695,8 @@ function createProviderManager(config, options = {}) {
703
695
  ...settings.thinkingExtraKwargs !== void 0 ? { thinkingExtraKwargs: settings.thinkingExtraKwargs } : existingModel?.thinkingExtraKwargs !== void 0 ? { thinkingExtraKwargs: existingModel.thinkingExtraKwargs } : {},
704
696
  ...settings.nonThinkingExtraKwargs !== void 0 ? { nonThinkingExtraKwargs: settings.nonThinkingExtraKwargs } : existingModel?.nonThinkingExtraKwargs !== void 0 ? { nonThinkingExtraKwargs: existingModel.nonThinkingExtraKwargs } : {},
705
697
  ...settings.thinkingQueryParams !== void 0 ? { thinkingQueryParams: settings.thinkingQueryParams } : existingModel?.thinkingQueryParams !== void 0 ? { thinkingQueryParams: existingModel.thinkingQueryParams } : {},
706
- ...settings.nonThinkingQueryParams !== void 0 ? { nonThinkingQueryParams: settings.nonThinkingQueryParams } : existingModel?.nonThinkingQueryParams !== void 0 ? { nonThinkingQueryParams: existingModel.nonThinkingQueryParams } : {}
698
+ ...settings.nonThinkingQueryParams !== void 0 ? { nonThinkingQueryParams: settings.nonThinkingQueryParams } : existingModel?.nonThinkingQueryParams !== void 0 ? { nonThinkingQueryParams: existingModel.nonThinkingQueryParams } : {},
699
+ ...settings.omitParams !== void 0 ? { omitParams: settings.omitParams } : existingModel?.omitParams !== void 0 ? { omitParams: existingModel.omitParams } : {}
707
700
  });
708
701
  if (existingModel) {
709
702
  providers = providers.map(
@@ -725,6 +718,7 @@ function createProviderManager(config, options = {}) {
725
718
  if (model["topK"] !== void 0) baseSettings["topK"] = model["topK"];
726
719
  if (model["maxTokens"] !== void 0) baseSettings["maxTokens"] = model["maxTokens"];
727
720
  if (model["supportsVision"] !== void 0) baseSettings["supportsVision"] = model["supportsVision"];
721
+ if (model["omitParams"] !== void 0) baseSettings["omitParams"] = model["omitParams"];
728
722
  const rawQueryParams = mode === "thinking" ? model.thinkingQueryParams : model.nonThinkingQueryParams;
729
723
  if (rawQueryParams) {
730
724
  return { ...baseSettings, queryParams: JSON.parse(rawQueryParams) };
@@ -740,6 +734,7 @@ function createProviderManager(config, options = {}) {
740
734
  if (fallbackRawQP) {
741
735
  return { ...baseSettings, queryParams: JSON.parse(fallbackRawQP) };
742
736
  }
737
+ if (model["omitParams"] !== void 0) return baseSettings;
743
738
  return void 0;
744
739
  },
745
740
  async refreshProviderModels(providerId) {
@@ -762,8 +757,8 @@ function createProviderManager(config, options = {}) {
762
757
  backendModelsCount: modelsWithContext.length
763
758
  });
764
759
  if (modelsWithContext.length === 0) {
765
- providerStatus.set(providerId, "disconnected");
766
760
  if (userModels.length > 0) {
761
+ providerStatus.set(providerId, "unknown");
767
762
  logger.debug("Backend unavailable, preserving user models", {
768
763
  providerId,
769
764
  userModels: userModels.map((m) => ({ id: m.id, contextWindow: m.contextWindow }))
@@ -771,6 +766,7 @@ function createProviderManager(config, options = {}) {
771
766
  providers = providers.map((p) => p.id === providerId ? { ...p, models: userModels } : p);
772
767
  return { success: true };
773
768
  }
769
+ providerStatus.set(providerId, "disconnected");
774
770
  return { success: false, error: "No models returned from backend" };
775
771
  }
776
772
  providerStatus.set(providerId, "connected");
@@ -803,4 +799,4 @@ export {
803
799
  parseDefaultModelSelection,
804
800
  createProviderManager
805
801
  };
806
- //# sourceMappingURL=chunk-GZTMCTUS.js.map
802
+ //# sourceMappingURL=chunk-U6JMRMBW.js.map
@@ -105,7 +105,7 @@ function resolveAgentDef(sessionManager, sessionId) {
105
105
  }
106
106
  async function buildCachedPrompt(sessionManager, sessionId, agentDef, modelName) {
107
107
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
108
- const { getToolRegistryForAgent } = await import("./tools-2Q3GRECI.js");
108
+ const { getToolRegistryForAgent } = await import("./tools-ZJXDZLRH.js");
109
109
  const tools = getToolRegistryForAgent(agentDef, sessionId).definitions;
110
110
  const toolFingerprint = getToolFingerprint(tools);
111
111
  const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
@@ -124,7 +124,7 @@ async function buildCachedPrompt(sessionManager, sessionId, agentDef, modelName)
124
124
  async function computeSessionHash(sessionManager, sessionId, modelName) {
125
125
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
126
126
  const agentDef = await resolveAgentDef(sessionManager, sessionId);
127
- const { getToolRegistryForAgent } = await import("./tools-2Q3GRECI.js");
127
+ const { getToolRegistryForAgent } = await import("./tools-ZJXDZLRH.js");
128
128
  const tools = getToolRegistryForAgent(agentDef, sessionId).definitions;
129
129
  const toolFingerprint = getToolFingerprint(tools);
130
130
  return computeDynamicContextHash(instructionContent, skills, toolFingerprint, modelName);
@@ -148,4 +148,4 @@ export {
148
148
  computeSessionHash,
149
149
  applyDynamicContext
150
150
  };
151
- //# sourceMappingURL=chunk-3PEYTWCS.js.map
151
+ //# sourceMappingURL=chunk-UNNCD7A3.js.map
@@ -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-SE62ZBNX.js";
18
22
  import {
19
23
  COMPACTION_PROMPT,
20
24
  buildBasePrompt,
@@ -57,7 +61,7 @@ import {
57
61
  getGateConfig,
58
62
  isTaskConflictError,
59
63
  isTaskGateError
60
- } from "./chunk-HZSKKJHQ.js";
64
+ } from "./chunk-5FAPM2GM.js";
61
65
  import {
62
66
  getSessionDisabledServers
63
67
  } from "./chunk-EQ5CGNOT.js";
@@ -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
@@ -116,7 +122,7 @@ import {
116
122
  formatPdfErrorMessage,
117
123
  isPdfBuffer,
118
124
  processPdfContent
119
- } from "./chunk-TOKQ2UVG.js";
125
+ } from "./chunk-MIPQOHWS.js";
120
126
  import {
121
127
  SETTINGS_KEYS,
122
128
  getSetting
@@ -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);
@@ -1791,11 +1805,14 @@ function emitDoneAndBreak(assistantMsgId, segments, statsIdentity, mode, turnMet
1791
1805
  }
1792
1806
  }
1793
1807
  var MAX_TRUNCATION_RETRIES = 3;
1808
+ var OUTPUT_RESERVE_TOKENS = 2048;
1794
1809
  var CONTINUE_PROMPT = "Continue your previous response. Do NOT repeat what you already wrote.";
1810
+ 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
1811
  async function runTopLevelAgentLoop(config, turnMetrics) {
1796
1812
  const { mode, sessionManager, sessionId, llmClient, signal, onMessage, statsIdentity } = config;
1797
1813
  const append = config.append;
1798
1814
  const agentType = config.subAgentMetadata ? "sub-agent" : void 0;
1815
+ const resolveClient = () => config.getLLMClient?.() ?? llmClient;
1799
1816
  const retryLimiter = createRetryLimiter(config.maxRetriesPerTurn ?? 10);
1800
1817
  let truncationRetryCount = 0;
1801
1818
  let returnValueContent;
@@ -1809,26 +1826,26 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1809
1826
  if (config.warmup) {
1810
1827
  const session2 = sessionManager.requireSession(sessionId);
1811
1828
  const runtimeConfig2 = getRuntimeConfig();
1812
- const configDir2 = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1813
- const skills2 = await getEnabledSkillMetadata(configDir2, sessionManager.getProjectWorkdir(sessionId));
1829
+ const configDir = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1830
+ const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1814
1831
  const { content: instructionContent2 } = await getAllInstructions(session2.workdir, session2.projectId);
1815
1832
  const toolRegistry2 = config.getToolRegistry();
1816
- const assembledRequest2 = await config.assembleRequest({
1833
+ const assembledRequest = await config.assembleRequest({
1817
1834
  workdir: session2.workdir,
1818
1835
  messages: [],
1819
1836
  injectedFiles: [],
1820
1837
  promptTools: toolRegistry2.definitions,
1821
1838
  toolChoice: "none",
1822
1839
  ...instructionContent2 ? { customInstructions: instructionContent2 } : {},
1823
- ...skills2.length > 0 ? { skills: skills2 } : {}
1840
+ ...skills.length > 0 ? { skills } : {}
1824
1841
  });
1825
- const modelSettings2 = sessionManager.getCurrentModelSettings(sessionId);
1826
- await llmClient.complete({
1827
- messages: [{ role: "system", content: assembledRequest2.systemPrompt }],
1828
- tools: assembledRequest2.tools,
1842
+ const modelSettings = sessionManager.getCurrentModelSettings(sessionId);
1843
+ await resolveClient().complete({
1844
+ messages: [{ role: "system", content: assembledRequest.systemPrompt }],
1845
+ tools: assembledRequest.tools,
1829
1846
  maxTokens: 1,
1830
1847
  temperature: 0,
1831
- ...modelSettings2 ? { modelSettings: modelSettings2 } : {}
1848
+ ...modelSettings ? { modelSettings } : {}
1832
1849
  });
1833
1850
  return {};
1834
1851
  }
@@ -1845,71 +1862,125 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1845
1862
  }));
1846
1863
  const toolRegistry = config.getToolRegistry();
1847
1864
  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}.
1865
+ const retryPolicy = { ...DEFAULT_LLM_RETRY_POLICY, ...config.llmRetryPolicy };
1866
+ const runtimeConfig = getRuntimeConfig();
1867
+ let requestFailures = 0;
1868
+ let requestFirstFailureAt = 0;
1869
+ let continuationAppended = false;
1870
+ let previousContextTokens;
1871
+ let result;
1872
+ let assistantMsgId;
1873
+ let assistantMessageStarted = false;
1874
+ for (; ; ) {
1875
+ const requestMessages = await config.getConversationMessages();
1876
+ if (requestFailures === 0 && retryLimiter.count() > 0) {
1877
+ const continueMsgId = crypto.randomUUID();
1878
+ const continueContent = lastPatternMatch ? `Your previous response was interrupted because it matched pattern "${lastPatternMatch.pattern}" in ${lastPatternMatch.field}.
1852
1879
  Matched content:
1853
1880
  ${lastPatternMatch.matchedContent}
1854
1881
 
1855
1882
  ${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" });
1883
+ append(
1884
+ createMessageStartEvent(continueMsgId, "user", continueContent, {
1885
+ ...currentWindowMessageOptions ?? {},
1886
+ isSystemGenerated: true,
1887
+ messageKind: "correction"
1888
+ })
1889
+ );
1890
+ append({ type: "message.done", data: { messageId: continueMsgId } });
1891
+ requestMessages.push({ role: "user", content: continueContent, source: "history" });
1892
+ }
1893
+ const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1894
+ const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1895
+ if (signal?.aborted) throw new Error("Aborted");
1896
+ const assembledRequest = await config.assembleRequest({
1897
+ workdir: session.workdir,
1898
+ messages: requestMessages,
1899
+ injectedFiles,
1900
+ promptTools: toolRegistry.definitions,
1901
+ toolChoice: "auto",
1902
+ ...instructionContent ? { customInstructions: instructionContent } : {},
1903
+ ...skills.length > 0 ? { skills } : {}
1904
+ });
1905
+ assistantMsgId = crypto.randomUUID();
1906
+ assistantMessageStarted = false;
1907
+ const ensureAssistantMessage = () => {
1908
+ if (assistantMessageStarted) return;
1909
+ assistantMessageStarted = true;
1910
+ append(
1911
+ createMessageStartEvent(assistantMsgId, "assistant", void 0, {
1912
+ ...currentWindowMessageOptions ?? {},
1913
+ ...config.subAgentMetadata ? { subAgentId: config.subAgentMetadata.subAgentId, subAgentType: config.subAgentMetadata.subAgentType } : {}
1914
+ })
1915
+ );
1916
+ };
1917
+ const contextState = sessionManager.getContextState(sessionId);
1918
+ previousContextTokens = contextState.currentTokens;
1919
+ const contextWindow = sessionManager.getCurrentModelContext();
1920
+ const availableForOutput = Math.max(256, contextWindow - contextState.currentTokens - OUTPUT_RESERVE_TOKENS);
1921
+ let modelSettings = config.modelSettings ?? (currentMaxTokensOverride !== void 0 ? { ...sessionManager.getCurrentModelSettings(sessionId), maxTokens: currentMaxTokensOverride } : sessionManager.getCurrentModelSettings(sessionId));
1922
+ if (modelSettings) {
1923
+ const requestedMaxTokens = modelSettings.maxTokens ?? 16384;
1924
+ modelSettings = { ...modelSettings, maxTokens: Math.min(requestedMaxTokens, availableForOutput) };
1925
+ }
1926
+ const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
1927
+ const subAgentAliases = new Set(getSubAgents(allAgents).map((a) => a.metadata.id));
1928
+ const streamGen = streamLLMPure({
1929
+ messageId: assistantMsgId,
1930
+ systemPrompt: assembledRequest.systemPrompt,
1931
+ llmClient: resolveClient(),
1932
+ messages: assembledRequest.messages,
1933
+ tools: assembledRequest.tools,
1934
+ toolChoice: "auto",
1935
+ signal,
1936
+ subAgentAliases,
1937
+ ...config.retryPatterns ? { retryPatterns: config.retryPatterns } : {},
1938
+ ...modelSettings && { modelSettings }
1939
+ });
1940
+ const attemptResult = await consumeStreamGenerator(streamGen, (event) => {
1941
+ ensureAssistantMessage();
1942
+ append(event);
1943
+ });
1944
+ if (!attemptResult.error) {
1945
+ result = attemptResult;
1946
+ break;
1947
+ }
1948
+ if (assistantMessageStarted && !continuationAppended) {
1949
+ append(createMessageDoneEvent(assistantMsgId, { partial: true }));
1950
+ onMessage?.(createChatMessageUpdatedMessage(assistantMsgId, { isStreaming: false, partial: true }));
1951
+ const continueMsgId = crypto.randomUUID();
1952
+ append(
1953
+ createMessageStartEvent(continueMsgId, "user", CONTINUE_AFTER_STREAM_ERROR_PROMPT, {
1954
+ ...currentWindowMessageOptions ?? {},
1955
+ isSystemGenerated: true,
1956
+ messageKind: "correction"
1957
+ })
1958
+ );
1959
+ append({ type: "message.done", data: { messageId: continueMsgId } });
1960
+ continuationAppended = true;
1961
+ }
1962
+ if (signal?.aborted) throw new Error("Aborted");
1963
+ requestFailures += 1;
1964
+ if (requestFirstFailureAt === 0) {
1965
+ requestFirstFailureAt = Date.now();
1966
+ }
1967
+ const decision = evaluateLLMRetry(requestFailures, requestFirstFailureAt, Date.now(), retryPolicy);
1968
+ if (!decision.retry) {
1969
+ if (!config.subAgentMetadata) {
1970
+ recordLLMFailure(sessionId);
1971
+ config.onMessage?.(createChatLLMRetryFailedMessage(attemptResult.error, requestFailures));
1972
+ }
1973
+ return { failed: { error: attemptResult.error } };
1974
+ }
1975
+ if (!config.subAgentMetadata) {
1976
+ config.onMessage?.(createChatLLMRetryMessage(decision.attempt, decision.delayMs));
1977
+ }
1978
+ const waitResult = await sleepThroughRetryBackoff(decision.delayMs, sessionId, signal);
1979
+ if (waitResult === "aborted") throw new Error("Aborted");
1980
+ }
1981
+ if (!config.subAgentMetadata) {
1982
+ clearLLMFailure(sessionId);
1865
1983
  }
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
1984
  if (result.patternMatch) {
1914
1985
  if (!retryLimiter.canRetry()) {
1915
1986
  append({
@@ -1949,41 +2020,30 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1949
2020
  continue;
1950
2021
  }
1951
2022
  if (result.aborted) {
1952
- emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2023
+ if (assistantMessageStarted) {
2024
+ emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
2025
+ }
1953
2026
  throw new Error("Aborted");
1954
2027
  }
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
- }
2028
+ turnMetrics.addLLMCall(
2029
+ result.timing,
2030
+ result.usage.promptTokens,
2031
+ result.usage.completionTokens,
2032
+ previousContextTokens,
2033
+ result.modelParams
2034
+ );
2035
+ sessionManager.setCurrentContextSize(
2036
+ sessionId,
2037
+ result.usage.promptTokens,
2038
+ result.usage.completionTokens,
2039
+ config.subAgentMetadata?.subAgentId
2040
+ );
1981
2041
  if (!compacting) {
1982
- const contextState2 = sessionManager.getContextState(sessionId);
1983
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-LAXZLPPA.js");
2042
+ const contextState = sessionManager.getContextState(sessionId);
2043
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-F6XMYVHL.js");
1984
2044
  if (shouldCompact(
1985
- contextState2.currentTokens,
1986
- contextState2.maxTokens,
2045
+ contextState.currentTokens,
2046
+ contextState.maxTokens,
1987
2047
  sessionManager.getModelCompactionThreshold(sessionId) ?? runtimeConfig.context.compactionThreshold
1988
2048
  )) {
1989
2049
  appendCompactionPrompt(sessionId, append);
@@ -1996,8 +2056,11 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1996
2056
  truncationRetryCount += 1;
1997
2057
  const currentMaxTokens = result.modelParams?.maxTokens ?? 16384;
1998
2058
  const promptTokens = result.usage.promptTokens;
1999
- const contextWindow2 = sessionManager.getCurrentModelContext();
2000
- const newMaxTokens = Math.min(Math.floor(currentMaxTokens * 1.5), contextWindow2 - promptTokens - 2048);
2059
+ const contextWindow = sessionManager.getCurrentModelContext();
2060
+ const newMaxTokens = Math.min(
2061
+ Math.floor(currentMaxTokens * 1.5),
2062
+ contextWindow - promptTokens - OUTPUT_RESERVE_TOKENS
2063
+ );
2001
2064
  currentMaxTokensOverride = newMaxTokens;
2002
2065
  const interimStats = turnMetrics.buildStats(statsIdentity, mode);
2003
2066
  append(
@@ -2069,7 +2132,7 @@ ${COMPACTION_PROMPT}`,
2069
2132
  turnMetrics,
2070
2133
  signal,
2071
2134
  onMessage,
2072
- llmClient,
2135
+ llmClient: resolveClient(),
2073
2136
  statsIdentity,
2074
2137
  onToolExecuted: config.onToolExecuted
2075
2138
  };
@@ -2970,7 +3033,7 @@ var callSubAgentTool = {
2970
3033
  };
2971
3034
  }
2972
3035
  try {
2973
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-2Q3GRECI.js");
3036
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-ZJXDZLRH.js");
2974
3037
  const toolRegistry = getToolRegistryForAgent2(agentDef);
2975
3038
  const turnMetrics = new TurnMetrics();
2976
3039
  const result = await executeSubAgent({
@@ -3992,7 +4055,7 @@ var mcpConfigTool = createTool(
3992
4055
  mcpNotifyChanged?.(sessionId);
3993
4056
  }
3994
4057
  async function rebuildTools() {
3995
- const { setMcpTools: setMcpTools2 } = await import("./tools-2Q3GRECI.js");
4058
+ const { setMcpTools: setMcpTools2 } = await import("./tools-ZJXDZLRH.js");
3996
4059
  const mcpTools = createMcpTools(mcpManagerForTools);
3997
4060
  setMcpTools2(mcpTools);
3998
4061
  }
@@ -4876,4 +4939,4 @@ export {
4876
4939
  getToolRegistryForAgent,
4877
4940
  createToolRegistry
4878
4941
  };
4879
- //# sourceMappingURL=chunk-2PQA3DHY.js.map
4942
+ //# sourceMappingURL=chunk-V5XWUVF5.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
  }
@@ -153,7 +156,7 @@ async function generateSessionNameForSession(sessionId, userMessage, deps, signa
153
156
  client = deps.getLLMClient();
154
157
  client.setModel(providerConfig.model);
155
158
  } else if (providerConfig) {
156
- const { createLLMClient } = await import("./client-KCNTDTIR.js");
159
+ const { createLLMClient } = await import("./client-R4PI64IL.js");
157
160
  client = createLLMClient({
158
161
  llm: {
159
162
  baseUrl: providerConfig.baseUrl,
@@ -204,4 +207,4 @@ export {
204
207
  needsNameGeneration,
205
208
  generateSessionNameForSession
206
209
  };
207
- //# sourceMappingURL=chunk-6XHDNSA3.js.map
210
+ //# sourceMappingURL=chunk-VFS7TFA7.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createServerMessage,
6
6
  isClientMessage
7
- } from "./chunk-ZKLE2Q3I.js";
7
+ } from "./chunk-KSDWQ6IZ.js";
8
8
 
9
9
  // src/server/session/client-session.ts
10
10
  function toClientSession(session) {
@@ -140,11 +140,11 @@ function createChatDoneMessage(messageId, reason, stats, agentType) {
140
140
  function createChatErrorMessage(error, recoverable) {
141
141
  return createServerMessage("chat.error", { error, recoverable });
142
142
  }
143
- function createChatMessageRemovedMessage(messageIds) {
144
- return createServerMessage("chat.message_removed", { messageIds });
143
+ function createChatLLMRetryMessage(attempt, retryInMs) {
144
+ return createServerMessage("chat.llm_retry", { attempt, retryInMs });
145
145
  }
146
- function createChatStepRetryMessage(stepName, attempt, retryInMs) {
147
- return createServerMessage("chat.step_retry", { stepName, attempt, retryInMs });
146
+ function createChatLLMRetryFailedMessage(error, attempts) {
147
+ return createServerMessage("chat.llm_retry_failed", { error, attempts });
148
148
  }
149
149
  function createChatPathConfirmationMessage(callId, tool, paths, workdir, reason) {
150
150
  return createServerMessage("chat.path_confirmation", { callId, tool, paths, workdir, reason });
@@ -322,14 +322,6 @@ function storedEventToServerMessage(event) {
322
322
  const data = event.data;
323
323
  return createChatFormatRetryMessage(data.attempt, data.maxAttempts, data.pattern, data.field, data.matchedContent);
324
324
  }
325
- case "message.removed": {
326
- const data = event.data;
327
- return createChatMessageRemovedMessage(data.messageIds);
328
- }
329
- case "workflow.step_retry": {
330
- const data = event.data;
331
- return createChatStepRetryMessage(data.stepName, data.attempt, data.retryInMs);
332
- }
333
325
  case "path.confirmation_pending":
334
326
  case "path.confirmation_responded":
335
327
  return null;
@@ -365,8 +357,8 @@ export {
365
357
  createChatMessageUpdatedMessage,
366
358
  createChatDoneMessage,
367
359
  createChatErrorMessage,
368
- createChatMessageRemovedMessage,
369
- createChatStepRetryMessage,
360
+ createChatLLMRetryMessage,
361
+ createChatLLMRetryFailedMessage,
370
362
  createChatPathConfirmationMessage,
371
363
  createChatAskUserMessage,
372
364
  createModeChangedMessage,
@@ -382,4 +374,4 @@ export {
382
374
  createQueueStateMessage,
383
375
  storedEventToServerMessage
384
376
  };
385
- //# sourceMappingURL=chunk-4GHLULHB.js.map
377
+ //# sourceMappingURL=chunk-XAAEP5XM.js.map