openfox 2.0.0-beta.1 → 2.0.0-beta.11

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 (49) hide show
  1. package/dist/agent-defaults/code-reviewer.agent.md +2 -1
  2. package/dist/{chat-handler-IVIWOR3D.js → chat-handler-NMJCOCCB.js} +14 -27
  3. package/dist/{chunk-ZLUBZ4K4.js → chunk-4RLDN2LL.js} +222 -106
  4. package/dist/{chunk-CEZNMLOO.js → chunk-7TTEGAO6.js} +12 -13
  5. package/dist/chunk-BU56QFHW.js +315 -0
  6. package/dist/{chunk-FQLK5GL5.js → chunk-BVHFMAVN.js} +1 -1
  7. package/dist/{chunk-RF2JGDSS.js → chunk-DMH6JVPF.js} +13 -10
  8. package/dist/{chunk-ALH4KM2Y.js → chunk-EQQDA4D3.js} +2967 -3248
  9. package/dist/{chunk-QFSSKIQ3.js → chunk-EXYMWI7A.js} +4 -4
  10. package/dist/{chunk-NNEHZT3V.js → chunk-EZUR7OEP.js} +11 -3
  11. package/dist/{chunk-NONI4CRP.js → chunk-ITWVFGFV.js} +5 -61
  12. package/dist/{chunk-4U4CSRBE.js → chunk-LCRJWUW7.js} +6 -6
  13. package/dist/{chunk-XKR3HCAL.js → chunk-NSBYORD5.js} +177 -34
  14. package/dist/{chunk-PSJIT5LZ.js → chunk-RFNEDBVO.js} +4 -4
  15. package/dist/chunk-RI6GAMNP.js +13 -0
  16. package/dist/{chunk-HHAJ3QF6.js → chunk-UKTPL5ZG.js} +16 -28
  17. package/dist/{chunk-HGAMIPFO.js → chunk-VIIRNJDT.js} +39 -178
  18. package/dist/cli/dev.js +1 -1
  19. package/dist/cli/index.js +1 -1
  20. package/dist/compactor-TDNRM3A7.js +9 -0
  21. package/dist/{config-YU7NYZYG.js → config-TDVA7MQN.js} +9 -8
  22. package/dist/{events-OHJWCI3S.js → events-UGTGGFG3.js} +8 -7
  23. package/dist/{folding-U6UHQAS5.js → folding-YOCGTZYH.js} +2 -2
  24. package/dist/{orchestrator-7ZXM4J22.js → orchestrator-75L5UGDU.js} +18 -22
  25. package/dist/package.json +1 -1
  26. package/dist/{processor-TKBJLQ2N.js → processor-GHESQ2YV.js} +8 -9
  27. package/dist/{protocol-BQ12Aw5J.d.ts → protocol-B9R1CUvt.d.ts} +14 -39
  28. package/dist/{protocol-K62EPEGS.js → protocol-CN24IKQN.js} +3 -5
  29. package/dist/{provider-HTJEB3ON.js → provider-BGH4MBLH.js} +25 -10
  30. package/dist/{serve-5KA6SSSP.js → serve-I6T7V62Z.js} +25 -26
  31. package/dist/server/index.d.ts +1 -6
  32. package/dist/server/index.js +15 -16
  33. package/dist/{settings-VRAOAPLA.js → settings-6XX56F3F.js} +2 -2
  34. package/dist/shared/index.d.ts +2 -2
  35. package/dist/shared/index.js +1 -1
  36. package/dist/{tools-Z7X4HXZN.js → tools-D3WWIOQD.js} +11 -13
  37. package/dist/web/assets/{index-BY8EbT5Z.css → index-CSOB8dwI.css} +1 -1
  38. package/dist/web/assets/index-tJDr1ODC.js +299 -0
  39. package/dist/web/index.html +2 -2
  40. package/dist/web/sw.js +1 -1
  41. package/dist/workflow-defaults/default.workflow.json +9 -4
  42. package/package.json +1 -1
  43. package/dist/auto-compaction-UIWTO3H5.js +0 -27
  44. package/dist/chunk-CGZHLM3K.js +0 -70
  45. package/dist/chunk-SZKEGZIB.js +0 -140
  46. package/dist/chunk-UFY4I643.js +0 -332
  47. package/dist/runtime-config-NPSPMRDA.js +0 -9
  48. package/dist/vision-fallback-3MIZZ6NQ.js +0 -22
  49. package/dist/web/assets/index-CqOJgw7l.js +0 -299
