openfox 1.6.45 → 1.6.47

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 (32) hide show
  1. package/dist/{auto-compaction-2AI46SNC.js → auto-compaction-7RDQVOYK.js} +6 -6
  2. package/dist/{chat-handler-ITVOWLJR.js → chat-handler-TTCW7DIB.js} +10 -10
  3. package/dist/{chunk-SMK6HIR5.js → chunk-22JBSK6P.js} +23 -42
  4. package/dist/{chunk-RB576RLK.js → chunk-4DR3WUVA.js} +99 -60
  5. package/dist/{chunk-BF7JQWEL.js → chunk-BHSTSA7U.js} +4 -4
  6. package/dist/{chunk-HSSXBW6N.js → chunk-DZHZ3UUR.js} +14 -2
  7. package/dist/{chunk-G6JKXYFE.js → chunk-LIMBYVO4.js} +58 -1
  8. package/dist/{chunk-FBUTQPJ6.js → chunk-NBBX64KC.js} +4 -5
  9. package/dist/{chunk-GY4TRYOG.js → chunk-SGOTQ7R3.js} +18 -13
  10. package/dist/{chunk-KBEOYUA3.js → chunk-SNIBI4L4.js} +2 -2
  11. package/dist/{chunk-53DUI4MS.js → chunk-Y6HBEACI.js} +1 -1
  12. package/dist/{chunk-ZSQFDQPH.js → chunk-YVQ6DP5Y.js} +23 -5
  13. package/dist/cli/dev.js +1 -1
  14. package/dist/cli/index.js +1 -1
  15. package/dist/{events-DFDD4BRS.js → events-FHPSSSE4.js} +7 -3
  16. package/dist/{folding-JSQFCDZO.js → folding-NEZWWL7K.js} +4 -2
  17. package/dist/{orchestrator-7ZXXNEEC.js → orchestrator-DIJO4BJ7.js} +7 -11
  18. package/dist/package.json +1 -1
  19. package/dist/{processor-6CITCUJR.js → processor-YLKEJ7QC.js} +11 -12
  20. package/dist/{protocol-IWXXOGWM.js → protocol-YNVBDNL7.js} +7 -3
  21. package/dist/{protocol-B4lesmg5.d.ts → protocol-_A3Upt5b.d.ts} +15 -7
  22. package/dist/{serve-BCRWEL5U.js → serve-4I7FE32H.js} +9 -9
  23. package/dist/server/index.d.ts +11 -2
  24. package/dist/server/index.js +8 -8
  25. package/dist/shared/index.d.ts +2 -2
  26. package/dist/shared/index.js +1 -1
  27. package/dist/{tools-K7TJWICQ.js → tools-E3UECGKO.js} +6 -6
  28. package/dist/web/assets/{index-Bl-fM2P0.js → index-CK4F8AG6.js} +66 -66
  29. package/dist/web/assets/{index-DzPKzXc0.css → index-DFE4PMXP.css} +1 -1
  30. package/dist/web/index.html +2 -2
  31. package/dist/web/sw.js +1 -1
  32. package/package.json +1 -1
@@ -2,18 +2,18 @@ import {
2
2
  maybeAutoCompactContext,
3
3
  performManualContextCompaction,
4
4
  resolveCompactionStatsIdentity
5
- } from "./chunk-GY4TRYOG.js";
5
+ } from "./chunk-SGOTQ7R3.js";
6
6
  import "./chunk-NBU6KIOD.js";
7
7
  import "./chunk-574HZVLE.js";
8
8
  import "./chunk-7JPKRM6M.js";
9
9
  import "./chunk-WNZIUQ2L.js";
10
- import "./chunk-ZSQFDQPH.js";
11
- import "./chunk-G6JKXYFE.js";
12
- import "./chunk-HSSXBW6N.js";
10
+ import "./chunk-YVQ6DP5Y.js";
11
+ import "./chunk-LIMBYVO4.js";
12
+ import "./chunk-DZHZ3UUR.js";
13
13
  import "./chunk-22CTURMH.js";
14
14
  import "./chunk-GQZGIMJO.js";
15
15
  import "./chunk-BLNFJ22S.js";
16
- import "./chunk-53DUI4MS.js";
16
+ import "./chunk-Y6HBEACI.js";
17
17
  import "./chunk-R4HADRYO.js";
18
18
  import "./chunk-TVQOONDR.js";
19
19
  import "./chunk-VCALN543.js";
@@ -23,4 +23,4 @@ export {
23
23
  performManualContextCompaction,
24
24
  resolveCompactionStatsIdentity
25
25
  };
