openfox 2.0.92 → 2.0.94

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 (78) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/CHANGELOG.md +35 -0
  3. package/dist/{chat-handler-PC5BUJGA.js → chat-handler-Z7OCNJWO.js} +24 -24
  4. package/dist/{chunk-CND2YWIJ.js → chunk-27SDWNKL.js} +12 -4
  5. package/dist/{chunk-GH5PL3JW.js → chunk-2BCQDYNA.js} +3 -3
  6. package/dist/{chunk-VJEVCZZA.js → chunk-3WKAKOU4.js} +3 -3
  7. package/dist/{chunk-CFK34T26.js → chunk-4R7G5JB6.js} +1 -1
  8. package/dist/{chunk-3NGD6IVM.js → chunk-5N5JXT7R.js} +3 -3
  9. package/dist/{chunk-BJHPUMRX.js → chunk-62X2MPO6.js} +2 -2
  10. package/dist/{chunk-DVVRKNFS.js → chunk-DLCMSSG3.js} +32 -17
  11. package/dist/{chunk-LT4MPTGU.js → chunk-FVV7TZC2.js} +19 -4
  12. package/dist/{chunk-6OAJNCRY.js → chunk-GLF65XDS.js} +22 -1
  13. package/dist/{chunk-NO65CC2R.js → chunk-KNRE3DG4.js} +267 -48
  14. package/dist/{chunk-C56Z4OVW.js → chunk-KU3YUGAN.js} +2 -2
  15. package/dist/{chunk-AKZGFLMD.js → chunk-LSDJCJWA.js} +4 -4
  16. package/dist/{chunk-SXHGRPCI.js → chunk-MC3MCMAF.js} +4 -4
  17. package/dist/{chunk-NLJXZZTB.js → chunk-MRWR3SIT.js} +4 -2
  18. package/dist/{chunk-Q7CN4JOO.js → chunk-MUNVSHL5.js} +10 -10
  19. package/dist/{chunk-WWC3R3YL.js → chunk-NLN5LPQ4.js} +2 -2
  20. package/dist/chunk-O4NHL6IN.js +7 -0
  21. package/dist/{chunk-NGN3Q26A.js → chunk-OHBY2673.js} +2 -2
  22. package/dist/{chunk-Z24V2LEL.js → chunk-OQXG4MS4.js} +235 -92
  23. package/dist/{chunk-AXFPEGJI.js → chunk-P637C6X3.js} +24 -4
  24. package/dist/{chunk-6J5IZ2NL.js → chunk-TSHJW7OC.js} +37 -6
  25. package/dist/{chunk-54Q4TGG6.js → chunk-UEOEA6BB.js} +2 -2
  26. package/dist/{chunk-FSLCOA4R.js → chunk-V4QTGYXL.js} +6 -6
  27. package/dist/{chunk-WPACSSBS.js → chunk-VYN37NXW.js} +3 -3
  28. package/dist/{chunk-ST4NYXLH.js → chunk-WWFH5GAR.js} +2 -2
  29. package/dist/{chunk-7YBGCZSI.js → chunk-XNB3JWAR.js} +2 -2
  30. package/dist/{chunk-U7D72C4O.js → chunk-YJ5P33SE.js} +2 -2
  31. package/dist/{chunk-DH32AHTL.js → chunk-ZASSAZ73.js} +2 -2
  32. package/dist/{chunk-4IBFA5IF.js → chunk-ZYDPYFRH.js} +10 -8
  33. package/dist/cli/dev.js +1 -1
  34. package/dist/cli/index.js +1 -1
  35. package/dist/{client-RBXMHFX3.js → client-OBMJSTFN.js} +5 -5
  36. package/dist/{compactor-HW6GBRAG.js → compactor-RSEV7VYH.js} +10 -10
  37. package/dist/{dynamic-context-TDD3Q43F.js → dynamic-context-C3BWQ5GK.js} +9 -9
  38. package/dist/{events-ICX5KVET.js → events-SY5B4VED.js} +9 -7
  39. package/dist/{folding-L2L4OHX6.js → folding-O4OYOTPS.js} +7 -5
  40. package/dist/http-client-3MOFAPO6.js +11 -0
  41. package/dist/{inspect-proxy-NZ3VSMSC.js → inspect-proxy-GF6OI7MR.js} +4 -4
  42. package/dist/{manager-ZPQ6VSM5.js → manager-UP3XMLKX.js} +5 -5
  43. package/dist/{orchestrator-56LSHPPK.js → orchestrator-VSUL2C7G.js} +21 -21
  44. package/dist/package.json +1 -1
  45. package/dist/{path-security-XENIR7SX.js → path-security-E55IEQHD.js} +10 -10
  46. package/dist/{platform-UKZ2QC34.js → platform-7KXP3VVA.js} +4 -4
  47. package/dist/{processor-H6NFFRI2.js → processor-WP34IB3C.js} +21 -21
  48. package/dist/{project-creator-2WMZYQME.js → project-creator-SMWFMIU5.js} +3 -3
  49. package/dist/{projects-N6KVZGMS.js → projects-M5XKC7O6.js} +3 -3
  50. package/dist/{protocol-CaSHnORC.d.ts → protocol-C5ROb3nH.d.ts} +13 -4
  51. package/dist/{protocol-3GNSIGP4.js → protocol-YDNGGADL.js} +3 -3
  52. package/dist/provider/index.d.ts +4 -4
  53. package/dist/{provider-SYYZI2KX.js → provider-E5IP7RF7.js} +6 -6
  54. package/dist/{provider-manager-P3ZSA5QS.js → provider-manager-FVIFMUTO.js} +6 -6
  55. package/dist/{registry-ERUV33AP.js → registry-XBEHPY7C.js} +4 -4
  56. package/dist/{serve-OYOC5O4A.js → serve-NZZVFNMA.js} +29 -28
  57. package/dist/server/index.d.ts +39 -3
  58. package/dist/server/index.js +28 -27
  59. package/dist/server-DYJTLAZS.js +46 -0
  60. package/dist/{session-overrides-NPVYNHTM.js → session-overrides-QWD4V5KW.js} +6 -6
  61. package/dist/{sessions-7KCM5QH4.js → sessions-BT4PION7.js} +15 -7
  62. package/dist/{settings-2OVKFWR5.js → settings-2WVGUPYV.js} +3 -3
  63. package/dist/shared/index.d.ts +3 -3
  64. package/dist/shared/index.js +1 -1
  65. package/dist/{tools-DXBIHSMY.js → tools-YXOCUUKE.js} +19 -19
  66. package/dist/{types-Cw7L4Bze.d.ts → types-D-dEQIrh.d.ts} +1 -1
  67. package/dist/{types-CHCZiJvw.d.ts → types-DHxO1nqw.d.ts} +25 -2
  68. package/dist/{update-7ZIRWYSC.js → update-5HWU675H.js} +2 -2
  69. package/dist/web/assets/{index-mS37wyUs.css → index-BlV1FebL.css} +1 -1
  70. package/dist/web/assets/index-DxAR7yc9.js +317 -0
  71. package/dist/web/index.html +2 -2
  72. package/dist/web/sw.js +1 -1
  73. package/dist/{workspace-YLTMP3OX.js → workspace-IIRKILYL.js} +4 -4
  74. package/package.json +1 -1
  75. package/dist/chunk-5OGB3MCV.js +0 -7
  76. package/dist/http-client-E3CV6E5D.js +0 -11
  77. package/dist/server-H3525HD6.js +0 -45
  78. package/dist/web/assets/index-CrenD396.js +0 -316