@@ -1,14 +1,19 @@
1
1
  import {
2
- createVerifierNudgeConfig,
3
- runBuilderTurn,
2
+ computeDynamicContextHash,
3
+ injectWorkflowKickoffIfNeeded,
4
+ runAgentTurn,
4
5
  runChatTurn
5
- } from "./chunk-UFY4I643.js";
6
+ } from "./chunk-BU56QFHW.js";
6
7
  import {
8
+ COMPACTION_PROMPT,
7
9
  TurnMetrics,
8
10
  agentExists,
11
+ buildBasePrompt,
9
12
  buildTopLevelSystemPrompt,
10
13
  checkAborted,
11
- computeDynamicContextHash,
14
+ consumeStreamGenerator,
15
+ createChatDoneEvent,
16
+ createMessageDoneEvent,
12
17
  createMessageStartEvent,
13
18
  createToolRegistry,
14
19
  deleteAgent,
@@ -21,6 +26,7 @@ import {
21
26
  findAgentById,
22
27
  findSkillById,
23
28
  getAllInstructions,
29
+ getConversationMessages,
24
30
  getDefaultAgentIds,
25
31
  getDefaultIds,
26
32
  getDefaultSkillIds,
@@ -42,40 +48,24 @@ import {
42
48
  loadProjectSkills,
43
49
  loadUserAgents,
44
50
  loadUserSkills,
51
+ loadVisionModelFromGlobalConfig,
45
52
  pathExists,
46
- performManualContextCompaction,
53
+ processContextImages,
47
54
  saveAgent,
48
55
  saveAgentToProject,
49
56
  saveItemToDir,
50
57
  saveSkill,
51
58
  saveSkillToProject,
52
59
  skillExists,
53
- spawnShellProcess
54
- } from "./chunk-ALH4KM2Y.js";
55
- import {
56
- getProject
57
- } from "./chunk-XAMAYRDA.js";
60
+ spawnShellProcess,
61
+ streamLLMPure
62
+ } from "./chunk-EQQDA4D3.js";
58
63
  import {
59
64
  getPathSeparator,
60
65
  getPlatformShell,
61
66
  isAbsolutePath,
62
67
  onProcessEvent
63
68
  } from "./chunk-PBGOZMVY.js";
64
- import {
65
- createProviderManager,
66
- parseDefaultModelSelection
67
- } from "./chunk-RF2JGDSS.js";
68
- import {
69
- SessionNotFoundError,
70
- createLLMClient,
71
- detectModel,
72
- getLlmStatus
73
- } from "./chunk-HHAJ3QF6.js";
74
- import {
75
- detectBackend,
76
- getBackendDisplayName,
77
- getModelProfile
78
- } from "./chunk-HGAMIPFO.js";
79
69
  import {
80
70
  createSession,
81
71
  deleteSession,
@@ -91,24 +81,24 @@ import {
91
81
  emitSessionInitialized,
92
82
  emitUserMessage,
93
83
  getCurrentContextWindowId,
84
+ getCurrentWindowMessageOptions,
94
85
  getEventStore,
86
+ getRuntimeConfig,
95
87
  getSession,
96
88
  getSessionState,
97
89
  initEventStore,
98
90
  listSessions,
99
91
  listSessionsByProject,
92
+ setRuntimeConfig,
100
93
  updateSessionDangerLevel,
101
94
  updateSessionMetadata,
102
95
  updateSessionProvider,
103
96
  updateSessionRunning
104
- } from "./chunk-XKR3HCAL.js";
105
- import {
106
- initDatabase
107
- } from "./chunk-FBGWG4N6.js";
97
+ } from "./chunk-NSBYORD5.js";
108
98
  import {
109
99
  buildMessagesFromStoredEvents,
110
100
  foldPendingConfirmations
111
- } from "./chunk-NONI4CRP.js";
101
+ } from "./chunk-ITWVFGFV.js";
112
102
  import {
113
103
  createChatErrorMessage,
114
104
  createChatMessageMessage,
@@ -123,28 +113,47 @@ import {
123
113
  parseClientMessage,
124
114
  serializeServerMessage,
125
115
  storedEventToServerMessage
126
- } from "./chunk-CEZNMLOO.js";
116
+ } from "./chunk-7TTEGAO6.js";
127
117
  import {
128
118
  EventEmitter,
129
119
  provideAnswer
130
120
  } from "./chunk-BJYPTN5S.js";
121
+ import {
122
+ getProject
123
+ } from "./chunk-XAMAYRDA.js";
124
+ import {
125
+ initDatabase
126
+ } from "./chunk-FBGWG4N6.js";
131
127
  import {
132
128
  computeSessionStats
133
129
  } from "./chunk-VUQCQXXJ.js";
134
130
  import {
135
131
  createServerMessage
136
- } from "./chunk-FQLK5GL5.js";
132
+ } from "./chunk-BVHFMAVN.js";
137
133
  import {
138
- getGlobalConfigDir
139
- } from "./chunk-CQGTEGKL.js";
134
+ createProviderManager,
135
+ parseDefaultModelSelection
136
+ } from "./chunk-DMH6JVPF.js";
140
137
  import {
141
- getRuntimeConfig,
142
- setRuntimeConfig
143
- } from "./chunk-CGZHLM3K.js";
138
+ SessionNotFoundError,
139
+ createLLMClient,
140
+ detectModel,
141
+ getLlmStatus
142
+ } from "./chunk-UKTPL5ZG.js";
143
+ import {
144
+ detectBackend,
145
+ ensureVersionPrefix,
146
+ getBackendDisplayName,
147
+ getModelProfile,
148
+ modelSupportsVision
149
+ } from "./chunk-VIIRNJDT.js";
144
150
  import {
145
151
  logger,
146
152
  setLogLevel
147
153
  } from "./chunk-K44MW7JJ.js";
154
+ import {
155
+ getGlobalConfigDir
156
+ } from "./chunk-CQGTEGKL.js";
148
157
 
149
158
  // src/server/index.ts
150
159
  import express from "express";
@@ -2041,7 +2050,7 @@ function emitWorkflowMessage(eventStore, sessionId, content, windowOptions, onMe
2041
2050
  }
2042
2051
  return msgId;
2043
2052
  }
