openfox 1.6.76 → 1.6.78

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/README.md +18 -18
  2. package/dist/agent-defaults/code-reviewer.agent.md +1 -0
  3. package/dist/agent-defaults/explorer.agent.md +2 -1
  4. package/dist/agent-defaults/verifier.agent.md +4 -0
  5. package/dist/{auto-compaction-V3PA77WG.js → auto-compaction-AN3U2AD5.js} +5 -5
  6. package/dist/{chat-handler-7DKHGTVO.js → chat-handler-AIBOSHAQ.js} +8 -8
  7. package/dist/{chunk-LCQ3MPXD.js → chunk-2IZMUXMP.js} +3 -3
  8. package/dist/{chunk-K2V7EW5F.js → chunk-DKKDNJT7.js} +36 -22
  9. package/dist/{chunk-XKIEDGQF.js → chunk-DL6ZILAF.js} +1 -2
  10. package/dist/{chunk-H5EICXF3.js → chunk-GLVNO4DS.js} +188 -91
  11. package/dist/{chunk-NHJ2GVCF.js → chunk-NWXLRRDD.js} +4 -4
  12. package/dist/{chunk-5ZD3GZTK.js → chunk-RJRG2VER.js} +33 -2
  13. package/dist/{chunk-VAMTEAYI.js → chunk-TS5XFQ2D.js} +100 -49
  14. package/dist/{chunk-RQ4XSKUR.js → chunk-VSYJIPRI.js} +3 -3
  15. package/dist/cli/dev.js +1 -1
  16. package/dist/cli/index.js +1 -1
  17. package/dist/{events-BDXQOC7F.js → events-ND5GZBT2.js} +7 -5
  18. package/dist/{folding-2HW7FIKL.js → folding-XIKR6AFM.js} +14 -4
  19. package/dist/{inspect-proxy-Y75AXMRX.js → inspect-proxy-42ZXL2R5.js} +2 -2
  20. package/dist/{orchestrator-KCHEENHK.js → orchestrator-5BY2MH72.js} +6 -6
  21. package/dist/package.json +1 -1
  22. package/dist/{processor-6TS37IYH.js → processor-PV446N55.js} +5 -5
  23. package/dist/{serve-OLDABBV3.js → serve-6ME66XOO.js} +7 -7
  24. package/dist/server/index.js +6 -6
  25. package/dist/server/public/__inspect__.js +161 -142
  26. package/dist/{service-D6LC3CAM.js → service-TU4XSXYJ.js} +33 -2
  27. package/dist/{tools-BHYHS3RY.js → tools-6DXPHBUV.js} +5 -5
  28. package/dist/web/__inspect__.js +178 -155
  29. package/dist/web/assets/{index-DAuZ02-Q.js → index-0igqGWob.js} +65 -65
  30. package/dist/web/index.html +2 -2
  31. package/dist/web/sw.js +1 -1
  32. package/package.json +1 -1
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-CMQCO27Y.js";
10
10
  import {
11
11
  startInspectProxy
12
- } from "./chunk-XKIEDGQF.js";
12
+ } from "./chunk-DL6ZILAF.js";
13
13
  import {
14
14
  createProcess,
15
15
  getPlatformShell,
@@ -30,10 +30,18 @@ import {
30
30
  streamWithSegments
31
31
  } from "./chunk-CUDAT6SS.js";
32
32
  import {
33
- getContextMessages,
34
33
  getCurrentContextWindowId,
35
34
  getEventStore
36
- } from "./chunk-5ZD3GZTK.js";
35
+ } from "./chunk-RJRG2VER.js";
36
+ import {
37
+ buildContextMessagesFromEventHistory,
38
+ foldContextState,
39
+ handleMessageDelta,
40
+ handleMessageThinking,
41
+ handleToolCall,
42
+ handleToolResult,
43
+ stripOrphanedToolCalls
44
+ } from "./chunk-TS5XFQ2D.js";
37
45
  import {
38
46
  createChatDoneMessage,
39
47
  createChatMessageMessage,
@@ -672,13 +680,15 @@ async function* streamLLMPure(options) {
672
680
  }
673
681
  };