@@ -1,17 +1,22 @@
1
1
  import {
2
2
  runAgentTurn,
3
3
  runChatTurn
4
- } from "./chunk-Q7CN4JOO.js";
4
+ } from "./chunk-MUNVSHL5.js";
5
+ import {
6
+ generateSessionNameForSession,
7
+ getSessionMessageCount,
8
+ needsNameGeneration
9
+ } from "./chunk-ZYDPYFRH.js";
5
10
  import {
6
11
  devServerManager,
7
12
  executeSubAgent,
8
13
  getToolRegistryForAgent
9
- } from "./chunk-DVVRKNFS.js";
14
+ } from "./chunk-DLCMSSG3.js";
10
15
  import {
11
16
  checkAborted,
12
17
  onProcessEvent,
13
18
  spawnShellProcess
14
- } from "./chunk-U7D72C4O.js";
19
+ } from "./chunk-YJ5P33SE.js";
15
20
  import {
16
21
  killProcessTree,
17
22
  terminateProcessTree
@@ -23,7 +28,7 @@ import {
23
28
  applyDynamicContext,
24
29
  computeSessionHash,
25
30
  computeUnifiedDiff
26
- } from "./chunk-FSLCOA4R.js";
31
+ } from "./chunk-V4QTGYXL.js";
27
32
  import {
28
33
  createChatErrorMessage,
29
34
  createChatMessageMessage,
@@ -38,14 +43,14 @@ import {
38
43
  parseClientMessage,
39
44
  serializeServerMessage,
40
45
  storedEventToServerMessage
41
- } from "./chunk-CND2YWIJ.js";
46
+ } from "./chunk-27SDWNKL.js";
42
47
  import {
43
48
  getPendingQuestionsForSession,
44
49
  provideAnswer
45
50
  } from "./chunk-EU3WWTFH.js";
46
51
  import {
47
52
  appendCompactionPrompt
48
- } from "./chunk-VJEVCZZA.js";
53
+ } from "./chunk-3WKAKOU4.js";
49
54
  import {
50
55
  TurnMetrics,
51
56
  createMessageStartEvent
@@ -54,14 +59,14 @@ import {
54
59
  combineEventsWithSnapshot,
55
60
  getCurrentContextWindowId,
56
61
  getEventStore
57
- } from "./chunk-LT4MPTGU.js";
62
+ } from "./chunk-FVV7TZC2.js";
58
63
  import {
59
64
  getPlatformShell
60
- } from "./chunk-WWC3R3YL.js";
65
+ } from "./chunk-NLN5LPQ4.js";
61
66
  import {
62
67
  buildMessagesFromStoredEvents,
63
68
  foldPendingConfirmations
64
- } from "./chunk-AXFPEGJI.js";
69
+ } from "./chunk-P637C6X3.js";
65
70
  import {
66
71
  deleteItemFromDir,
67
72
  findAgentById,
@@ -70,10 +75,10 @@ import {
70
75
  loadAllAgentsDefault,
71
76
  resolveDefaultAgentId,
72
77
  saveItemToDir
73
- } from "./chunk-NGN3Q26A.js";
78
+ } from "./chunk-OHBY2673.js";
74
79
  import {
75
80
  getMaxVisibleItems
76
- } from "./chunk-54Q4TGG6.js";
81
+ } from "./chunk-UEOEA6BB.js";
77
82
  import {
78
83
  logger
79
84
  } from "./chunk-K44MW7JJ.js";