26
- //# sourceMappingURL=auto-compaction-2AI46SNC.js.map
26
+ //# sourceMappingURL=auto-compaction-7RDQVOYK.js.map
@@ -2,33 +2,33 @@ import {
2
2
  buildRunChatTurnParams,
3
3
  finalizeTurnCompletion,
4
4
  getSessionMessageCount
5
- } from "./chunk-FBUTQPJ6.js";
5
+ } from "./chunk-NBBX64KC.js";
6
6
  import {
7
7
  applyGeneratedSessionName,
8
8
  generateSessionName,
9
9
  needsNameGenerationCheck
10
- } from "./chunk-BF7JQWEL.js";
10
+ } from "./chunk-BHSTSA7U.js";
11
11
  import {
12
12
  runChatTurn
13
- } from "./chunk-SMK6HIR5.js";
14
- import "./chunk-GY4TRYOG.js";
13
+ } from "./chunk-22JBSK6P.js";
14
+ import "./chunk-SGOTQ7R3.js";
15
15
  import "./chunk-NBU6KIOD.js";
16
16
  import "./chunk-574HZVLE.js";
17
17
  import "./chunk-7JPKRM6M.js";
18
18
  import "./chunk-WNZIUQ2L.js";
19
19
  import {
20
20
  getEventStore
21
- } from "./chunk-ZSQFDQPH.js";
22
- import "./chunk-G6JKXYFE.js";
21
+ } from "./chunk-YVQ6DP5Y.js";
22
+ import "./chunk-LIMBYVO4.js";
23
23
  import {
24
24
  createChatMessageMessage,
25
25
  createPhaseChangedMessage,
26
26
  createSessionRunningMessage
27
- } from "./chunk-HSSXBW6N.js";
27
+ } from "./chunk-DZHZ3UUR.js";
28
28
  import "./chunk-22CTURMH.js";
29
29
  import "./chunk-GQZGIMJO.js";
30
30
  import "./chunk-BLNFJ22S.js";
31
- import "./chunk-53DUI4MS.js";
31
+ import "./chunk-Y6HBEACI.js";
32
32
  import "./chunk-R4HADRYO.js";
33
33
  import "./chunk-TVQOONDR.js";
34
34
  import "./chunk-VCALN543.js";