674
682
  } else if (seenToolIndices.has(value.index) && value.arguments) {
675
- const accumulatedArgs = toolArgs.get(value.index);
676
683
  const name = toolNames.get(value.index);
677
- if (accumulatedArgs && name) {
678
- yield {
679
- type: "tool.preparing",
680
- data: { messageId, index: value.index, name, arguments: accumulatedArgs }
681
- };
684
+ if (name === "run_command" || name === "return_value") {
685
+ const accumulatedArgs = toolArgs.get(value.index);
686
+ if (accumulatedArgs) {
687
+ yield {
688
+ type: "tool.preparing",
689
+ data: { messageId, index: value.index, name, arguments: accumulatedArgs }
690
+ };
691
+ }
682
692
  }
683
693
  }
684
694
  if (fullName === "return_value" && value.arguments) {
@@ -1434,9 +1444,20 @@ function extractDangerousPatterns(command) {
1434
1444
  }
1435
1445
  return dangerous;
1436
1446
  }
1437
- var GIT_NO_VERIFY_PATTERN = /\bgit\s+\w+\s+.*(?:--no-verify|-n)/;
1438
1447
  function extractGitNoVerify(command) {
1439
- return GIT_NO_VERIFY_PATTERN.test(command);
1448
+ const parts = command.split(/\s+/);
1449
+ for (let i = 0; i < parts.length - 1; i++) {
1450
+ if (parts[i] === "git") {
1451
+ const sub = parts[i + 1];
1452
+ if (sub && !sub.startsWith("-")) {
1453
+ const args = parts.slice(i + 2);
1454
+ if (args.includes("--no-verify") || args.includes("-n")) {
1455
+ return true;
1456
+ }
1457
+ }
1458
+ }
1459
+ }
1460
+ return false;
1440
1461
  }
1441
1462
  async function requestPathAccess(paths, workdir, sessionId, callId, tool, onEvent, dangerLevel, command) {
1442
1463
  const emitPendingEvent = (confirmationPaths, confirmationReason) => {
@@ -2798,6 +2819,111 @@ async function deleteSkill(configDir, skillId) {
2798
2819
 
2799
2820
  // src/server/chat/agent-loop.ts
2800
2821
  import stripAnsi from "strip-ansi";
2822
+
2823
+ // src/server/chat/conversation-history.ts
2824
+ function buildContextMessages(events, scope) {
2825
+ if (scope.type === "toplevel") {
2826
+ return buildTopLevelContextMessages(events, scope);
2827
+ }
2828
+ return buildSubAgentContextMessages(events, scope);
2829
+ }
2830
+ function buildTopLevelContextMessages(events, scope) {
2831
+ const includeVerifier = scope.includeVerifier ?? true;
2832
+ const currentWindowId = foldContextState(events, "").currentContextWindowId;
2833
+ if (!currentWindowId) return [];
2834
+ return buildContextMessagesFromEventHistory(events, currentWindowId, { includeVerifier });
2835
+ }
2836
+ function buildSubAgentContextMessages(events, scope) {
2837
+ const { subAgentId } = scope;
2838
+ const messages = [];
2839
+ const messageMap = /* @__PURE__ */ new Map();
2840
+ const fulfilledToolCallIds = /* @__PURE__ */ new Set();
2841
+ let compactionSummaryIndex = -1;
2842
+ for (let i = events.length - 1; i >= 0; i--) {
2843
+ const event = events[i];
2844
+ if (event.type === "context.compacted") {
2845
+ const data = event.data;
2846
+ if (data.subAgentId === subAgentId) {
2847
+ compactionSummaryIndex = i;
2848
+ break;
2849
+ }
2850
+ }
2851
+ }
2852
+ const startIdx = compactionSummaryIndex >= 0 ? compactionSummaryIndex : 0;
2853
+ for (let i = startIdx; i < events.length; i++) {
2854
+ const event = events[i];
2855
+ switch (event.type) {
2856
+ case "message.start": {
2857
+ const data = event.data;
2858
+ if (data.subAgentId !== subAgentId) break;
2859
+ if (data.role === "system") break;
2860
+ if (data.messageKind === "context-reset") break;
2861
+ const message = {
2862
+ id: data.messageId,
2863
+ role: data.role,
2864
+ content: data.content ?? "",
2865
+ ...data.subAgentId ? { subAgentId: data.subAgentId } : {},
2866
+ ...data.subAgentType ? { subAgentType: data.subAgentType } : {},
2867
+ ...data.contextWindowId ? { contextWindowId: data.contextWindowId } : {},
2868
+ ...data.isCompactionSummary ? { isCompactionSummary: data.isCompactionSummary } : {},
2869
+ ...data.attachments !== void 0 ? { attachments: data.attachments } : {}
2870
+ };
2871
+ messageMap.set(data.messageId, message);
2872
+ messages.push(message);
2873
+ break;
2874
+ }
2875
+ case "message.thinking": {
2876
+ const evt = event.data;
2877
+ handleMessageThinking(messageMap, evt);
2878
+ break;
2879
+ }
2880
+ case "message.delta": {
2881
+ const evt = event.data;
2882
+ handleMessageDelta(messageMap, evt);
2883
+ break;
2884
+ }
2885
+ case "tool.call": {
2886
+ const evt = event.data;
2887
+ handleToolCall(messageMap, evt);
2888
+ break;
2889
+ }
2890
+ case "tool.result": {
2891
+ const evt = event.data;
2892
+ handleToolResult(messages, messageMap, fulfilledToolCallIds, evt);
2893
+ break;
2894
+ }
2895
+ case "context.compacted": {
2896
+ const data = event.data;
2897
+ if (data.subAgentId === subAgentId && i === compactionSummaryIndex) {
2898
+ }
2899
+ break;
2900
+ }
2901
+ }
2902
+ }
2903
+ stripOrphanedToolCalls(messages, fulfilledToolCallIds);
2904
+ return messages.map(
2905
+ ({ id: _id, subAgentId: _sa, subAgentType: _st, contextWindowId: _cw, isCompactionSummary: _ics, ...rest }) => {
2906
+ const ctx = {
2907
+ role: rest.role,
2908
+ content: rest.content,
2909
+ ...rest.thinkingContent ? { thinkingContent: rest.thinkingContent } : {},
2910
+ ...rest.toolCalls ? { toolCalls: rest.toolCalls } : {},
2911
+ ...rest.toolCallId ? { toolCallId: rest.toolCallId } : {},
2912
+ ...rest.attachments ? { attachments: rest.attachments } : {}
2913
+ };
2914
+ return ctx;
2915
+ }
2916
+ );
2917
+ }
2918
+ function getConversationMessages(scope) {
2919
+ const eventStore = getEventStore();
2920
+ const events = eventStore.getEvents(scope.sessionId);
2921
+ if (events.length === 0) return [];
2922
+ const contextMessages = buildContextMessages(events, scope);
2923
+ return minimalMessagesToRequestContextMessages(contextMessages, "history");
2924
+ }
2925
+
2926
+ // src/server/chat/agent-loop.ts
2801
2927
  function emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, promptContext, eventStore) {
2802
2928
  const stats = turnMetrics.buildStats(statsIdentity, mode);
2803
2929
  eventStore.append(
@@ -2918,24 +3044,7 @@ Error: ${toolResult.error}` : `Error: ${toolResult.error}`
2918
3044
  return { toolMessages, criteriaChanged, returnValueContent, returnValueResult };
2919
3045
  }
2920
3046
  var MAX_FORMAT_RETRIES = 10;
2921
- var FORMAT_CORRECTION_PROMPT2 = `IMPORTANT: You MUST use the JSON function calling API. Do NOT output XML tags like <tool_call>, <function=>, or <parameter=>. Your previous attempt was stopped because you used the wrong format. Use the proper tool_calls format.`;
2922
- function toRequestContextMessages(messages) {
2923
- return messages.map((message) => ({
2924
- role: message.role,
2925
- content: message.content,
2926
- source: "history",
2927
- ...message.thinkingContent ? { thinkingContent: message.thinkingContent } : {},
2928
- ...message.toolCalls ? {
2929
- toolCalls: message.toolCalls.map((toolCall) => ({
2930
- id: toolCall.id,
2931
- name: toolCall.name,
2932
- arguments: toolCall.arguments
2933
- }))
2934
- } : {},
2935
- ...message.toolCallId ? { toolCallId: message.toolCallId } : {},
2936
- ...message.attachments ? { attachments: message.attachments } : {}
2937
- }));
2938
- }
3047
+ var FORMAT_CORRECTION_PROMPT2 = `IMPORTANT: You MUST use the JSON function calling API. Do NOT output XML tags like <function=>, <parameter=>, or <invoke=>. Your previous attempt was stopped because you used the wrong format. Use the proper tool_calls format.`;
2939
3048
  async function runTopLevelAgentLoop(config, turnMetrics) {
2940
3049
  const { mode, sessionManager, sessionId, llmClient, signal, onMessage, statsIdentity } = config;
2941
3050
  const eventStore = getEventStore();
@@ -2964,7 +3073,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
2964
3073
  }));
2965
3074
  const toolRegistry = config.getToolRegistry();
2966
3075
  const currentWindowMessageOptions = getCurrentWindowMessageOptions(sessionId);
2967
- const requestMessages = toRequestContextMessages(getContextMessages(sessionId));
3076
+ const requestMessages = getConversationMessages({ type: "toplevel", sessionId });
2968
3077
  if (formatRetryCount > 0) {
2969
3078
  const correctionMsgId = crypto.randomUUID();
2970
3079
  eventStore.append(
@@ -2976,7 +3085,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
2976
3085
  })
2977
3086
  );
2978
3087
  eventStore.append(sessionId, createFormatRetryEvent(formatRetryCount, MAX_FORMAT_RETRIES));
2979
- requestMessages.push({ role: "user", content: FORMAT_CORRECTION_PROMPT2, source: "runtime" });
3088
+ requestMessages.push({ role: "user", content: FORMAT_CORRECTION_PROMPT2, source: "history" });
2980
3089
  }
2981
3090
  const configDir = getGlobalConfigDir(getRuntimeConfig().mode ?? "production");
2982
3091
  const skills = await getEnabledSkillMetadata(configDir);
@@ -3252,7 +3361,6 @@ async function executeSubAgent(options) {
3252
3361
  const subAgentId = crypto.randomUUID();
3253
3362
  let session = sessionManager.requireSession(sessionId);
3254
3363
  const currentWindowMessageOptions = getCurrentWindowMessageOptions2(sessionId);
3255
- const contextMessages = [{ role: "user", content: prompt, source: "runtime" }];
3256
3364
  logger.debug("Sub-agent starting", { subAgentType, subAgentId, sessionId });
3257
3365
  const resetMsgId = crypto.randomUUID();
3258
3366
  eventStore.append(
@@ -3266,12 +3374,30 @@ async function executeSubAgent(options) {
3266
3374
  })
3267
3375
  );
3268
3376
  eventStore.append(sessionId, { type: "message.done", data: { messageId: resetMsgId } });
3269
- for (const msg of contextMessages) {
3270
- const msgId = crypto.randomUUID();
3271
- eventStore.append(
3272
- sessionId,
3273
- createMessageStartEvent(msgId, "user", msg.content, {
3274
- ...currentWindowMessageOptions ?? {},
3377
+ const promptMsgId = crypto.randomUUID();
3378
+ eventStore.append(
3379
+ sessionId,
3380
+ createMessageStartEvent(promptMsgId, "user", prompt, {
3381
+ ...currentWindowMessageOptions ?? {},
3382
+ isSystemGenerated: true,
3383
+ messageKind: "auto-prompt",
3384
+ subAgentId,
3385
+ subAgentType,
3386
+ metadata: {
3387
+ type: "subagent",
3388
+ name: agentDef.metadata.name,
3389
+ color: agentDef.metadata.color ?? "#6b7280"
3390
+ }
3391
+ })
3392
+ );
3393
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: promptMsgId } });
3394
+ if (onMessage) {
3395
+ onMessage(
3396
+ createChatMessageMessage({
3397
+ id: promptMsgId,
3398
+ role: "user",
3399
+ content: prompt,
3400
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3275
3401
  isSystemGenerated: true,
3276
3402
  messageKind: "auto-prompt",
3277
3403
  subAgentId,
@@ -3283,28 +3409,8 @@ async function executeSubAgent(options) {
3283
3409
  }
3284
3410
  })
3285
3411
  );
3286
- eventStore.append(sessionId, { type: "message.done", data: { messageId: msgId } });
3287
- if (onMessage) {
3288
- onMessage(
3289
- createChatMessageMessage({
3290
- id: msgId,
3291
- role: "user",
3292
- content: msg.content,
3293
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3294
- isSystemGenerated: true,
3295
- messageKind: "auto-prompt",
3296
- subAgentId,
3297
- subAgentType,
3298
- metadata: {
3299
- type: "subagent",
3300
- name: agentDef.metadata.name,
3301
- color: agentDef.metadata.color ?? "#6b7280"
3302
- }
3303
- })
3304
- );
3305
- }
3306
3412
  }
3307
- const { files } = await getAllInstructions(session.workdir, session.projectId);
3413
+ const { content: instructionContent, files } = await getAllInstructions(session.workdir, session.projectId);
3308
3414
  const injectedFiles = toInjectedFiles(files);
3309
3415
  const configDir = getGlobalConfigDir(getRuntimeConfig().mode ?? "production");
3310
3416
  const skills = await getEnabledSkillMetadata(configDir);
@@ -3314,7 +3420,7 @@ async function executeSubAgent(options) {
3314
3420
  skills.length > 0 ? skills : void 0,
3315
3421
  llmClient.getModel()
3316
3422
  );
3317
- let customMessages = [...contextMessages];
3423
+ const subAgentScope = { type: "subagent", sessionId, subAgentId, subAgentType };
3318
3424
  let consecutiveEmptyStops = 0;
3319
3425
  let finalContent;
3320
3426
  let returnValueContent = null;
@@ -3324,13 +3430,7 @@ async function executeSubAgent(options) {
3324
3430
  if (signal?.aborted) {
3325
3431
  throw new Error("Aborted");
3326
3432
  }
3327
- await maybeAutoCompactContext({
3328
- sessionManager,
3329
- sessionId,
3330
- llmClient,
3331
- statsIdentity: resolveCompactionStatsIdentity(llmClient),
3332
- ...signal ? { signal } : {}
3333
- });
3433
+ const requestMessages = getConversationMessages(subAgentScope);
3334
3434
  const assistantMsgId = crypto.randomUUID();
3335
3435
  eventStore.append(
3336
3436
  sessionId,
@@ -3344,19 +3444,29 @@ async function executeSubAgent(options) {
3344
3444
  systemPrompt,
3345
3445
  injectedFiles,
3346
3446
  prompt,
3347
- customMessages,
3447
+ requestMessages,
3348
3448
  toolRegistry.definitions
3349
3449
  );
3450
+ const assembledRequest = assembleAgentRequest({
3451
+ agentDef,
3452
+ subAgentDefs: [],
3453
+ workdir: session.workdir,
3454
+ messages: requestMessages,
3455
+ injectedFiles,
3456
+ promptTools: toolRegistry.definitions,
3457
+ requestTools: toolRegistry.definitions,
3458
+ toolChoice: "auto",
3459
+ disableThinking: true,
3460
+ ...instructionContent ? { customInstructions: instructionContent } : {},
3461
+ ...skills.length > 0 ? { skills } : {},
3462
+ modelName: llmClient.getModel()
3463
+ });
3464
+ const effectiveSystemPrompt = assembledRequest.systemPrompt + RETURN_VALUE_INSTRUCTION;
3350
3465
  const streamGen = streamLLMPure({
3351
3466
  messageId: assistantMsgId,
3352
- systemPrompt: systemPrompt + RETURN_VALUE_INSTRUCTION,
3467
+ systemPrompt: effectiveSystemPrompt,
3353
3468
  llmClient,
3354
- messages: customMessages.map((m) => ({
3355
- role: m.role,
3356
- content: m.content,
3357
- ...m.toolCalls ? { toolCalls: m.toolCalls.map((tc) => ({ id: tc.id, name: tc.name, arguments: tc.arguments })) } : {},
3358
- ...m.toolCallId ? { toolCallId: m.toolCallId } : {}
3359
- })),
3469
+ messages: assembledRequest.messages,
3360
3470
  tools: toolRegistry.definitions,
3361
3471
  toolChoice: "auto",
3362
3472
  signal,
@@ -3379,14 +3489,7 @@ async function executeSubAgent(options) {
3379
3489
  throw new Error("Aborted");
3380
3490
  }
3381
3491
  turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens, result.modelParams);
3382
- sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens, subAgentId);
3383
3492
  finalContent = result.content;
3384
- customMessages.push({
3385
- role: "assistant",
3386
- content: result.content,
3387
- source: "history",
3388
- ...result.toolCalls.length > 0 && { toolCalls: result.toolCalls }
3389
- });
3390
3493
  session = sessionManager.requireSession(sessionId);
3391
3494
  if (result.toolCalls.length === 0) {
3392
3495
  if (nudgeConfig) {
@@ -3406,7 +3509,6 @@ async function executeSubAgent(options) {
3406
3509
  subAgentId,
3407
3510
  subAgentType
3408
3511
  });
3409
- customMessages = [...customMessages, { role: "user", content: nudgeContent, source: "runtime" }];
3410
3512
  continue;
3411
3513
  }
3412
3514
  const stalledMsgId = crypto.randomUUID();
@@ -3436,7 +3538,6 @@ async function executeSubAgent(options) {
3436
3538
  subAgentId,
3437
3539
  subAgentType
3438
3540
  });
3439
- customMessages = [...customMessages, { role: "user", content: RETURN_VALUE_NUDGE, source: "runtime" }];
3440
3541
  continue;
3441
3542
  }
3442
3543
  const stats = turnMetrics.buildStats(statsIdentity, "verifier");
@@ -3488,7 +3589,6 @@ async function executeSubAgent(options) {
3488
3589
  }
3489
3590
  break;
3490
3591
  }
3491
- customMessages = [...customMessages, ...batchResult.toolMessages];
3492
3592
  session = sessionManager.requireSession(sessionId);
3493
3593
  if (nudgeConfig) {
3494
3594
  consecutiveEmptyStops = 0;
@@ -3575,7 +3675,7 @@ var callSubAgentTool = {
3575
3675
  };
3576
3676
  }
3577
3677
  try {
3578
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-BHYHS3RY.js");
3678
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-6DXPHBUV.js");
3579
3679
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3580
3680
  const turnMetrics = new TurnMetrics();
3581
3681
  const result = await executeSubAgent({
@@ -4559,9 +4659,6 @@ function getCurrentWindowMessageOptions3(sessionId) {
4559
4659
  const contextWindowId = getCurrentContextWindowId(sessionId);
4560
4660
  return contextWindowId ? { contextWindowId } : void 0;
4561
4661
  }
4562
- function toRequestContextMessages2(messages) {
4563
- return minimalMessagesToRequestContextMessages(messages, "history");
4564
- }
4565
4662
  async function maybeAutoCompactContext(options) {
4566
4663
  const config = getRuntimeConfig();
4567
4664
  const contextState = options.sessionManager.getContextState(options.sessionId);
@@ -4608,7 +4705,7 @@ async function performContextCompaction(options) {
4608
4705
  const session = sessionManager.requireSession(sessionId);
4609
4706
  const { content: instructions, files } = await getAllInstructions(session.workdir, session.projectId);
4610
4707
  const injectedFiles = toInjectedFiles(files);
4611
- const requestMessages = toRequestContextMessages2(getContextMessages(sessionId));
4708
+ const requestMessages = getConversationMessages({ type: "toplevel", sessionId });
4612
4709
  const config = getRuntimeConfig();
4613
4710
  const allAgents = await loadAllAgentsDefault();
4614
4711
  const plannerDef = findAgentById("planner", allAgents);
@@ -4767,4 +4864,4 @@ export {
4767
4864
  getToolRegistryForAgent,
4768
4865
  createToolRegistry
4769
4866
  };
4770
- //# sourceMappingURL=chunk-H5EICXF3.js.map
4867
+ //# sourceMappingURL=chunk-GLVNO4DS.js.map
@@ -13,14 +13,14 @@ import {
13
13
  getToolRegistryForAgent,
14
14
  loadAllAgentsDefault,
15
15
  runTopLevelAgentLoop
16
- } from "./chunk-H5EICXF3.js";
16
+ } from "./chunk-GLVNO4DS.js";
17
17
  import {
18
18
  getCurrentContextWindowId,
19
19
  getEventStore
20
- } from "./chunk-5ZD3GZTK.js";
20
+ } from "./chunk-RJRG2VER.js";
21
21
  import {
22
22
  buildSnapshotFromSessionState
23
- } from "./chunk-VAMTEAYI.js";
23
+ } from "./chunk-TS5XFQ2D.js";
24
24
  import {
25
25
  logger
26
26
  } from "./chunk-K44MW7JJ.js";
@@ -327,4 +327,4 @@ export {
327
327
  runBuilderTurn,
328
328
  runVerifierTurn
329
329
  };
330
- //# sourceMappingURL=chunk-NHJ2GVCF.js.map
330
+ //# sourceMappingURL=chunk-NWXLRRDD.js.map
@@ -9,7 +9,7 @@ import {
9
9
  foldSessionState,
10
10
  spreadOptionalMessageFields,
11
11
  stripPromptContextMessages
12
- } from "./chunk-VAMTEAYI.js";
12
+ } from "./chunk-TS5XFQ2D.js";
13
13
  import {
14
14
  getRuntimeConfig
15
15
  } from "./chunk-B5AP3RSV.js";
@@ -316,6 +316,19 @@ var EventStore = class {
316
316
  const result = this.db.prepare(`DELETE FROM events WHERE session_id = ? AND seq <= ?`).run(sessionId, upToSeq);
317
317
  return result.changes;
318
318
  }
319
+ /**
320
+ * Delete all events after a given sequence number (exclusive).
321
+ * Retains session.initialized (seq 1) and any events at/below fromSeq.
322
+ * Used when truncating session history.
323
+ *
324
+ * @param sessionId - The session ID
325
+ * @param fromSeq - Events with seq > fromSeq will be deleted
326
+ * @returns The number of events deleted
327
+ */
328
+ deleteEventsAfterSeq(sessionId, fromSeq) {
329
+ const result = this.db.prepare(`DELETE FROM events WHERE session_id = ? AND seq > ?`).run(sessionId, fromSeq);
330
+ return result.changes;
331
+ }
319
332
  /**
320
333
  * Clean up old events, keeping only:
321
334
  * - session.initialized event (seq 1)
@@ -1089,6 +1102,23 @@ function emitTurnSnapshot(sessionId, snapshot) {
1089
1102
  data: snapshot
1090
1103
  });
1091
1104
  }
1105
+ function truncateSessionMessages(sessionId, messageIndex) {
1106
+ const eventStore = getEventStore();
1107
+ const snapshotEvent = eventStore.getLatestSnapshot(sessionId);
1108
+ if (!snapshotEvent) return;
1109
+ const snapshot = snapshotEvent.data;
1110
+ const messages = snapshot.messages;
1111
+ const lastKept = messageIndex + 1;
1112
+ if (lastKept < 1 || lastKept >= messages.length) return;
1113
+ snapshot.messages = messages.slice(0, lastKept);
1114
+ eventStore.deleteEventsAfterSeq(sessionId, snapshotEvent.seq);
1115
+ eventStore.append(sessionId, {
1116
+ type: "turn.snapshot",
1117
+ data: snapshot
1118
+ });
1119
+ const removed = messages.length - messageIndex;
1120
+ updateSessionMessageCount(sessionId, -removed);
1121
+ }
1092
1122
  function compactContext(sessionId, summary, beforeTokens) {
1093
1123
  const state = getSessionState(sessionId);
1094
1124
  if (!state) {
@@ -1218,7 +1248,8 @@ export {
1218
1248
  emitChatError,
1219
1249
  emitFormatRetry,
1220
1250
  emitTurnSnapshot,
1251
+ truncateSessionMessages,
1221
1252
  compactContext,
1222
1253
  getRecentUserPromptsForSession
1223
1254
  };
1224
- //# sourceMappingURL=chunk-5ZD3GZTK.js.map
1255
+ //# sourceMappingURL=chunk-RJRG2VER.js.map