@@ -82,7 +87,7 @@ import {
82
87
  } from "./chunk-VUQCQXXJ.js";
83
88
  import {
84
89
  createServerMessage
85
- } from "./chunk-CFK34T26.js";
90
+ } from "./chunk-4R7G5JB6.js";
86
91
  import {
87
92
  getGlobalConfigDir
88
93
  } from "./chunk-CQGTEGKL.js";
@@ -647,6 +652,9 @@ function resolveTemplate(template, ctx) {
647
652
  result = result.replace(/\{\{stepOutput\.(\w+)\}\}/g, (_, key) => ctx.stepOutput[key] ?? "");
648
653
  result = result.replace(/\{\{verifierFindings\}\}/g, ctx.stepOutput["content"] ?? "");
649
654
  result = result.replace(/\{\{previousStepOutput\}\}/g, ctx.stepOutput["stdout"] ?? "");
655
+ for (const [key, value] of Object.entries(ctx.params)) {
656
+ result = result.replaceAll(`{{${key}}}`, value);
657
+ }
650
658
  return result;
651
659
  }
652
660
  function evaluateCondition(condition, stepOutcome, metadataEntries) {
@@ -735,8 +743,10 @@ async function executeWorkflow(workflow, options, subGroup) {
735
743
  const startTime = performance.now();
736
744
  let iterations = 0;
737
745
  const activeSteps = subGroup ? workflow.steps.filter((s) => s.subGroup === subGroup) : workflow.steps;
738
- let currentStepId = subGroup ? activeSteps[0]?.id ?? workflow.entryStep : workflow.entryStep;
739
- let lastStepOutput = {};
746
+ const resumeFromStep = options.resumeFromStep;
747
+ const isResume = !!resumeFromStep;
748
+ let currentStepId = isResume ? resumeFromStep : subGroup ? activeSteps[0]?.id ?? workflow.entryStep : workflow.entryStep;
749
+ let lastStepOutput = options.initialStepOutput ?? {};
740
750
  const firstEntryForStep = /* @__PURE__ */ new Set();
741
751
  const messagesBeforeWorkflow = sessionManager.requireSession(sessionId).messages.length;
742
752
  const activeStepIds = new Set(activeSteps.map((s) => s.id));
@@ -744,6 +754,31 @@ async function executeWorkflow(workflow, options, subGroup) {
744
754
  for (const step of activeSteps) {
745
755
  stepsById.set(step.id, step);
746
756
  }
757
+ if (resumeFromStep) {
758
+ const targetStep = stepsById.get(resumeFromStep);
759
+ if (!targetStep) {
760
+ return {
761
+ finalAction: {
762
+ type: "BLOCKED",
763
+ reason: `Resume target step "${resumeFromStep}" not found in workflow "${workflow.metadata.id}"`,
764
+ blockedCriteria: []
765
+ },
766
+ iterations: 0,
767
+ totalTime: (performance.now() - startTime) / 1e3
768
+ };
769
+ }
770
+ if (targetStep.type !== "user") {
771
+ return {
772
+ finalAction: {
773
+ type: "BLOCKED",
774
+ reason: `Cannot resume from step "${resumeFromStep}" (type: ${targetStep.type}): only user steps support resume`,
775
+ blockedCriteria: []
776
+ },
777
+ iterations: 0,
778
+ totalTime: (performance.now() - startTime) / 1e3
779
+ };
780
+ }
781
+ }
747
782
  logger.debug("Workflow executor starting", { sessionId, workflow: workflow.metadata.id });
748
783
  if (workflow.startCondition && workflow.startCondition.type !== "always") {
749
784
  const session = sessionManager.requireSession(sessionId);
@@ -765,32 +800,58 @@ async function executeWorkflow(workflow, options, subGroup) {
765
800
  };
766
801
  }
767
802
  }
768
- const startMsgId = crypto.randomUUID();
769
- const startWindowOpts = getCurrentWindowMessageOptions(sessionId);
770
- eventStore.append(
771
- sessionId,
772
- createMessageStartEvent(
773
- startMsgId,
774
- "user",
775
- JSON.stringify({
776
- workflowName: workflow.metadata.name,
777
- workflowId: workflow.metadata.id,
778
- workflowColor: workflow.metadata.color
779
- }),
780
- { ...startWindowOpts ?? {}, isSystemGenerated: true, messageKind: "workflow-started" }
781
- )
782
- );
783
- eventStore.append(sessionId, { type: "message.done", data: { messageId: startMsgId } });
784
- if (options.userMessage) {
785
- sessionManager.addMessage(sessionId, {
786
- role: "user",
787
- content: options.userMessage.content,
788
- ...options.userMessage.attachments ? { attachments: options.userMessage.attachments } : {}
789
- });
803
+ let executionId;
804
+ if (!isResume) {
805
+ const startMsgId = crypto.randomUUID();
806
+ const startWindowOpts = getCurrentWindowMessageOptions(sessionId);
807
+ eventStore.append(
808
+ sessionId,
809
+ createMessageStartEvent(
810
+ startMsgId,
811
+ "user",
812
+ JSON.stringify({
813
+ workflowName: workflow.metadata.name,
814
+ workflowId: workflow.metadata.id,
815
+ workflowColor: workflow.metadata.color
816
+ }),
817
+ { ...startWindowOpts ?? {}, isSystemGenerated: true, messageKind: "workflow-started" }
818
+ )
819
+ );
820
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: startMsgId } });
821
+ executionId = crypto.randomUUID();
822
+ sessionManager.startWorkflow(
823
+ sessionId,
824
+ executionId,
825
+ workflow.metadata.id,
826
+ workflow.metadata.name,
827
+ workflow.metadata.color,
828
+ options.params ?? {}
829
+ );
830
+ if (options.userMessage) {
831
+ sessionManager.addMessage(sessionId, {
832
+ role: "user",
833
+ content: options.userMessage.content,
834
+ ...options.userMessage.attachments ? { attachments: options.userMessage.attachments } : {}
835
+ });
836
+ }
837
+ } else {
838
+ const activeExec = sessionManager.getActiveWorkflowExecution(sessionId);
839
+ if (activeExec) {
840
+ executionId = activeExec.id;
841
+ }
790
842
  }