@@ -62,7 +62,7 @@ async function startChatSession(sessionId, content, deps, options) {
62
62
  sessionManager.setRunning(sessionId, true);
63
63
  broadcastForSession(sessionId, createSessionRunningMessage(true));
64
64
  try {
65
- const { maybeAutoCompactContext } = await import("./auto-compaction-2AI46SNC.js");
65
+ const { maybeAutoCompactContext } = await import("./auto-compaction-7RDQVOYK.js");
66
66
  await maybeAutoCompactContext({
67
67
  sessionManager,
68
68
  sessionId,
@@ -171,4 +171,4 @@ export {
171
171
  startChatSession,
172
172
  stopSessionExecution
173
173
  };
174
- //# sourceMappingURL=chat-handler-ITVOWLJR.js.map
174
+ //# sourceMappingURL=chat-handler-TTCW7DIB.js.map
@@ -13,14 +13,14 @@ import {
13
13
  getToolRegistryForAgent,
14
14
  loadAllAgentsDefault,
15
15
  runTopLevelAgentLoop
16
- } from "./chunk-GY4TRYOG.js";
16
+ } from "./chunk-SGOTQ7R3.js";
17
17
  import {
18
18
  getCurrentContextWindowId,
19
19
  getEventStore
20
- } from "./chunk-ZSQFDQPH.js";
20
+ } from "./chunk-YVQ6DP5Y.js";
21
21
  import {
22
22
  buildSnapshotFromSessionState
23
- } from "./chunk-G6JKXYFE.js";
23
+ } from "./chunk-LIMBYVO4.js";
24
24
  import {
25
25
  logger
26
26
  } from "./chunk-PNBH3RAX.js";
@@ -72,16 +72,17 @@ async function runChatTurn(options) {
72
72
  const { sessionManager, sessionId } = options;
73
73
  const eventStore = getEventStore();
74
74
  const statsIdentity = resolveStatsIdentity(options);
75
- const agentId = options.agentId ?? "planner";
76
- logger.debug("Starting chat turn", { sessionId, agentId });
75
+ const session = sessionManager.requireSession(sessionId);
76
+ const mode = session.mode;
77
+ logger.debug("Starting chat turn", { sessionId, mode });
77
78
  const turnMetrics = new TurnMetrics();
78
79
  try {
79
- if (agentId === "builder") {
80
+ if (mode === "builder") {
80
81
  await runBuilderTurn(options, turnMetrics);
81
82
  } else {
82
- await runGenericAgentTurn(options, turnMetrics, agentId);
83
+ await runGenericAgentTurn(options, turnMetrics, mode);
83
84
  }
84
- const snapshot = buildSnapshot(sessionManager, sessionId, turnMetrics.buildStats(statsIdentity, agentId));
85
+ const snapshot = buildSnapshot(sessionManager, sessionId, turnMetrics.buildStats(statsIdentity, mode));
85
86
  const snapshotEvent = eventStore.append(sessionId, { type: "turn.snapshot", data: snapshot });
86
87
  const deletedCount = eventStore.cleanupOldEvents(sessionId);
87
88
  if (deletedCount > 0) {
@@ -109,7 +110,7 @@ async function runChatTurn(options) {
109
110
  if (error instanceof Error && error.message === "Aborted") {
110
111
  return;
111
112
  }
112
- logger.error("Chat turn error", { sessionId, agentId, error });
113
+ logger.error("Chat turn error", { sessionId, mode, error });
113
114
  const errorMsgId = crypto.randomUUID();
114
115
  eventStore.append(sessionId, {
115
116
  type: "chat.error",
@@ -128,39 +129,18 @@ async function runChatTurn(options) {
128
129
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
129
130
  }
130
131
  }
131
- function hasReminderInCurrentWindow(events, currentWindowId, keyword) {
132
- for (let i = events.length - 1; i >= 0; i--) {
133
- const event = events[i];
134
- if (event?.type !== "message.start") continue;
135
- const data = event.data;
136
- if (data?.role !== "user") continue;
137
- if (data?.messageKind !== "auto-prompt") continue;
138
- if (!data?.content?.includes("<system-reminder>")) continue;
139
- if (!data.content.includes(keyword)) continue;
140
- if (currentWindowId && data.contextWindowId && data.contextWindowId !== currentWindowId) {
141
- continue;
142
- }
143
- if (currentWindowId && !data.contextWindowId) {
144
- continue;
145
- }
146
- return true;
147
- }
148
- return false;
149
- }
150
- function injectModeReminderIfNeeded(_sessionManager, sessionId, agentId, allAgents, _onMessage) {
132
+ function injectModeReminderIfNeeded(sessionManager, sessionId, agentId, allAgents, onMessage) {
151
133
  const eventStore = getEventStore();
152
- const currentWindowId = getCurrentContextWindowId(sessionId);
153
- const agentDef = findAgentById(agentId, allAgents);
154
- if (!agentDef) return;
155
- const modeKeywordMatch = agentDef.prompt.match(/#\s*(.+Mode)/);
156
- const keyword = modeKeywordMatch ? modeKeywordMatch[1] ?? agentId : agentId;
157
- const events = eventStore.getEvents(sessionId);
158
- if (hasReminderInCurrentWindow(events, currentWindowId, keyword)) {
134
+ const session = sessionManager.requireSession(sessionId);
135
+ const lastModeReminder = session.executionState?.lastModeWithReminder;
136
+ if (lastModeReminder === agentId) {
159
137
  return;
160
138
  }
139
+ const agentDef = findAgentById(agentId, allAgents);
140
+ if (!agentDef) return;
161
141
  const reminderContent = buildAgentReminder(agentDef);
162
142
  const reminderMsgId = crypto.randomUUID();
163
- const currentWindowMessageOptions = currentWindowId ? { contextWindowId: currentWindowId } : void 0;
143
+ const currentWindowMessageOptions = getCurrentContextWindowId(sessionId) ? { contextWindowId: getCurrentContextWindowId(sessionId) } : void 0;
164
144
  eventStore.append(sessionId, {
165
145
  type: "message.start",
166
146
  data: {
@@ -181,6 +161,9 @@ function injectModeReminderIfNeeded(_sessionManager, sessionId, agentId, allAgen
181
161
  type: "message.done",
182
162
  data: { messageId: reminderMsgId }
183
163
  });
164
+ sessionManager.updateExecutionState(sessionId, {
165
+ lastModeWithReminder: agentId
166
+ });
184
167
  }
185
168
  async function runGenericAgentTurn(options, turnMetrics, agentId) {
186
169
  const statsIdentity = resolveStatsIdentity(options);
@@ -196,7 +179,7 @@ async function runGenericAgentTurn(options, turnMetrics, agentId) {
196
179
  statsIdentity,
197
180
  signal: options.signal,
198
181
  onMessage: options.onMessage,
199
- assembleRequest: (input) => assembleAgentRequest({ ...input, agentDef, subAgentDefs }),
182
+ assembleRequest: (input) => assembleAgentRequest({ ...input, agentDef, subAgentDefs, modelName: options.llmClient.getModel() }),
200
183
  getToolRegistry: () => getToolRegistryForAgent(agentDef)
201
184
  }, turnMetrics);
202
185
  }
@@ -221,7 +204,7 @@ async function runBuilderTurn(options, turnMetrics) {
221
204
  statsIdentity,
222
205
  signal: options.signal,
223
206
  onMessage: options.onMessage,
224
- assembleRequest: (input) => assembleAgentRequest({ ...input, agentDef: builderDef, subAgentDefs }),
207
+ assembleRequest: (input) => assembleAgentRequest({ ...input, agentDef: builderDef, subAgentDefs, modelName: options.llmClient.getModel() }),
225
208
  getToolRegistry: () => {
226
209
  const baseRegistry = getToolRegistryForAgent(builderDef);
227
210
  return filterToolRegistryForStepDone(baseRegistry, options.injectStepDone === true);
@@ -306,10 +289,8 @@ function buildSnapshot(sessionManager, sessionId, lastStats) {
306
289
  export {
307
290
  createVerifierNudgeConfig,
308
291
  runChatTurn,
309
- hasReminderInCurrentWindow,
310
- injectModeReminderIfNeeded,
311
292
  filterToolRegistryForStepDone,
312
293
  runBuilderTurn,
313
294
  runVerifierTurn
314
295
  };
315
- //# sourceMappingURL=chunk-SMK6HIR5.js.map
296
+ //# sourceMappingURL=chunk-22JBSK6P.js.map
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  generateSessionName,
3
3
  needsNameGeneration
4
- } from "./chunk-BF7JQWEL.js";
4
+ } from "./chunk-BHSTSA7U.js";
5
5
  import {
6
6
  createVerifierNudgeConfig,
7
7
  runBuilderTurn,
8
8
  runChatTurn
9
- } from "./chunk-SMK6HIR5.js";
9
+ } from "./chunk-22JBSK6P.js";
10
10
  import {
11
11
  TurnMetrics,
12
12
  agentExists,
@@ -47,7 +47,7 @@ import {
47
47
  setSkillEnabled,
48
48
  skillExists,
49
49
  spawnShellProcess
50
- } from "./chunk-GY4TRYOG.js";
50
+ } from "./chunk-SGOTQ7R3.js";
51
51
  import {
52
52
  getPathSeparator,
53
53
  getPlatformShell,
@@ -80,6 +80,7 @@ import {
80
80
  emitContextState,
81
81
  emitCriteriaSet,
82
82
  emitCriterionUpdated,
83
+ emitModeChanged,
83
84
  emitPhaseChanged,
84
85
  emitRunningChanged,
85
86
  emitSessionInitialized,
@@ -96,12 +97,12 @@ import {
96
97
  updateSessionProvider,
97
98
  updateSessionRunning,
98
99
  updateSessionSummary
99
- } from "./chunk-ZSQFDQPH.js";
100
+ } from "./chunk-YVQ6DP5Y.js";
100
101
  import {
101
102
  buildContextMessagesFromEventHistory,
102
103
  buildMessagesFromStoredEvents,
103
104
  foldPendingConfirmations
104
- } from "./chunk-G6JKXYFE.js";
105
+ } from "./chunk-LIMBYVO4.js";
105
106
  import {
106
107
  createChatErrorMessage,
107
108
  createChatMessageMessage,
@@ -117,7 +118,7 @@ import {
117
118
  parseClientMessage,
118
119
  serializeServerMessage,
119
120
  storedEventToServerMessage
120
- } from "./chunk-HSSXBW6N.js";
121
+ } from "./chunk-DZHZ3UUR.js";
121
122
  import {
122
123
  EventEmitter,
123
124
  cancelQuestionsForSession,
@@ -131,7 +132,7 @@ import {
131
132
  } from "./chunk-B7E3BICY.js";
132
133
  import {
133
134
  createServerMessage
134
- } from "./chunk-53DUI4MS.js";
135
+ } from "./chunk-Y6HBEACI.js";
135
136
  import {
136
137
  getGlobalConfigDir
137
138
  } from "./chunk-R4HADRYO.js";
@@ -2296,15 +2297,14 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2296
2297
  };
2297
2298
  const llmForSession = (sessionId) => getSessionLLMClient?.(sessionId) ?? getLLMClient();
2298
2299
  const statsForSession = (sessionId) => getSessionStatsIdentity?.(sessionId) ?? resolveStatsIdentity(getLLMClient(), getActiveProvider);
2299
- function startTurnWithCompletionChain(sessionId, controller, agentId) {
2300
+ function startTurnWithCompletionChain(sessionId, controller) {
2300
2301
  runChatTurn({
2301
2302
  sessionManager,
2302
2303
  sessionId,
2303
2304
  llmClient: llmForSession(sessionId),
2304
2305
  statsIdentity: statsForSession(sessionId),
2305
2306
  signal: controller.signal,
2306
- onMessage: (msg) => broadcastForSession(sessionId, msg),
2307
- ...agentId ? { agentId } : {}
2307
+ onMessage: (msg) => broadcastForSession(sessionId, msg)
2308
2308
  }).catch((error) => {
2309
2309
  if (error instanceof Error && error.message === "Aborted") {
2310
2310
  return;
@@ -2319,7 +2319,7 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2319
2319
  const nextAsap = asapMsgs[0];
2320
2320
  if (nextAsap) {
2321
2321
  for (const remaining of asapMsgs.slice(1)) {
2322
- sessionManager.queueMessage(sessionId, "asap", remaining.content, remaining.attachments, remaining.messageKind, remaining.agentId);
2322
+ sessionManager.queueMessage(sessionId, "asap", remaining.content, remaining.attachments, remaining.messageKind);
2323
2323
  }
2324
2324
  broadcastForSession(sessionId, createQueueStateMessage(sessionManager.getQueueState(sessionId)));
2325
2325
  const userMessagePayload = {
@@ -2331,14 +2331,14 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2331
2331
  broadcastForSession(sessionId, createChatMessageMessage(userMessage));
2332
2332
  const newController = new AbortController();
2333
2333
  activeAgents.set(sessionId, newController);
2334
- startTurnWithCompletionChain(sessionId, newController, nextAsap.agentId);
2334
+ startTurnWithCompletionChain(sessionId, newController);
2335
2335
  return;
2336
2336
  }
2337
2337
  const completionMsgs = sessionManager.drainCompletionMessages(sessionId);
2338
2338
  const next = completionMsgs[0];
2339
2339
  if (next) {
2340
2340
  for (const remaining of completionMsgs.slice(1)) {
2341
- sessionManager.queueMessage(sessionId, "completion", remaining.content, remaining.attachments, void 0, remaining.agentId);
2341
+ sessionManager.queueMessage(sessionId, "completion", remaining.content, remaining.attachments);
2342
2342
  }
2343
2343
  broadcastForSession(sessionId, createQueueStateMessage(sessionManager.getQueueState(sessionId)));
2344
2344
  const userMessage = sessionManager.addMessage(sessionId, {
@@ -2349,7 +2349,7 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2349
2349
  broadcastForSession(sessionId, createChatMessageMessage(userMessage));
2350
2350
  const newController = new AbortController();
2351
2351
  activeAgents.set(sessionId, newController);
2352
- startTurnWithCompletionChain(sessionId, newController, next.agentId);
2352
+ startTurnWithCompletionChain(sessionId, newController);
2353
2353
  return;
2354
2354
  }
2355
2355
  sessionManager.clearMessageQueue(sessionId);
@@ -2691,7 +2691,7 @@ async function handleClientMessage(ws, client, message, getLLMClient, getActiveP
2691
2691
  logger.warn("Session name generation failed", { sessionId, error: error instanceof Error ? error.message : error });
2692
2692
  });
2693
2693
  }
2694
- startTurnWithCompletionChain(sessionId, controller, message.payload.agentId);
2694
+ startTurnWithCompletionChain(sessionId, controller);
2695
2695
  } catch (error) {
2696
2696
  if (activeAgents.get(sessionId) === controller) {
2697
2697
  activeAgents.delete(sessionId);
@@ -2807,7 +2807,9 @@ ${content}` : workflowInfo;
2807
2807
  (async () => {
2808
2808
  let controller = null;
2809
2809
  try {
2810
+ sessionManager.setMode(sessionId, "builder");
2810
2811
  sessionManager.setPhase(sessionId, "build");
2812
+ eventStore.append(sessionId, { type: "mode.changed", data: { mode: "builder", auto: false, reason: "Criteria accepted" } });
2811
2813
  eventStore.append(sessionId, { type: "phase.changed", data: { phase: "build" } });
2812
2814
  controller = new AbortController();
2813
2815
  const existingController = activeAgents.get(sessionId);
@@ -2827,7 +2829,6 @@ ${content}` : workflowInfo;
2827
2829
  llmClient: llmForSession(sessionId),
2828
2830
  statsIdentity: statsForSession(sessionId),
2829
2831
  injectBuilderKickoff: !hasAcceptMessage,
2830
- agentId: "builder",
2831
2832
  ...acceptPayload2?.workflowId ? { workflowId: acceptPayload2.workflowId } : {},
2832
2833
  ...hasAcceptMessage ? { userMessage: { content: hasAcceptContent ? acceptPayload2.content : "", ...hasAcceptAttachments ? { attachments: acceptAttachments } : {} } } : {},
2833
2834
  signal: controller.signal,
@@ -2985,6 +2986,10 @@ ${content}` : workflowInfo;
2985
2986
  });
2986
2987
  return;
2987
2988
  }
2989
+ if (session.mode !== "builder") {
2990
+ send(createErrorMessage("INVALID_MODE", "Runner can only be launched in builder mode", message.id));
2991
+ return;
2992
+ }
2988
2993
  const launchPayloadEarly = message.payload;
2989
2994
  const pendingCriteria = session.criteria.filter((c) => c.status.type !== "passed");
2990
2995
  if (!launchPayloadEarly?.workflowId && pendingCriteria.length === 0) {
@@ -4160,28 +4165,6 @@ function canCompact(currentTokens, maxTokens) {
4160
4165
  }
4161
4166
 
4162
4167
  // src/server/session/manager.ts
4163
- function mapSnapshotMessage(m) {
4164
- const msg = {
4165
- id: m.id,
4166
- role: m.role,
4167
- content: m.content,
4168
- timestamp: new Date(m.timestamp).toISOString()
4169
- };
4170
- if (m.thinkingContent !== void 0) msg.thinkingContent = m.thinkingContent;
4171
- if (m.toolCalls !== void 0) msg.toolCalls = m.toolCalls;
4172
- if (m.segments !== void 0) msg.segments = m.segments;
4173
- if (m.stats !== void 0) msg.stats = m.stats;
4174
- if (m.partial !== void 0) msg.partial = m.partial;
4175
- if (m.isStreaming !== void 0) msg.isStreaming = m.isStreaming;
4176
- if (m.subAgentId !== void 0) msg.subAgentId = m.subAgentId;
4177
- if (m.subAgentType !== void 0) msg.subAgentType = m.subAgentType;
4178
- if (m.isSystemGenerated !== void 0) msg.isSystemGenerated = m.isSystemGenerated;
4179
- if (m.messageKind !== void 0) msg.messageKind = m.messageKind;
4180
- if (m.contextWindowId !== void 0) msg.contextWindowId = m.contextWindowId;
4181
- if (m.isCompactionSummary !== void 0) msg.isCompactionSummary = m.isCompactionSummary;
4182
- if (m.promptContext !== void 0) msg.promptContext = m.promptContext;
4183
- return msg;
4184
- }
4185
4168
  var SessionManager = class {
4186
4169
  events = new EventEmitter();
4187
4170
  activeSessionId = null;
@@ -4291,6 +4274,22 @@ var SessionManager = class {
4291
4274
  // ============================================================================
4292
4275
  // State Changes (emit events + notify subscribers)
4293
4276
  // ============================================================================
4277
+ /**
4278
+ * Change session mode. Emits mode.changed event.
4279
+ */
4280
+ setMode(sessionId, toMode) {
4281
+ const session = this.requireSession(sessionId);
4282
+ const fromMode = session.mode;
4283
+ if (fromMode === toMode) {
4284
+ return session;
4285
+ }
4286
+ logger.debug("Changing session mode", { sessionId, from: fromMode, to: toMode });
4287
+ emitModeChanged(sessionId, toMode, false);
4288
+ const updatedSession = this.requireSession(sessionId);
4289
+ this.emit({ type: "mode_changed", sessionId, from: fromMode, to: toMode });
4290
+ this.emit({ type: "session_updated", session: updatedSession });
4291
+ return updatedSession;
4292
+ }
4294
4293
  /**
4295
4294
  * Change session phase. Emits phase.changed event.
4296
4295
  */
@@ -4452,7 +4451,26 @@ var SessionManager = class {
4452
4451
  getCurrentWindowMessages(sessionId) {
4453
4452
  const state = getSessionState(sessionId);
4454
4453
  if (!state) return [];
4455
- return state.messages.filter((m) => m.contextWindowId === state.currentContextWindowId).map(mapSnapshotMessage);
4454
+ return state.messages.filter((m) => m.contextWindowId === state.currentContextWindowId).map((m) => {
4455
+ const msg = {
4456
+ id: m.id,
4457
+ role: m.role,
4458
+ content: m.content,
4459
+ timestamp: new Date(m.timestamp).toISOString()
4460
+ };
4461
+ if (m.thinkingContent !== void 0) msg.thinkingContent = m.thinkingContent;
4462
+ if (m.toolCalls !== void 0) msg.toolCalls = m.toolCalls;
4463
+ if (m.segments !== void 0) msg.segments = m.segments;
4464
+ if (m.stats !== void 0) msg.stats = m.stats;
4465
+ if (m.partial !== void 0) msg.partial = m.partial;
4466
+ if (m.isStreaming !== void 0) msg.isStreaming = m.isStreaming;
4467
+ if (m.contextWindowId !== void 0) msg.contextWindowId = m.contextWindowId;
4468
+ if (m.isSystemGenerated !== void 0) msg.isSystemGenerated = m.isSystemGenerated;
4469
+ if (m.messageKind !== void 0) msg.messageKind = m.messageKind;
4470
+ if (m.isCompactionSummary !== void 0) msg.isCompactionSummary = m.isCompactionSummary;
4471
+ if (m.promptContext !== void 0) msg.promptContext = m.promptContext;
4472
+ return msg;
4473
+ });
4456
4474
  }
4457
4475
  /**
4458
4476
  * Compact context. Delegates to EventStore.
@@ -4597,7 +4615,7 @@ ${summary}`, {
4597
4615
  // Message Queue (runtime state, transient while agent is running)
4598
4616
  // ============================================================================
4599
4617
  messageQueues = /* @__PURE__ */ new Map();
4600
- queueMessage(sessionId, mode, content, attachments, messageKind, agentId) {
4618
+ queueMessage(sessionId, mode, content, attachments, messageKind) {
4601
4619
  const queue = this.messageQueues.get(sessionId) ?? [];
4602
4620
  const msg = {
4603
4621
  queueId: crypto.randomUUID(),
@@ -4605,7 +4623,6 @@ ${summary}`, {
4605
4623
  content,
4606
4624
  ...attachments ? { attachments } : {},
4607
4625
  ...messageKind ? { messageKind } : {},
4608
- ...agentId ? { agentId } : {},
4609
4626
  queuedAt: (/* @__PURE__ */ new Date()).toISOString()
4610
4627
  };
4611
4628
  queue.push(msg);
@@ -4813,6 +4830,7 @@ ${summary}`,
4813
4830
  if (!eventState) {
4814
4831
  return {
4815
4832
  ...dbSession,
4833
+ mode: "planner",
4816
4834
  phase: "plan",
4817
4835
  isRunning: false,
4818
4836
  messages: [],
@@ -4845,13 +4863,14 @@ ${summary}`,
4845
4863
  });
4846
4864
  return {
4847
4865
  ...dbSession,
4866
+ mode: eventState.mode,
4848
4867
  phase: eventState.phase,
4849
4868
  isRunning: eventState.isRunning,
4850
4869
  messages,
4851
4870
  criteria: eventState.criteria,
4852
4871
  contextWindows: [],
4853
4872
  // Derived from events, not stored separately
4854
- executionState: null
4873
+ executionState: eventState.lastModeWithReminder ? { lastModeWithReminder: eventState.lastModeWithReminder } : null
4855
4874
  };
4856
4875
  }
4857
4876
  };
@@ -5460,7 +5479,7 @@ function createTerminalRoutes() {
5460
5479
  }
5461
5480
 
5462
5481
  // src/constants.ts
5463
- var VERSION = "1.6.45";
5482
+ var VERSION = "1.6.47";
5464
5483
 
5465
5484
  // src/server/index.ts
5466
5485
  var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
@@ -5621,7 +5640,7 @@ async function createServerHandle(config) {
5621
5640
  res.json({ success: true });
5622
5641
  });
5623
5642
  app.get("/api/sessions", async (req, res) => {
5624
- const { getRecentUserPromptsForSession } = await import("./events-DFDD4BRS.js");
5643
+ const { getRecentUserPromptsForSession } = await import("./events-FHPSSSE4.js");
5625
5644
  const projectId = req.query["projectId"];
5626
5645
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
5627
5646
  const offset = parseInt(req.query["offset"]) || 0;
@@ -5654,8 +5673,8 @@ async function createServerHandle(config) {
5654
5673
  res.status(201).json({ session });
5655
5674
  });
5656
5675
  app.get("/api/sessions/:id", async (req, res) => {
5657
- const { getEventStore: getEventStore2 } = await import("./events-DFDD4BRS.js");
5658
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-JSQFCDZO.js");
5676
+ const { getEventStore: getEventStore2 } = await import("./events-FHPSSSE4.js");
5677
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-NEZWWL7K.js");
5659
5678
  const session = sessionManager.getSession(req.params.id);
5660
5679
  if (!session) {
5661
5680
  return res.status(404).json({ error: "Session not found" });
@@ -5685,8 +5704,8 @@ async function createServerHandle(config) {
5685
5704
  res.json({ success: true });
5686
5705
  });
5687
5706
  app.post("/api/sessions/:id/provider", async (req, res) => {
5688
- const { getEventStore: getEventStore2 } = await import("./events-DFDD4BRS.js");
5689
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-JSQFCDZO.js");
5707
+ const { getEventStore: getEventStore2 } = await import("./events-FHPSSSE4.js");
5708
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-NEZWWL7K.js");
5690
5709
  const sessionId = req.params.id;
5691
5710
  const session = sessionManager.getSession(sessionId);
5692
5711
  if (!session) {
@@ -5722,6 +5741,26 @@ async function createServerHandle(config) {
5722
5741
  sessionManager.setCriteria(sessionId, criteria);
5723
5742
  res.json({ success: true });
5724
5743
  });
5744
+ app.put("/api/sessions/:id/mode", async (req, res) => {
5745
+ const { getEventStore: getEventStore2 } = await import("./events-FHPSSSE4.js");
5746
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-NEZWWL7K.js");
5747
+ const sessionId = req.params.id;
5748
+ const session = sessionManager.getSession(sessionId);
5749
+ if (!session) {
5750
+ return res.status(404).json({ error: "Session not found" });
5751
+ }
5752
+ const { mode } = req.body;
5753
+ if (!mode || !["planner", "builder"].includes(mode)) {
5754
+ return res.status(400).json({ error: 'mode is required and must be "planner" or "builder"' });
5755
+ }
5756
+ sessionManager.setMode(sessionId, mode);
5757
+ const eventStore = getEventStore2();
5758
+ eventStore.append(sessionId, { type: "mode.changed", data: { mode, auto: false } });
5759
+ const events = eventStore.getEvents(sessionId);
5760
+ const messages = buildMessagesFromStoredEvents2(events);
5761
+ const updatedSession = sessionManager.getSession(sessionId);
5762
+ res.json({ session: updatedSession, messages });
5763
+ });
5725
5764
  app.put("/api/sessions/:id/danger-level", async (req, res) => {
5726
5765
  const sessionId = req.params.id;
5727
5766
  const session = sessionManager.getSession(sessionId);
@@ -5742,14 +5781,14 @@ async function createServerHandle(config) {
5742
5781
  if (!callId || approved === void 0) {
5743
5782
  return res.status(400).json({ error: "callId and approved are required" });
5744
5783
  }
5745
- const { providePathConfirmation: providePathConfirmation2 } = await import("./tools-K7TJWICQ.js");
5784
+ const { providePathConfirmation: providePathConfirmation2 } = await import("./tools-E3UECGKO.js");
5746
5785
  const result = providePathConfirmation2(callId, approved, alwaysAllow);
5747
5786
  if (!result.found) {
5748
5787
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
5749
5788
  }
5750
- const { getEventStore: getEventStore2 } = await import("./events-DFDD4BRS.js");
5751
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-JSQFCDZO.js");
5752
- const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-IWXXOGWM.js");
5789
+ const { getEventStore: getEventStore2 } = await import("./events-FHPSSSE4.js");
5790
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-NEZWWL7K.js");
5791
+ const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-YNVBDNL7.js");
5753
5792
  const eventStore = getEventStore2();
5754
5793
  const events = eventStore.getEvents(sessionId);
5755
5794
  const messages = buildMessagesFromStoredEvents2(events);
@@ -5767,7 +5806,7 @@ async function createServerHandle(config) {
5767
5806
  if (!callId || !answer) {
5768
5807
  return res.status(400).json({ error: "callId and answer are required" });
5769
5808
  }
5770
- const { provideAnswer: provideAnswer2 } = await import("./tools-K7TJWICQ.js");
5809
+ const { provideAnswer: provideAnswer2 } = await import("./tools-E3UECGKO.js");
5771
5810
  const found = provideAnswer2(callId, answer);
5772
5811
  if (!found) {
5773
5812
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -5780,11 +5819,11 @@ async function createServerHandle(config) {
5780
5819
  if (!session) {
5781
5820
  return res.status(404).json({ error: "Session not found" });
5782
5821
  }
5783
- const { content, attachments, messageKind, agentId } = req.body;
5822
+ const { content, attachments, messageKind } = req.body;
5784
5823
  if (!content?.trim()) {
5785
5824
  return res.status(400).json({ error: "content is required" });
5786
5825
  }
5787
- sessionManager.queueMessage(sessionId, "asap", content, attachments, messageKind, agentId);
5826
+ sessionManager.queueMessage(sessionId, "asap", content, attachments, messageKind);
5788
5827
  res.json({ success: true, queueState: sessionManager.getQueueState(sessionId) });
5789
5828
  });
5790
5829
  app.delete("/api/sessions/:id/queue/:queueId", (req, res) => {
@@ -5803,14 +5842,14 @@ async function createServerHandle(config) {
5803
5842
  if (!session) {
5804
5843
  return res.status(404).json({ error: "Session not found" });
5805
5844
  }
5806
- const { stopSessionExecution } = await import("./chat-handler-ITVOWLJR.js");
5807
- const { cancelQuestionsForSession: cancelQuestionsForSession2, cancelPathConfirmationsForSession: cancelPathConfirmationsForSession2 } = await import("./tools-K7TJWICQ.js");
5845
+ const { stopSessionExecution } = await import("./chat-handler-TTCW7DIB.js");
5846
+ const { cancelQuestionsForSession: cancelQuestionsForSession2, cancelPathConfirmationsForSession: cancelPathConfirmationsForSession2 } = await import("./tools-E3UECGKO.js");
5808
5847
  stopSessionExecution(sessionId, sessionManager);
5809
5848
  abortSession(sessionId);
5810
5849
  cancelQuestionsForSession2(sessionId, "Session stopped by user");
5811
5850
  cancelPathConfirmationsForSession2(sessionId, "Session stopped by user");
5812
5851
  sessionManager.clearMessageQueue(sessionId);
5813
- const eventStore = (await import("./events-DFDD4BRS.js")).getEventStore();
5852
+ const eventStore = (await import("./events-FHPSSSE4.js")).getEventStore();
5814
5853
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
5815
5854
  res.json({ success: true });
5816
5855
  });
@@ -6263,7 +6302,7 @@ async function createServerHandle(config) {
6263
6302
  providerManager
6264
6303
  );
6265
6304
  const wss = wssExports.wss;
6266
- const { QueueProcessor } = await import("./processor-6CITCUJR.js");
6305
+ const { QueueProcessor } = await import("./processor-YLKEJ7QC.js");
6267
6306
  const queueProcessor = new QueueProcessor({
6268
6307
  sessionManager,
6269
6308
  providerManager,
@@ -6336,4 +6375,4 @@ export {
6336
6375
  createServerHandle,
6337
6376
  createServer
6338
6377
  };
6339
- //# sourceMappingURL=chunk-RB576RLK.js.map
6378
+ //# sourceMappingURL=chunk-4DR3WUVA.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  updateSessionMetadata
3
- } from "./chunk-ZSQFDQPH.js";
3
+ } from "./chunk-YVQ6DP5Y.js";
4
4
  import {
5
5
  buildMessagesFromStoredEvents,
6
6
  foldPendingConfirmations
7
- } from "./chunk-G6JKXYFE.js";
7
+ } from "./chunk-LIMBYVO4.js";
8
8
  import {
9
9
  createSessionStateMessage
10
- } from "./chunk-HSSXBW6N.js";
10
+ } from "./chunk-DZHZ3UUR.js";
11
11
  import {
12
12
  logger
13
13
  } from "./chunk-PNBH3RAX.js";
@@ -108,4 +108,4 @@ export {
108
108
  needsNameGenerationCheck,
109
109
  applyGeneratedSessionName
110
110
  };
111
- //# sourceMappingURL=chunk-BF7JQWEL.js.map
111
+ //# sourceMappingURL=chunk-BHSTSA7U.js.map