2044
- function getCurrentWindowMessageOptions(sessionId) {
2053
+ function getCurrentWindowMessageOptions2(sessionId) {
2045
2054
  const contextWindowId = getCurrentContextWindowId(sessionId);
2046
2055
  return contextWindowId ? { contextWindowId } : void 0;
2047
2056
  }
@@ -2050,17 +2059,19 @@ function buildReason(metadataEntries) {
2050
2059
  const remaining = entries.filter((e) => e.status !== "passed");
2051
2060
  return `${remaining.length} criteria remaining`;
2052
2061
  }
2053
- async function executeWorkflow(workflow, options) {
2062
+ async function executeWorkflow(workflow, options, subGroup) {
2054
2063
  const { sessionManager, sessionId, llmClient, signal, onMessage } = options;
2055
2064
  const eventStore = getEventStore();
2056
2065
  const startTime = performance.now();
2057
2066
  let iterations = 0;
2058
- let currentStepId = workflow.entryStep;
2067
+ const activeSteps = subGroup ? workflow.steps.filter((s) => s.subGroup === subGroup) : workflow.steps;
2068
+ let currentStepId = subGroup ? activeSteps[0]?.id ?? workflow.entryStep : workflow.entryStep;
2059
2069
  let lastStepOutput = {};
2060
2070
  const firstEntryForStep = /* @__PURE__ */ new Set();
2061
2071
  const messagesBeforeWorkflow = sessionManager.requireSession(sessionId).messages.length;
2072
+ const activeStepIds = new Set(activeSteps.map((s) => s.id));
2062
2073
  const stepsById = /* @__PURE__ */ new Map();
2063
- for (const step of workflow.steps) {
2074
+ for (const step of activeSteps) {
2064
2075
  stepsById.set(step.id, step);
2065
2076
  }
2066
2077
  logger.debug("Workflow executor starting", { sessionId, workflow: workflow.metadata.id });
@@ -2085,7 +2096,7 @@ async function executeWorkflow(workflow, options) {
2085
2096
  }
2086
2097
  }
2087
2098
  const startMsgId = crypto.randomUUID();
2088
- const startWindowOpts = getCurrentWindowMessageOptions(sessionId);
2099
+ const startWindowOpts = getCurrentWindowMessageOptions2(sessionId);
2089
2100
  eventStore.append(
2090
2101
  sessionId,
2091
2102
  createMessageStartEvent(
@@ -2127,7 +2138,7 @@ async function executeWorkflow(workflow, options) {
2127
2138
  };
2128
2139
  }
2129
2140
  const session = sessionManager.requireSession(sessionId);
2130
- const currentWindowMessageOptions = getCurrentWindowMessageOptions(sessionId);
2141
+ const currentWindowMessageOptions = getCurrentWindowMessageOptions2(sessionId);
2131
2142
  const criteriaEntries = session.metadataEntries["criteria"] ?? [];
2132
2143
  const templateCtx = {
2133
2144
  workdir: session.workdir,
@@ -2189,22 +2200,36 @@ async function executeWorkflow(workflow, options) {
2189
2200
  emitWorkflowMessage(eventStore, sessionId, nudgeContent, currentWindowMessageOptions, onMessage);
2190
2201
  }
2191
2202
  const turnMetrics = new TurnMetrics();
2192
- const agentResult = await runBuilderTurn(
2203
+ const es = getEventStore();
2204
+ const append = (event) => es.append(sessionId, event);
2205
+ let stepDoneCalled = false;
2206
+ const agentResult = await runAgentTurn(
2193
2207
  {
2194
2208
  sessionManager,
2195
2209
  sessionId,
2196
2210
  llmClient,
2197
- injectStepDone: true,
2198
2211
  ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
2199
- ...!firstEntryForStep.has(step.id) && !agentStep.prompt && options.injectBuilderKickoff === true ? { injectBuilderKickoff: true } : {},
2200
2212
  ...signal ? { signal } : {},
2201
2213
  ...onMessage ? { onMessage } : {}
2202
2214
  },
2203
- turnMetrics
2215
+ turnMetrics,
2216
+ agentStep.agentId ?? "planner",
2217
+ append,
2218
+ {
2219
+ ...!firstEntryForStep.has(step.id) && !agentStep.prompt && options.injectWorkflowKickoff === true ? { injectKickoff: () => injectWorkflowKickoffIfNeeded(sessionManager, sessionId, es) } : {},
2220
+ onToolExecuted: (toolCall, toolResult) => {
2221
+ if (toolCall.name === "step_done" && toolResult.success) {
2222
+ stepDoneCalled = true;
2223
+ }
2224
+ if (toolResult.success && ["write_file", "edit_file"].includes(toolCall.name)) {
2225
+ const path = toolCall.arguments["path"];
2226
+ sessionManager.addModifiedFile(sessionId, path);
2227
+ }
2228
+ }
2229
+ }
2204
2230
  );
2205
2231
  firstEntryForStep.add(step.id);
2206
2232
  const agentReturnValue = agentResult.returnValueResult ?? "completed";
2207
- const stepDoneCalled = agentResult.stepDoneCalled ?? false;
2208
2233
  lastStepOutput = {
2209
2234
  ...agentResult.returnValueContent ? { content: agentResult.returnValueContent } : {},
2210
2235
  ...agentResult.returnValueResult ? { result: agentResult.returnValueResult } : {},
@@ -2239,7 +2264,6 @@ async function executeWorkflow(workflow, options) {
2239
2264
  definitions: toolRegistry.definitions.filter((d) => d.type === "function" && d.function.name !== "step_done"),
2240
2265
  execute: toolRegistry.execute
2241
2266
  };
2242
- const nudgeConfig = subStep.subAgentType === "verifier" && !subStep.nudgePrompt ? createVerifierNudgeConfig() : void 0;
2243
2267
  const result = await executeSubAgent({
2244
2268
  subAgentType: subStep.subAgentType,
2245
2269
  prompt: resolvedPrompt,
@@ -2255,8 +2279,7 @@ async function executeWorkflow(workflow, options) {
2255
2279
  model: llmClient.getModel()
2256
2280
  },
2257
2281
  ...signal ? { signal } : {},
2258
- ...onMessage ? { onMessage } : {},
2259
- nudgeConfig
2282
+ ...onMessage ? { onMessage } : {}
2260
2283
  });
2261
2284
  lastStepOutput = { content: result.content ?? "", ...result.result ? { result: result.result } : {} };
2262
2285
  stepOutcome = { result: result.result ?? "success", output: lastStepOutput };
@@ -2325,7 +2348,9 @@ ${output.slice(0, 1e4)}
2325
2348
  }
2326
2349
  }
2327
2350
  const refreshedSession = sessionManager.requireSession(sessionId);
2328
- const nextStepId = evaluateTransitions(step.transitions, stepOutcome, refreshedSession.metadataEntries);
2351
+ const effectiveTransitions = subGroup ? step.transitions.filter((t) => !t.subGroup || t.subGroup === subGroup) : step.transitions;
2352
+ const rawNextStepId = evaluateTransitions(effectiveTransitions, stepOutcome, refreshedSession.metadataEntries);
2353
+ const nextStepId = subGroup && rawNextStepId !== TERMINAL_DONE && rawNextStepId !== TERMINAL_BLOCKED && !activeStepIds.has(rawNextStepId) ? TERMINAL_DONE : rawNextStepId;
2329
2354
  if (nextStepId === TERMINAL_DONE) {
2330
2355
  sessionManager.setPhase(sessionId, "done");
2331
2356
  const totalTimeSeconds = Math.round((performance.now() - startTime) / 100) / 10;
@@ -2402,8 +2427,82 @@ async function runOrchestrator(options) {
2402
2427
  if (!workflow) {
2403
2428
  throw new Error(`Workflow "${workflowId}" not found`);
2404
2429
  }
2405
- logger.debug("Using workflow executor", { sessionId: options.sessionId, workflow: workflow.metadata.id });
2406
- return executeWorkflow(workflow, options);
2430
+ logger.debug("Using workflow executor", {
2431
+ sessionId: options.sessionId,
2432
+ workflow: workflow.metadata.id,
2433
+ subGroup: options.subGroup
2434
+ });
2435
+ return executeWorkflow(workflow, options, options.subGroup);
2436
+ }
2437
+
2438
+ // src/server/context/auto-compaction.ts
2439
+ async function compactContext(options) {
2440
+ const { sessionManager, sessionId, llmClient, signal } = options;
2441
+ const eventStore = getEventStore();
2442
+ const session = sessionManager.requireSession(sessionId);
2443
+ const compactPromptMsgId = crypto.randomUUID();
2444
+ eventStore.append(
2445
+ sessionId,
2446
+ createMessageStartEvent(compactPromptMsgId, "user", COMPACTION_PROMPT, {
2447
+ ...getCurrentWindowMessageOptions(sessionId) ?? {},
2448
+ isSystemGenerated: true,
2449
+ messageKind: "auto-prompt",
2450
+ metadata: { type: "compaction", name: "Compaction", color: "#64748b" }
2451
+ })
2452
+ );
2453
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: compactPromptMsgId } });
2454
+ const rawEvents = eventStore.getEvents(sessionId);
2455
+ const modelVision = modelSupportsVision(llmClient.getModel());
2456
+ const runtimeConfig = getRuntimeConfig();
2457
+ const visionModel = runtimeConfig.llm.visionModel ? { baseUrl: runtimeConfig.llm.baseUrl, model: runtimeConfig.llm.visionModel, timeout: runtimeConfig.llm.timeout } : await loadVisionModelFromGlobalConfig();
2458
+ const { events: processedEvents } = await processContextImages(rawEvents, {
2459
+ modelSupportsVision: modelVision,
2460
+ ...visionModel ? { visionModel } : {},
2461
+ onEvent: (event) => eventStore.append(sessionId, event)
2462
+ });
2463
+ const messages = getConversationMessages({ type: "toplevel", sessionId }, { events: processedEvents });
2464
+ const systemPrompt = buildBasePrompt(session.workdir);
2465
+ const assistantMsgId = crypto.randomUUID();
2466
+ const streamGen = streamLLMPure({
2467
+ messageId: assistantMsgId,
2468
+ systemPrompt,
2469
+ llmClient,
2470
+ messages,
2471
+ tools: [],
2472
+ toolChoice: "none",
2473
+ signal
2474
+ });
2475
+ const result = await consumeStreamGenerator(streamGen, (event) => {
2476
+ eventStore.append(sessionId, event);
2477
+ });
2478
+ const summary = result.content?.trim() || result.thinkingContent?.trim() || "";
2479
+ if (!summary) {
2480
+ eventStore.append(sessionId, {
2481
+ type: "chat.error",
2482
+ data: { error: "Compaction produced empty summary, continuing with full context", recoverable: true }
2483
+ });
2484
+ logger.warn("Compaction produced empty summary", { sessionId });
2485
+ return;
2486
+ }
2487
+ const closedWindowId = getCurrentContextWindowId(sessionId) ?? "";
2488
+ const newWindowId = crypto.randomUUID();
2489
+ eventStore.append(sessionId, {
2490
+ type: "context.compacted",
2491
+ data: { closedWindowId, newWindowId, beforeTokens: result.usage.promptTokens, afterTokens: 0, summary }
2492
+ });
2493
+ eventStore.append(sessionId, {
2494
+ type: "message.start",
2495
+ data: {
2496
+ messageId: assistantMsgId,
2497
+ role: "assistant",
2498
+ content: summary,
2499
+ contextWindowId: newWindowId,
2500
+ isCompactionSummary: true
2501
+ }
2502
+ });
2503
+ eventStore.append(sessionId, createMessageDoneEvent(assistantMsgId, {}));
2504
+ eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "complete"));
2505
+ logger.info("Manual compaction complete", { sessionId });
2407
2506
  }
2408
2507
 
2409
2508
  // src/server/auth.ts
@@ -2745,7 +2844,7 @@ function createWebSocketServer(httpServer, config4, getLLMClient, getActiveProvi
2745
2844
  sessionLLMClients.delete(sessionId);
2746
2845
  return getLLMClient();
2747
2846
  }
2748
- const baseUrl = provider.url.includes("/v1") ? provider.url : `${provider.url}/v1`;
2847
+ const baseUrl = ensureVersionPrefix(provider.url);
2749
2848
  const sessionConfig = {
2750
2849
  ...config4,
2751
2850
  llm: {
@@ -2854,7 +2953,6 @@ function createWebSocketServer(httpServer, config4, getLLMClient, getActiveProvi
2854
2953
  return;
2855
2954
  }
2856
2955
  sessionManager.clearMessageQueue(sessionId);
2857
- sessionManager.setRunning(sessionId, false);
2858
2956
  const contextState = sessionManager.getContextState(sessionId);
2859
2957
  sendFn(sessionId, createContextStateMessage(contextState));
2860
2958
  }
@@ -3149,17 +3247,14 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
3149
3247
  send(createErrorMessage("SESSION_RUNNING", "Cannot compact while session is running", message.id));
3150
3248
  return;
3151
3249
  }
3152
- const contextState = sessionManager.getContextState(sessionId);
3153
- const tokensBefore = contextState.currentTokens;
3154
3250
  send({ type: "ack", payload: {}, id: message.id });
3155
3251
  (async () => {
3156
3252
  try {
3157
- await performManualContextCompaction({
3253
+ await compactContext({
3158
3254
  sessionManager,
3159
3255
  sessionId,
3160
3256
  llmClient: llmForSession(sessionId),
3161
- statsIdentity: statsForSession(sessionId),
3162
- tokenCountAtClose: tokensBefore
3257
+ statsIdentity: statsForSession(sessionId)
3163
3258
  });
3164
3259
  const newContextState = sessionManager.getContextState(sessionId);
3165
3260
  sendForSession(sessionId, createContextStateMessage(newContextState));
@@ -3294,10 +3389,6 @@ ${content}` : workflowInfo;
3294
3389
  });
3295
3390
  return;
3296
3391
  }
3297
- if (session.mode !== "builder") {
3298
- send(createErrorMessage("INVALID_MODE", "Runner can only be launched in builder mode", message.id));
3299
- return;
3300
- }
3301
3392
  const launchPayloadEarly = message.payload;
3302
3393
  const pendingCriteria = session.criteria.filter((c) => c.status.type !== "passed");
3303
3394
  if (!launchPayloadEarly?.workflowId && pendingCriteria.length === 0) {
@@ -3331,8 +3422,9 @@ ${content}` : workflowInfo;
3331
3422
  sessionId,
3332
3423
  llmClient: llmForSession(sessionId),
3333
3424
  statsIdentity: statsForSession(sessionId),
3334
- injectBuilderKickoff: !hasUserMessage,
3425
+ injectWorkflowKickoff: !hasUserMessage,
3335
3426
  ...launchPayload?.workflowId ? { workflowId: launchPayload.workflowId } : {},
3427
+ ...launchPayload?.subGroup ? { subGroup: launchPayload.subGroup } : {},
3336
3428
  ...hasUserMessage ? {
3337
3429
  userMessage: {
3338
3430
  content: hasUserContent ? launchPayload.content : "",
@@ -3348,6 +3440,8 @@ ${content}` : workflowInfo;
3348
3440
  }
3349
3441
  logger.error("Runner error", { error, sessionId });
3350
3442
  }).finally(() => {
3443
+ sessionManager.setRunning(sessionId, false);
3444
+ sendForSession(sessionId, createSessionRunningMessage(false));
3351
3445
  cleanupAfterTurn(sessionId, controller, sendForSession, true);
3352
3446
  });
3353
3447
  break;
@@ -4747,7 +4841,6 @@ var SessionManager = class {
4747
4841
  if (m.isSystemGenerated !== void 0) msg.isSystemGenerated = m.isSystemGenerated;
4748
4842
  if (m.messageKind !== void 0) msg.messageKind = m.messageKind;
4749
4843
  if (m.isCompactionSummary !== void 0) msg.isCompactionSummary = m.isCompactionSummary;
4750
- if (m.promptContext !== void 0) msg.promptContext = m.promptContext;
4751
4844
  return msg;
4752
4845
  });
4753
4846
  }
@@ -5165,7 +5258,6 @@ ${summary}`,
5165
5258
  if (m.messageKind !== void 0) msg.messageKind = m.messageKind;
5166
5259
  if (m.contextWindowId !== void 0) msg.contextWindowId = m.contextWindowId;
5167
5260
  if (m.isCompactionSummary !== void 0) msg.isCompactionSummary = m.isCompactionSummary;
5168
- if (m.promptContext !== void 0) msg.promptContext = m.promptContext;
5169
5261
  return msg;
5170
5262
  });
5171
5263
  const isRunning = dbSession.isRunning;
@@ -5190,8 +5282,7 @@ ${summary}`,
5190
5282
  metadataEntries: eventState.metadataEntries,
5191
5283
  contextWindows: [],
5192
5284
  // Derived from events, not stored separately
5193
- executionState: eventState.lastModeWithReminder || eventState.cachedSystemPrompt || hasCachedPrompt ? {
5194
- lastModeWithReminder: eventState.lastModeWithReminder,
5285
+ executionState: eventState.cachedSystemPrompt || hasCachedPrompt ? {
5195
5286
  cachedSystemPrompt: cachedData?.systemPrompt ?? eventState.cachedSystemPrompt,
5196
5287
  dynamicContextHash: cachedData?.hash ?? eventState.dynamicContextHash
5197
5288
  } : null
@@ -5558,10 +5649,14 @@ function createWorkflowRoutes(configDir, config4, projectDir) {
5558
5649
  if (!Array.isArray(steps) || steps.length === 0) return "Missing required fields: metadata.id, steps";
5559
5650
  return null;
5560
5651
  },
5561
- mapToResponse: (w) => ({
5562
- ...w.metadata,
5563
- startCondition: w.startCondition
5564
- }),
5652
+ mapToResponse: (w) => {
5653
+ const subGroups = [...new Set(w.steps.map((s) => s.subGroup).filter(Boolean))];
5654
+ return {
5655
+ ...w.metadata,
5656
+ startCondition: w.startCondition,
5657
+ subGroups: subGroups.length > 0 ? subGroups : void 0
5658
+ };
5659
+ },
5565
5660
  extraGetData: () => Promise.resolve({ activeWorkflowId: config4.activeWorkflowId ?? "default" }),
5566
5661
  extraRoutes: (router) => {
5567
5662
  router.get("/template-variables", (_req, res) => {
@@ -5735,7 +5830,7 @@ import { Router as Router6 } from "express";
5735
5830
  import { spawn as spawn5 } from "child_process";
5736
5831
 
5737
5832
  // src/constants.ts
5738
- var VERSION = "2.0.0-beta.1";
5833
+ var VERSION = "2.0.0-beta.11";
5739
5834
 
5740
5835
  // src/server/routes/auto-update.ts
5741
5836
  var updateInProgress = false;
@@ -6038,7 +6133,7 @@ async function createServerHandle(config4) {
6038
6133
  res.json({ project });
6039
6134
  });
6040
6135
  app.get("/api/sessions", async (req, res) => {
6041
- const { getRecentUserPromptsForSession } = await import("./events-OHJWCI3S.js");
6136
+ const { getRecentUserPromptsForSession } = await import("./events-UGTGGFG3.js");
6042
6137
  const projectId = req.query["projectId"];
6043
6138
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
6044
6139
  const offset = parseInt(req.query["offset"]) || 0;
@@ -6071,8 +6166,8 @@ async function createServerHandle(config4) {
6071
6166
  res.status(201).json({ session });
6072
6167
  });
6073
6168
  app.get("/api/sessions/:id", async (req, res) => {
6074
- const { getEventStore: getEventStore2 } = await import("./events-OHJWCI3S.js");
6075
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-U6UHQAS5.js");
6169
+ const { getEventStore: getEventStore2 } = await import("./events-UGTGGFG3.js");
6170
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-YOCGTZYH.js");
6076
6171
  const session = sessionManager.getSession(req.params.id);
6077
6172
  if (!session) {
6078
6173
  return res.status(404).json({ error: "Session not found" });
@@ -6102,8 +6197,8 @@ async function createServerHandle(config4) {
6102
6197
  res.json({ success: true });
6103
6198
  });
6104
6199
  app.post("/api/sessions/:id/provider", async (req, res) => {
6105
- const { getEventStore: getEventStore2 } = await import("./events-OHJWCI3S.js");
6106
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-U6UHQAS5.js");
6200
+ const { getEventStore: getEventStore2 } = await import("./events-UGTGGFG3.js");
6201
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-YOCGTZYH.js");
6107
6202
  const sessionId = req.params.id;
6108
6203
  const session = sessionManager.getSession(sessionId);
6109
6204
  if (!session) {
@@ -6114,7 +6209,7 @@ async function createServerHandle(config4) {
6114
6209
  return res.status(400).json({ error: "providerId is required" });
6115
6210
  }
6116
6211
  sessionManager.setSessionProvider(sessionId, providerId, model ?? "auto");
6117
- const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-YU7NYZYG.js");
6212
+ const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-TDVA7MQN.js");
6118
6213
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6119
6214
  const updatedConfig = setDefaultModelSelection(globalConfig, providerId, model ?? "auto");
6120
6215
  await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
@@ -6145,8 +6240,8 @@ async function createServerHandle(config4) {
6145
6240
  res.json({ success: true });
6146
6241
  });
6147
6242
  app.put("/api/sessions/:id/mode", async (req, res) => {
6148
- const { getEventStore: getEventStore2 } = await import("./events-OHJWCI3S.js");
6149
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-U6UHQAS5.js");
6243
+ const { getEventStore: getEventStore2 } = await import("./events-UGTGGFG3.js");
6244
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-YOCGTZYH.js");
6150
6245
  const sessionId = req.params.id;
6151
6246
  const session = sessionManager.getSession(sessionId);
6152
6247
  if (!session) {
@@ -6202,14 +6297,14 @@ async function createServerHandle(config4) {
6202
6297
  if (!callId || approved === void 0) {
6203
6298
  return res.status(400).json({ error: "callId and approved are required" });
6204
6299
  }
6205
- const { providePathConfirmation } = await import("./tools-Z7X4HXZN.js");
6300
+ const { providePathConfirmation } = await import("./tools-D3WWIOQD.js");
6206
6301
  const result = providePathConfirmation(callId, approved, alwaysAllow);
6207
6302
  if (!result.found) {
6208
6303
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
6209
6304
  }
6210
- const { getEventStore: getEventStore2 } = await import("./events-OHJWCI3S.js");
6211
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-U6UHQAS5.js");
6212
- const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-K62EPEGS.js");
6305
+ const { getEventStore: getEventStore2 } = await import("./events-UGTGGFG3.js");
6306
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-YOCGTZYH.js");
6307
+ const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-CN24IKQN.js");
6213
6308
  const eventStore = getEventStore2();
6214
6309
  const events = eventStore.getEvents(sessionId);
6215
6310
  const messages = buildMessagesFromStoredEvents2(events);
@@ -6226,7 +6321,7 @@ async function createServerHandle(config4) {
6226
6321
  if (!callId || !answer) {
6227
6322
  return res.status(400).json({ error: "callId and answer are required" });
6228
6323
  }
6229
- const { provideAnswer: provideAnswer2 } = await import("./tools-Z7X4HXZN.js");
6324
+ const { provideAnswer: provideAnswer2 } = await import("./tools-D3WWIOQD.js");
6230
6325
  const found = provideAnswer2(callId, answer);
6231
6326
  if (!found) {
6232
6327
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -6262,14 +6357,14 @@ async function createServerHandle(config4) {
6262
6357
  if (!session) {
6263
6358
  return res.status(404).json({ error: "Session not found" });
6264
6359
  }
6265
- const { stopSessionExecution } = await import("./chat-handler-IVIWOR3D.js");
6266
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-Z7X4HXZN.js");
6360
+ const { stopSessionExecution } = await import("./chat-handler-NMJCOCCB.js");
6361
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-D3WWIOQD.js");
6267
6362
  stopSessionExecution(sessionId, sessionManager);
6268
6363
  abortSession(sessionId);
6269
6364
  cancelQuestionsForSession(sessionId, "Session stopped by user");
6270
6365
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
6271
6366
  sessionManager.clearMessageQueue(sessionId);
6272
- const eventStore = (await import("./events-OHJWCI3S.js")).getEventStore();
6367
+ const eventStore = (await import("./events-UGTGGFG3.js")).getEventStore();
6273
6368
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
6274
6369
  res.json({ success: true });
6275
6370
  });
@@ -6283,7 +6378,7 @@ async function createServerHandle(config4) {
6283
6378
  if (typeof messageIndex !== "number" || messageIndex < 0) {
6284
6379
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
6285
6380
  }
6286
- const { truncateSessionMessages } = await import("./events-OHJWCI3S.js");
6381
+ const { truncateSessionMessages } = await import("./events-UGTGGFG3.js");
6287
6382
  truncateSessionMessages(sessionId, messageIndex);
6288
6383
  res.json({ success: true });
6289
6384
  });
@@ -6301,7 +6396,7 @@ async function createServerHandle(config4) {
6301
6396
  if (!msg) {
6302
6397
  return res.status(400).json({ error: "Message not found at this index" });
6303
6398
  }
6304
- const { truncateSessionMessages } = await import("./events-OHJWCI3S.js");
6399
+ const { truncateSessionMessages } = await import("./events-UGTGGFG3.js");
6305
6400
  truncateSessionMessages(sessionId, messageIndex - 1);
6306
6401
  sessionManager.queueMessage(sessionId, "asap", msg.content, msg.attachments, msg.messageKind);
6307
6402
  res.json({ success: true });
@@ -6333,7 +6428,7 @@ async function createServerHandle(config4) {
6333
6428
  res.json({ accepted: true });
6334
6429
  });
6335
6430
  app.get("/api/settings", async (req, res) => {
6336
- const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-VRAOAPLA.js");
6431
+ const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-6XX56F3F.js");
6337
6432
  const keysParam = req.query["keys"];
6338
6433
  if (!keysParam) {
6339
6434
  return res.status(400).json({ error: "keys query parameter is required" });
@@ -6346,19 +6441,19 @@ async function createServerHandle(config4) {
6346
6441
  res.json(result);
6347
6442
  });
6348
6443
  app.get("/api/settings/:key", async (req, res) => {
6349
- const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-VRAOAPLA.js");
6444
+ const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-6XX56F3F.js");
6350
6445
  const key = req.params.key;
6351
6446
  const value = getSetting(key) ?? SETTINGS_DEFAULTS[key] ?? null;
6352
6447
  res.json({ key, value });
6353
6448
  });
6354
6449
  app.get("/api/settings/:key", async (req, res) => {
6355
- const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-VRAOAPLA.js");
6450
+ const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-6XX56F3F.js");
6356
6451
  const key = req.params.key;
6357
6452
  const value = getSetting(key) ?? SETTINGS_DEFAULTS[key] ?? null;
6358
6453
  res.json({ key, value });
6359
6454
  });
6360
6455
  app.put("/api/settings/:key", async (req, res) => {
6361
- const { setSetting } = await import("./settings-VRAOAPLA.js");
6456
+ const { setSetting } = await import("./settings-6XX56F3F.js");
6362
6457
  const key = req.params.key;
6363
6458
  const { value } = req.body;
6364
6459
  if (value === void 0) {
@@ -6373,7 +6468,7 @@ async function createServerHandle(config4) {
6373
6468
  let visionFallback;
6374
6469
  let globalWorkdir;
6375
6470
  try {
6376
- const { loadGlobalConfig, getVisionFallback } = await import("./config-YU7NYZYG.js");
6471
+ const { loadGlobalConfig, getVisionFallback } = await import("./config-TDVA7MQN.js");
6377
6472
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6378
6473
  const fallback = getVisionFallback(globalConfig);
6379
6474
  if (fallback) {
@@ -6447,12 +6542,12 @@ async function createServerHandle(config4) {
6447
6542
  }
6448
6543
  });
6449
6544
  app.post("/api/providers", async (req, res) => {
6450
- const { name, url, backend, apiKey, model } = req.body;
6545
+ const { name, url, backend, apiKey, model, isLocal } = req.body;
6451
6546
  if (!name || !url || !backend) {
6452
6547
  return res.status(400).json({ error: "name, url, and backend are required" });
6453
6548
  }
6454
6549
  try {
6455
- const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-YU7NYZYG.js");
6550
+ const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-TDVA7MQN.js");
6456
6551
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6457
6552
  const providerBackend = backend;
6458
6553
  const configWithProvider = addProvider(globalConfig, {
@@ -6460,6 +6555,7 @@ async function createServerHandle(config4) {
6460
6555
  url,
6461
6556
  backend: providerBackend,
6462
6557
  apiKey,
6558
+ ...isLocal !== void 0 ? { isLocal } : {},
6463
6559
  models: model ? [{ id: model, contextWindow: 2e5, source: "user" }] : [],
6464
6560
  isActive: true
6465
6561
  });
@@ -6485,7 +6581,7 @@ async function createServerHandle(config4) {
6485
6581
  app.post("/api/init/config", async (req, res) => {
6486
6582
  const { workdir, visionFallback } = req.body;
6487
6583
  try {
6488
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-YU7NYZYG.js");
6584
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-TDVA7MQN.js");
6489
6585
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6490
6586
  const updatedConfig = {
6491
6587
  ...globalConfig,
@@ -6513,13 +6609,33 @@ async function createServerHandle(config4) {
6513
6609
  });
6514
6610
  app.delete("/api/providers/:id", async (req, res) => {
6515
6611
  const { id } = req.params;
6516
- const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-YU7NYZYG.js");
6612
+ const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-TDVA7MQN.js");
6517
6613
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6518
6614
  const updatedConfig = removeProvider(globalConfig, id);
6519
6615
  await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
6520
6616
  providerManager.setProviders(updatedConfig.providers, updatedConfig.defaultModelSelection ?? void 0);
6521
6617
  res.json({ success: true });
6522
6618
  });
6619
+ app.patch("/api/providers/:id", async (req, res) => {
6620
+ const { id } = req.params;
6621
+ const { isLocal } = req.body;
6622
+ try {
6623
+ const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-TDVA7MQN.js");
6624
+ const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6625
+ const provider = globalConfig.providers.find((p) => p.id === id);
6626
+ if (!provider) {
6627
+ return res.status(404).json({ error: "Provider not found" });
6628
+ }
6629
+ const updates = {};
6630
+ if (isLocal !== void 0) updates["isLocal"] = isLocal;
6631
+ const updatedConfig = updateProvider(globalConfig, id, updates);
6632
+ await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
6633
+ providerManager.setProviders(updatedConfig.providers, updatedConfig.defaultModelSelection ?? void 0);
6634
+ res.json({ success: true, provider: updatedConfig.providers.find((p) => p.id === id) });
6635
+ } catch (error) {
6636
+ res.status(500).json({ error: error instanceof Error ? error.message : "Failed to update provider" });
6637
+ }
6638
+ });
6523
6639
  app.get("/api/providers/:id/models", async (req, res) => {
6524
6640
  const { id } = req.params;
6525
6641
  const models = await providerManager.getProviderModels(id);
@@ -6533,7 +6649,7 @@ async function createServerHandle(config4) {
6533
6649
  return res.status(400).json({ error: result.error });
6534
6650
  }
6535
6651
  const llmClient = getLLMClient();
6536
- const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-YU7NYZYG.js");
6652
+ const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-TDVA7MQN.js");
6537
6653
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6538
6654
  const updatedConfig = setDefaultModelSelection(globalConfig, id, llmClient.getModel());
6539
6655
  await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
@@ -6564,7 +6680,7 @@ async function createServerHandle(config4) {
6564
6680
  if (!result.success) {
6565
6681
  return res.status(400).json({ error: result.error });
6566
6682
  }
6567
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-YU7NYZYG.js");
6683
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-TDVA7MQN.js");
6568
6684
  const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
6569
6685
  const updatedProviders = providerManager.getProviders();
6570
6686
  const updatedConfig = {
@@ -6778,7 +6894,7 @@ async function createServerHandle(config4) {
6778
6894
  providerManager
6779
6895
  );
6780
6896
  const wss = wssExports.wss;
6781
- const { QueueProcessor } = await import("./processor-TKBJLQ2N.js");
6897
+ const { QueueProcessor } = await import("./processor-GHESQ2YV.js");
6782
6898
  const queueProcessor = new QueueProcessor({
6783
6899
  sessionManager,
6784
6900
  providerManager,
@@ -6850,4 +6966,4 @@ export {
6850
6966
  createServerHandle,
6851
6967
  createServer
6852
6968
  };
6853
- //# sourceMappingURL=chunk-ZLUBZ4K4.js.map
6969
+ //# sourceMappingURL=chunk-4RLDN2LL.js.map