791
843
  while (iterations < workflow.settings.maxIterations) {
792
844
  if (signal?.aborted) {
793
845
  logger.debug("Workflow executor aborted", { sessionId, iterations });
846
+ if (executionId) {
847
+ sessionManager.cancelWorkflow(
848
+ sessionId,
849
+ executionId,
850
+ workflow.metadata.id,
851
+ workflow.metadata.name,
852
+ workflow.metadata.color
853
+ );
854
+ }
794
855
  return {
795
856
  finalAction: { type: "RUN_BUILDER", reason: "Aborted" },
796
857
  iterations,
@@ -819,9 +880,21 @@ async function executeWorkflow(workflow, options, subGroup) {
819
880
  pendingCount: criteriaEntries.filter((e) => e.status !== "passed").length,
820
881
  criteriaList: formatCriteriaList(criteriaEntries),
821
882
  modifiedFiles: await formatModifiedFiles(sessionManager.getEffectiveWorkdir(sessionId)),
822
- stepOutput: lastStepOutput
883
+ stepOutput: lastStepOutput,
884
+ params: options.params ?? {}
823
885
  };
824
886
  sessionManager.setPhase(sessionId, step.phase);
887
+ if (executionId) {
888
+ sessionManager.updateWorkflowStep(
889
+ sessionId,
890
+ executionId,
891
+ step.id,
892
+ step.name,
893
+ workflow.metadata.id,
894
+ workflow.metadata.name,
895
+ workflow.metadata.color
896
+ );
897
+ }
825
898
  if (step.type === "agent") {
826
899
  const agentStep = step;
827
900
  sessionManager.setMode(sessionId, agentStep.agentId ?? resolveDefaultAgentId());
@@ -1021,6 +1094,36 @@ ${output.slice(0, 1e4)}
1021
1094
  stepOutcome = { result: successCodes.includes(result.exitCode) ? "success" : "failure", output: lastStepOutput };
1022
1095
  break;
1023
1096
  }
1097
+ case "user": {
1098
+ if (resumeFromStep === step.id) {
1099
+ stepOutcome = { result: "continue", output: lastStepOutput };
1100
+ break;
1101
+ }
1102
+ if (executionId) {
1103
+ sessionManager.waitAtStep(
1104
+ sessionId,
1105
+ executionId,
1106
+ step.id,
1107
+ step.name,
1108
+ lastStepOutput,
1109
+ workflow.metadata.id,
1110
+ workflow.metadata.name,
1111
+ workflow.metadata.color
1112
+ );
1113
+ }
1114
+ logger.debug("Workflow paused at user step", { sessionId, stepId: step.id, stepName: step.name });
1115
+ return {
1116
+ finalAction: {
1117
+ type: "WAITING",
1118
+ reason: `Paused at user step: ${step.name}`,
1119
+ workflowId: workflow.metadata.id,
1120
+ stepId: step.id,
1121
+ stepOutput: lastStepOutput
1122
+ },
1123
+ iterations,
1124
+ totalTime: (performance.now() - startTime) / 1e3
1125
+ };
1126
+ }
1024
1127
  }
1025
1128
  const refreshedSession = sessionManager.requireSession(sessionId);
1026
1129
  const effectiveTransitions = subGroup ? step.transitions.filter((t) => !t.subGroup || t.subGroup === subGroup) : step.transitions;
@@ -1028,6 +1131,15 @@ ${output.slice(0, 1e4)}
1028
1131
  const nextStepId = subGroup && rawNextStepId !== TERMINAL_DONE && rawNextStepId !== TERMINAL_BLOCKED && !activeStepIds.has(rawNextStepId) ? TERMINAL_DONE : rawNextStepId;
1029
1132
  if (nextStepId === TERMINAL_DONE) {
1030
1133
  sessionManager.setPhase(sessionId, "done");
1134
+ if (executionId) {
1135
+ sessionManager.completeWorkflow(
1136
+ sessionId,
1137
+ executionId,
1138
+ workflow.metadata.id,
1139
+ workflow.metadata.name,
1140
+ workflow.metadata.color
1141
+ );
1142
+ }
1031
1143
  const totalTimeSeconds = Math.round((performance.now() - startTime) / 100) / 10;
1032
1144
  const completedSession = sessionManager.requireSession(sessionId);
1033
1145
  const workflowMessages = completedSession.messages.slice(messagesBeforeWorkflow);
@@ -1068,6 +1180,15 @@ ${output.slice(0, 1e4)}
1068
1180
  }
1069
1181
  if (nextStepId === TERMINAL_BLOCKED) {
1070
1182
  sessionManager.setPhase(sessionId, "blocked");
1183
+ if (executionId) {
1184
+ sessionManager.blockWorkflow(
1185
+ sessionId,
1186
+ executionId,
1187
+ workflow.metadata.id,
1188
+ workflow.metadata.name,
1189
+ workflow.metadata.color
1190
+ );
1191
+ }
1071
1192
  const reason = "No matching transition";
1072
1193
  emitWorkflowMessage(eventStore, sessionId, `Runner blocked: ${reason}`, currentWindowMessageOptions, onMessage);
1073
1194
  logger.warn("Workflow executor blocked", { sessionId, iterations, reason });
@@ -1097,11 +1218,20 @@ async function runOrchestrator(options) {
1097
1218
  const runtimeConfig = getRuntimeConfig();
1098
1219
  const workflowId = options.workflowId ?? runtimeConfig.activeWorkflowId ?? "default";
1099
1220
  const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1100
- const workflows = await loadAllWorkflows(configDir);
1221
+ const session = options.sessionManager.requireSession(options.sessionId);
1222
+ const projectDir = session.workdir;
1223
+ const workflows = await loadAllWorkflows(configDir, projectDir);
1101
1224
  const workflow = findWorkflowById(workflowId, workflows);
1102
1225
  if (!workflow) {
1103
1226
  throw new Error(`Workflow "${workflowId}" not found`);
1104
1227
  }
1228
+ const requiredParams = (workflow.metadata.parameters ?? []).filter((p) => p.required);
1229
+ const suppliedParams = options.params ?? {};
1230
+ const missing = requiredParams.filter((p) => !(p.id in suppliedParams));
1231
+ if (missing.length > 0) {
1232
+ const names = missing.map((p) => p.label || p.id).join(", ");
1233
+ throw new Error(`Missing required parameter${missing.length > 1 ? "s" : ""}: ${names}`);
1234
+ }
1105
1235
  logger.debug("Using workflow executor", {
1106
1236
  sessionId: options.sessionId,
1107
1237
  workflow: workflow.metadata.id,
@@ -1665,6 +1795,7 @@ function createWebSocketServer(httpServer, _config, getLLMClient, getActiveProvi
1665
1795
  const { messages, hiddenCount } = buildMessagesFromStoredEvents(events, maxVisible || void 0);
1666
1796
  const pendingConfirmations = foldPendingConfirmations(events);
1667
1797
  const pendingQuestions = getPendingQuestionsForSession(updatedSession.id);
1798
+ const activeWorkflowExecution = sessionManager.getActiveWorkflowExecution(updatedSession.id);
1668
1799
  const effectiveWorkdir = updatedSession.workspace ?? updatedSession.workdir;
1669
1800
  for (const [, client] of clients) {
1670
1801
  if (client.activeSessionId === updatedSession.id && client.activeWorkdir !== effectiveWorkdir) {
@@ -1688,7 +1819,8 @@ function createWebSocketServer(httpServer, _config, getLLMClient, getActiveProvi
1688
1819
  pendingQuestions,
1689
1820
  void 0,
1690
1821
  void 0,
1691
- hiddenCount
1822
+ hiddenCount,
1823
+ activeWorkflowExecution ?? void 0
1692
1824
  )
1693
1825
  );
1694
1826
  if (effectiveWorkdir) {
@@ -2048,8 +2180,8 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
2048
2180
  const sessionId = client.activeSessionId;
2049
2181
  const session = sessionManager.requireSession(sessionId);
2050
2182
  try {
2051
- const { buildCachedPrompt } = await import("./dynamic-context-TDD3Q43F.js");
2052
- const allAgents = await import("./registry-ERUV33AP.js");
2183
+ const { buildCachedPrompt } = await import("./dynamic-context-C3BWQ5GK.js");
2184
+ const allAgents = await import("./registry-XBEHPY7C.js");
2053
2185
  const agentDef = allAgents.findAgentById(session.mode, await allAgents.loadAllAgentsDefault()) ?? allAgents.findAgentById("planner", await allAgents.loadAllAgentsDefault());
2054
2186
  const { systemPrompt: newPrompt, hash: newHash } = await buildCachedPrompt(sessionManager, sessionId, agentDef);
2055
2187
  const oldCached = sessionManager.getCachedPrompt(sessionId);
@@ -2144,10 +2276,12 @@ ${content}` : workflowInfo;
2144
2276
  return;
2145
2277
  }
2146
2278
  const launchPayloadEarly = message.payload;
2147
- const pendingCriteria = session.criteria.filter((c) => c.status.type !== "passed");
2148
- if (!launchPayloadEarly?.workflowId && pendingCriteria.length === 0) {
2149
- send(createErrorMessage("NO_WORK", "No pending criteria to work on", message.id));
2150
- return;
2279
+ if (!launchPayloadEarly?.resumeFrom) {
2280
+ const pendingCriteria = session.criteria.filter((c) => c.status.type !== "passed");
2281
+ if (!launchPayloadEarly?.workflowId && pendingCriteria.length === 0) {
2282
+ send(createErrorMessage("NO_WORK", "No pending criteria to work on", message.id));
2283
+ return;
2284
+ }
2151
2285
  }
2152
2286
  const sessionId = client.activeSessionId;
2153
2287
  if (session.phase === "blocked") {
@@ -2159,6 +2293,7 @@ ${content}` : workflowInfo;
2159
2293
  const hasUserContent = launchPayload?.content && typeof launchPayload.content === "string" && launchPayload.content.trim();
2160
2294
  const hasUserAttachments = launchAttachments && launchAttachments.length > 0;
2161
2295
  const hasUserMessage = hasUserContent || hasUserAttachments;
2296
+ const isResume = !!launchPayload?.resumeFrom;
2162
2297
  sessionManager.setRunning(sessionId, true);
2163
2298
  sendForSession(sessionId, createSessionRunningMessage(true));
2164
2299
  const controller = new AbortController();
@@ -2170,7 +2305,25 @@ ${content}` : workflowInfo;
2170
2305
  activeAgents.set(sessionId, controller);
2171
2306
  send({ type: "ack", payload: {}, id: message.id });
2172
2307
  ensureEventStoreSubscription(sessionId);
2173
- logger.info("Runner launching", { sessionId, pendingCriteria: pendingCriteria.length });
2308
+ logger.info("Runner launching", { sessionId, isResume });
2309
+ if (!isResume && launchPayload?.workflowId && _providerManager) {
2310
+ const session2 = sessionManager.getSession(sessionId);
2311
+ const messageCount = getSessionMessageCount(sessionId);
2312
+ if (session2 && needsNameGeneration(session2.metadata?.title, messageCount)) {
2313
+ const nameHint = launchPayload.workflowId + (launchPayload?.params && Object.keys(launchPayload.params).length > 0 ? ": " + Object.entries(launchPayload.params).map(([k, v]) => `${k}=${v}`).join(", ") : "");
2314
+ generateSessionNameForSession(
2315
+ sessionId,
2316
+ nameHint,
2317
+ {
2318
+ sessionManager,
2319
+ providerManager: _providerManager,
2320
+ broadcastForSession: _broadcastForSession,
2321
+ eventStore: getEventStore()
2322
+ },
2323
+ controller.signal
2324
+ );
2325
+ }
2326
+ }
2174
2327
  runOrchestrator({
2175
2328
  sessionManager,
2176
2329
  sessionId,
@@ -2178,6 +2331,30 @@ ${content}` : workflowInfo;
2178
2331
  statsIdentity: statsForSession(sessionId),
2179
2332
  ...launchPayload?.workflowId ? { workflowId: launchPayload.workflowId } : {},
2180
2333
  ...launchPayload?.subGroup ? { subGroup: launchPayload.subGroup } : {},
2334
+ ...isResume && launchPayload?.resumeFrom ? { resumeFromStep: launchPayload.resumeFrom } : {},
2335
+ ...isResume && launchPayload?.stepOutput ? { initialStepOutput: launchPayload.stepOutput } : {},
2336
+ ...launchPayload?.params ? { params: launchPayload.params } : {},
2337
+ // On resume, prefer params/stepOutput from the persisted workflow execution
2338
+ ...isResume ? (() => {
2339
+ const exec = sessionManager.getActiveWorkflowExecution(sessionId);
2340
+ if (exec && exec.status === "waiting") {
2341
+ const resumed = sessionManager.resumeWorkflow(
2342
+ sessionId,
2343
+ exec.id,
2344
+ exec.workflowId,
2345
+ exec.workflowName,
2346
+ exec.workflowColor
2347
+ );
2348
+ if (resumed) {
2349
+ return {
2350
+ params: resumed.params,
2351
+ initialStepOutput: resumed.stepOutput,
2352
+ ...exec.currentStepId ? { resumeFromStep: exec.currentStepId } : {}
2353
+ };
2354
+ }
2355
+ }
2356
+ return {};
2357
+ })() : {},
2181
2358
  ...hasUserMessage ? {
2182
2359
  userMessage: {
2183
2360
  content: hasUserContent ? launchPayload.content : "",
@@ -2191,7 +2368,12 @@ ${content}` : workflowInfo;
2191
2368
  if (error instanceof Error && error.message === "Aborted") {
2192
2369
  return;
2193
2370
  }
2194
- logger.error("Runner error", { error, sessionId });
2371
+ const errorMessage = error instanceof Error ? error.message : String(error);
2372
+ logger.error("Runner error", { error: errorMessage, sessionId });
2373
+ _broadcastForSession(
2374
+ sessionId,
2375
+ createServerMessage("chat.error", { error: errorMessage, recoverable: false })
2376
+ );
2195
2377
  }).finally(() => {
2196
2378
  try {
2197
2379
  sessionManager.setRunning(sessionId, false);
@@ -2241,6 +2423,43 @@ ${content}` : workflowInfo;
2241
2423
  send({ type: "ack", payload: {}, id: message.id });
2242
2424
  break;
2243
2425
  }
2426
+ // =========================================================================
2427
+ // Workflow
2428
+ // =========================================================================
2429
+ case "workflow.exit": {
2430
+ if (!client.activeSessionId) {
2431
+ send(createErrorMessage("NO_SESSION", "No active session", message.id));
2432
+ return;
2433
+ }
2434
+ const exitSessionId = client.activeSessionId;
2435
+ const exitSession = sessionManager.getSession(exitSessionId);
2436
+ if (!exitSession) {
2437
+ send(createErrorMessage("NOT_FOUND", "Session not found", message.id));
2438
+ return;
2439
+ }
2440
+ const activeExec = sessionManager.getActiveWorkflowExecution(exitSessionId);
2441
+ if (activeExec) {
2442
+ sessionManager.cancelWorkflow(
2443
+ exitSessionId,
2444
+ activeExec.id,
2445
+ activeExec.workflowId,
2446
+ activeExec.workflowName,
2447
+ activeExec.workflowColor
2448
+ );
2449
+ } else {
2450
+ sessionManager.setPhase(exitSessionId, "build");
2451
+ }
2452
+ const controller = activeAgents.get(exitSessionId);
2453
+ if (controller) {
2454
+ activeAgents.delete(exitSessionId);
2455
+ controller.abort();
2456
+ }
2457
+ if (exitSession.isRunning) {
2458
+ sessionManager.setRunning(exitSessionId, false);
2459
+ }
2460
+ send({ type: "ack", payload: {}, id: message.id });
2461
+ break;
2462
+ }
2244
2463
  default: {
2245
2464
  send(createErrorMessage("UNKNOWN_MESSAGE", `Unknown message type: ${message.type}`, message.id));
2246
2465
  }
@@ -2272,4 +2491,4 @@ export {
2272
2491
  signalMcpReady,
2273
2492
  createWebSocketServer
2274
2493
  };
2275
- //# sourceMappingURL=chunk-NO65CC2R.js.map
2494
+ //# sourceMappingURL=chunk-KNRE3DG4.js.map
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  LLMError,
19
19
  OpenAIHttpClient
20
- } from "./chunk-7YBGCZSI.js";
20
+ } from "./chunk-XNB3JWAR.js";
21
21
  import {
22
22
  logger
23
23
  } from "./chunk-K44MW7JJ.js";
@@ -268,4 +268,4 @@ function createLLMClient(config, initialBackend = "unknown") {
268
268
  export {
269
269
  createLLMClient
270
270
  };
271
- //# sourceMappingURL=chunk-C56Z4OVW.js.map
271
+ //# sourceMappingURL=chunk-KU3YUGAN.js.map
@@ -163,7 +163,7 @@ async function runCli(options) {
163
163
  break;
164
164
  }
165
165
  case "provider": {
166
- const { runProviderCommand } = await import("./provider-SYYZI2KX.js");
166
+ const { runProviderCommand } = await import("./provider-E5IP7RF7.js");
167
167
  const [, subcommand] = positionals;
168
168
  await runProviderCommand(mode, subcommand);
169
169
  break;
@@ -200,7 +200,7 @@ async function runCli(options) {
200
200
  break;
201
201
  }
202
202
  case "update": {
203
- const { runUpdate } = await import("./update-7ZIRWYSC.js");
203
+ const { runUpdate } = await import("./update-5HWU675H.js");
204
204
  const code = await runUpdate();
205
205
  if (code !== 0) {
206
206
  process.exit(code);
@@ -213,7 +213,7 @@ async function runCli(options) {
213
213
  if (!configExists) {
214
214
  await runNetworkSetup(mode);
215
215
  }
216
- const { runServe } = await import("./serve-OYOC5O4A.js");
216
+ const { runServe } = await import("./serve-NZZVFNMA.js");
217
217
  const serveOptions = { mode };
218
218
  if (values.port) serveOptions.port = parseInt(values.port);
219
219
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -225,4 +225,4 @@ async function runCli(options) {
225
225
  export {
226
226
  runCli
227
227
  };
228
- //# sourceMappingURL=chunk-AKZGFLMD.js.map
228
+ //# sourceMappingURL=chunk-LSDJCJWA.js.map
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  getProject
3
- } from "./chunk-ST4NYXLH.js";
3
+ } from "./chunk-WWFH5GAR.js";
4
4
  import {
5
5
  deleteItemFromDir,
6
6
  loadItemsFromDir,
7
7
  pathExists
8
- } from "./chunk-NGN3Q26A.js";
8
+ } from "./chunk-OHBY2673.js";
9
9
  import {
10
10
  SETTINGS_KEYS,
11
11
  deleteSetting,
12
12
  getSetting,
13
13
  setSetting
14
- } from "./chunk-54Q4TGG6.js";
14
+ } from "./chunk-UEOEA6BB.js";
15
15
 
16
16
  // src/server/context/instructions.ts
17
17
  import { readFile, access } from "fs/promises";
@@ -440,4 +440,4 @@ export {
440
440
  deleteSkill,
441
441
  deleteProjectSkill
442
442
  };
443
- //# sourceMappingURL=chunk-SXHGRPCI.js.map
443
+ //# sourceMappingURL=chunk-MC3MCMAF.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getPlatformShell
3
- } from "./chunk-WWC3R3YL.js";
3
+ } from "./chunk-NLN5LPQ4.js";
4
4
 
5
5
  // src/server/tools/tool-policy.ts
6
6
  var ALWAYS_ALLOWED = /* @__PURE__ */ new Set(["step_done"]);
@@ -123,6 +123,8 @@ NEVER commit changes unless user explicitly asks you to. VERY IMPORTANT only com
123
123
  When doing file search, prefer to use the call_sub_agent tool with the "explorer" in order to reduce context usage, except if this would take less than 3 calls to get the information.
124
124
  You have the capability to call multiple tools in a single response. When multiple independent pieces of information are requested, batch your tool calls together for optimal performance.
125
125
 
126
+ If working on OpenFox itself, repo: https://github.com/co-l/openfox
127
+
126
128
  ${instructionsSection}
127
129
  ${buildSkillsSection(skills)}
128
130
  `;
@@ -243,4 +245,4 @@ export {
243
245
  buildAgentSmallReminder,
244
246
  COMPACTION_PROMPT
245
247
  };
246
- //# sourceMappingURL=chunk-NLJXZZTB.js.map
248
+ //# sourceMappingURL=chunk-MRWR3SIT.js.map
@@ -4,19 +4,19 @@ import {
4
4
  getToolRegistryForAgent,
5
5
  processEventsForConversation,
6
6
  runTopLevelAgentLoop
7
- } from "./chunk-DVVRKNFS.js";
7
+ } from "./chunk-DLCMSSG3.js";
8
8
  import {
9
9
  buildCachedPrompt,
10
10
  computeDynamicContextHash,
11
11
  getToolFingerprint
12
- } from "./chunk-FSLCOA4R.js";
12
+ } from "./chunk-V4QTGYXL.js";
13
13
  import {
14
14
  getAllInstructions,
15
15
  getEnabledSkillMetadata
16
- } from "./chunk-SXHGRPCI.js";
16
+ } from "./chunk-MC3MCMAF.js";
17
17
  import {
18
18
  PathAccessDeniedError
19
- } from "./chunk-WPACSSBS.js";
19
+ } from "./chunk-VYN37NXW.js";
20
20
  import {
21
21
  TurnMetrics,
22
22
  createChatDoneEvent,
@@ -25,21 +25,21 @@ import {
25
25
  import {
26
26
  buildAgentReminder,
27
27
  buildAgentSmallReminder
28
- } from "./chunk-NLJXZZTB.js";
28
+ } from "./chunk-MRWR3SIT.js";
29
29
  import {
30
30
  getCurrentContextWindowId,
31
31
  getCurrentWindowMessageOptions,
32
32
  getEventStore
33
- } from "./chunk-LT4MPTGU.js";
33
+ } from "./chunk-FVV7TZC2.js";
34
34
  import {
35
35
  buildSnapshotFromSessionState
36
- } from "./chunk-AXFPEGJI.js";
36
+ } from "./chunk-P637C6X3.js";
37
37
  import {
38
38
  findAgentById,
39
39
  getRuntimeConfig,
40
40
  loadAllAgentsDefault,
41
41
  resolveDefaultAgentId
42
- } from "./chunk-NGN3Q26A.js";
42
+ } from "./chunk-OHBY2673.js";
43
43
  import {
44
44
  logger
45
45
  } from "./chunk-K44MW7JJ.js";
@@ -49,7 +49,7 @@ import {
49
49
 
50
50
  // src/server/chat/orchestrator.ts
51
51
  async function buildRetryPatterns() {
52
- const { getSetting, SETTINGS_KEYS } = await import("./settings-2OVKFWR5.js");
52
+ const { getSetting, SETTINGS_KEYS } = await import("./settings-2WVGUPYV.js");
53
53
  const raw = getSetting(SETTINGS_KEYS.RETRY_PATTERNS);
54
54
  if (!raw) {
55
55
  const oldXmlProtection = getSetting("llm.disableXmlProtection");
@@ -309,4 +309,4 @@ export {
309
309
  runChatTurn,
310
310
  runAgentTurn
311
311
  };
312
- //# sourceMappingURL=chunk-Q7CN4JOO.js.map
312
+ //# sourceMappingURL=chunk-MUNVSHL5.js.map