@dexto/core 1.9.2 → 1.9.3

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.
@@ -27,6 +27,7 @@ var ContextErrorCode = /* @__PURE__ */ ((ContextErrorCode2) => {
27
27
  ContextErrorCode2["USER_MESSAGE_CONTENT_INVALID"] = "context_user_message_content_invalid";
28
28
  ContextErrorCode2["ASSISTANT_MESSAGE_CONTENT_OR_TOOLS_REQUIRED"] = "context_assistant_message_content_or_tools_required";
29
29
  ContextErrorCode2["ASSISTANT_MESSAGE_TOOL_CALLS_INVALID"] = "context_assistant_message_tool_calls_invalid";
30
+ ContextErrorCode2["ASSISTANT_MESSAGE_ID_MISSING"] = "context_assistant_message_id_missing";
30
31
  ContextErrorCode2["TOOL_MESSAGE_FIELDS_MISSING"] = "context_tool_message_fields_missing";
31
32
  ContextErrorCode2["TOOL_CALL_ID_NAME_REQUIRED"] = "context_tool_call_id_name_required";
32
33
  ContextErrorCode2["SYSTEM_MESSAGE_CONTENT_INVALID"] = "context_system_message_content_invalid";
@@ -8,6 +8,7 @@ export declare enum ContextErrorCode {
8
8
  USER_MESSAGE_CONTENT_INVALID = "context_user_message_content_invalid",
9
9
  ASSISTANT_MESSAGE_CONTENT_OR_TOOLS_REQUIRED = "context_assistant_message_content_or_tools_required",
10
10
  ASSISTANT_MESSAGE_TOOL_CALLS_INVALID = "context_assistant_message_tool_calls_invalid",
11
+ ASSISTANT_MESSAGE_ID_MISSING = "context_assistant_message_id_missing",
11
12
  TOOL_MESSAGE_FIELDS_MISSING = "context_tool_message_fields_missing",
12
13
  TOOL_CALL_ID_NAME_REQUIRED = "context_tool_call_id_name_required",
13
14
  SYSTEM_MESSAGE_CONTENT_INVALID = "context_system_message_content_invalid",
@@ -1 +1 @@
1
- {"version":3,"file":"error-codes.d.ts","sourceRoot":"","sources":["../../src/context/error-codes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,gBAAgB;IAExB,oBAAoB,iCAAiC;IACrD,qBAAqB,kCAAkC;IAGvD,4BAA4B,yCAAyC;IAGrE,2CAA2C,wDAAwD;IACnG,oCAAoC,iDAAiD;IAGrF,2BAA2B,wCAAwC;IACnE,0BAA0B,uCAAuC;IAGjE,8BAA8B,2CAA2C;IAEzE,kBAAkB,+BAA+B;IAMjD,wBAAwB,qCAAqC;IAC7D,qBAAqB,kCAAkC;IACvD,uBAAuB,oCAAoC;IAC3D,qBAAqB,kCAAkC;IACvD,sBAAsB,mCAAmC;IACzD,sCAAsC,mDAAmD;IAGzF,iBAAiB,8BAA8B;IAC/C,qBAAqB,kCAAkC;IACvD,4BAA4B,yCAAyC;CACxE"}
1
+ {"version":3,"file":"error-codes.d.ts","sourceRoot":"","sources":["../../src/context/error-codes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,gBAAgB;IAExB,oBAAoB,iCAAiC;IACrD,qBAAqB,kCAAkC;IAGvD,4BAA4B,yCAAyC;IAGrE,2CAA2C,wDAAwD;IACnG,oCAAoC,iDAAiD;IACrF,4BAA4B,yCAAyC;IAGrE,2BAA2B,wCAAwC;IACnE,0BAA0B,uCAAuC;IAGjE,8BAA8B,2CAA2C;IAEzE,kBAAkB,+BAA+B;IAMjD,wBAAwB,qCAAqC;IAC7D,qBAAqB,kCAAkC;IACvD,uBAAuB,oCAAoC;IAC3D,qBAAqB,kCAAkC;IACvD,sBAAsB,mCAAmC;IACzD,sCAAsC,mDAAmD;IAGzF,iBAAiB,8BAA8B;IAC/C,qBAAqB,kCAAkC;IACvD,4BAA4B,yCAAyC;CACxE"}
@@ -5,6 +5,7 @@ var ContextErrorCode = /* @__PURE__ */ ((ContextErrorCode2) => {
5
5
  ContextErrorCode2["USER_MESSAGE_CONTENT_INVALID"] = "context_user_message_content_invalid";
6
6
  ContextErrorCode2["ASSISTANT_MESSAGE_CONTENT_OR_TOOLS_REQUIRED"] = "context_assistant_message_content_or_tools_required";
7
7
  ContextErrorCode2["ASSISTANT_MESSAGE_TOOL_CALLS_INVALID"] = "context_assistant_message_tool_calls_invalid";
8
+ ContextErrorCode2["ASSISTANT_MESSAGE_ID_MISSING"] = "context_assistant_message_id_missing";
8
9
  ContextErrorCode2["TOOL_MESSAGE_FIELDS_MISSING"] = "context_tool_message_fields_missing";
9
10
  ContextErrorCode2["TOOL_CALL_ID_NAME_REQUIRED"] = "context_tool_call_id_name_required";
10
11
  ContextErrorCode2["SYSTEM_MESSAGE_CONTENT_INVALID"] = "context_system_message_content_invalid";
@@ -66,6 +66,16 @@ class ContextError {
66
66
  "Ensure toolCalls have proper structure with function name and arguments"
67
67
  );
68
68
  }
69
+ static assistantMessageIdMissing() {
70
+ return new import_errors.DextoRuntimeError(
71
+ import_error_codes.ContextErrorCode.ASSISTANT_MESSAGE_ID_MISSING,
72
+ import_types.ErrorScope.CONTEXT,
73
+ import_types.ErrorType.SYSTEM,
74
+ "Expected assistant message id after saving message",
75
+ {},
76
+ "Check conversation store saveMessage behavior"
77
+ );
78
+ }
69
79
  static toolMessageFieldsMissing() {
70
80
  return new import_errors.DextoRuntimeError(
71
81
  import_error_codes.ContextErrorCode.TOOL_MESSAGE_FIELDS_MISSING,
@@ -8,6 +8,7 @@ export declare class ContextError {
8
8
  static userMessageContentInvalid(): DextoRuntimeError<{}>;
9
9
  static assistantMessageContentOrToolsRequired(): DextoRuntimeError<{}>;
10
10
  static assistantMessageToolCallsInvalid(): DextoRuntimeError<{}>;
11
+ static assistantMessageIdMissing(): DextoRuntimeError<{}>;
11
12
  static toolMessageFieldsMissing(): DextoRuntimeError<{}>;
12
13
  static systemMessageContentInvalid(): DextoRuntimeError<{}>;
13
14
  static userMessageContentEmpty(): DextoRuntimeError<{}>;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/context/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAIvD;;;GAGG;AACH,qBAAa,YAAY;IAErB,MAAM,CAAC,kBAAkB;IAWzB,MAAM,CAAC,yBAAyB;IAWhC,MAAM,CAAC,sCAAsC;IAW7C,MAAM,CAAC,gCAAgC;IAWvC,MAAM,CAAC,wBAAwB;IAW/B,MAAM,CAAC,2BAA2B;IAWlC,MAAM,CAAC,uBAAuB;IAW9B,MAAM,CAAC,sBAAsB;IAe7B,MAAM,CAAC,sBAAsB;IAW7B,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM;;;IAWrC,MAAM,CAAC,mBAAmB;IAW1B,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;;;;IAW9D,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;;;;IAWzD,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM;;;IAWxC,MAAM,CAAC,mCAAmC,CAAC,IAAI,EAAE,MAAM;;;IAYvD,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM;;;IAUxC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM;;;IAU5C,MAAM,CAAC,yBAAyB;CASnC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/context/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAIvD;;;GAGG;AACH,qBAAa,YAAY;IAErB,MAAM,CAAC,kBAAkB;IAWzB,MAAM,CAAC,yBAAyB;IAWhC,MAAM,CAAC,sCAAsC;IAW7C,MAAM,CAAC,gCAAgC;IAWvC,MAAM,CAAC,yBAAyB;IAWhC,MAAM,CAAC,wBAAwB;IAW/B,MAAM,CAAC,2BAA2B;IAWlC,MAAM,CAAC,uBAAuB;IAW9B,MAAM,CAAC,sBAAsB;IAe7B,MAAM,CAAC,sBAAsB;IAW7B,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM;;;IAWrC,MAAM,CAAC,mBAAmB;IAW1B,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;;;;IAW9D,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;;;;IAWzD,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM;;;IAWxC,MAAM,CAAC,mCAAmC,CAAC,IAAI,EAAE,MAAM;;;IAYvD,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM;;;IAUxC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM;;;IAU5C,MAAM,CAAC,yBAAyB;CASnC"}
@@ -44,6 +44,16 @@ class ContextError {
44
44
  "Ensure toolCalls have proper structure with function name and arguments"
45
45
  );
46
46
  }
47
+ static assistantMessageIdMissing() {
48
+ return new DextoRuntimeError(
49
+ ContextErrorCode.ASSISTANT_MESSAGE_ID_MISSING,
50
+ ErrorScope.CONTEXT,
51
+ ErrorType.SYSTEM,
52
+ "Expected assistant message id after saving message",
53
+ {},
54
+ "Check conversation store saveMessage behavior"
55
+ );
56
+ }
47
57
  static toolMessageFieldsMissing() {
48
58
  return new DextoRuntimeError(
49
59
  ContextErrorCode.TOOL_MESSAGE_FIELDS_MISSING,
@@ -74,7 +74,7 @@ class ContextManager {
74
74
  */
75
75
  lastActualOutputTokens = null;
76
76
  /**
77
- * Message count at the time of the last LLM call.
77
+ * Model-visible message count at the time of the last LLM call.
78
78
  * Used to identify which messages are "new" since the last call.
79
79
  * Messages after this index are estimated with length/4 heuristic.
80
80
  */
@@ -321,19 +321,21 @@ class ContextManager {
321
321
  this.logger.debug(`Updated lastActualOutputTokens: ${tokens}`);
322
322
  }
323
323
  /**
324
- * Returns the message count at the time of the last LLM call.
324
+ * Returns the model-visible message count at the time of the last LLM call.
325
325
  * Returns null if no LLM call has been made yet.
326
326
  */
327
327
  getLastCallMessageCount() {
328
328
  return this.lastCallMessageCount;
329
329
  }
330
330
  /**
331
- * Records the current message count after an LLM call completes.
331
+ * Records the current model-visible message count after an LLM call completes.
332
332
  * This marks the boundary for "new messages" calculation.
333
333
  */
334
334
  async recordLastCallMessageCount() {
335
- const history = await this.conversationStore.listMessages({ sessionId: this.sessionId });
336
- this.lastCallMessageCount = history.length;
335
+ const history = await this.conversationStore.loadModelHistory({
336
+ sessionId: this.sessionId
337
+ });
338
+ this.lastCallMessageCount = history.messages.length;
337
339
  this.logger.debug(`Recorded lastCallMessageCount: ${this.lastCallMessageCount}`);
338
340
  }
339
341
  /**
@@ -371,9 +373,36 @@ class ContextManager {
371
373
  const fullHistory = await this.conversationStore.listMessages({
372
374
  sessionId: this.sessionId
373
375
  });
374
- const originalCount = fullHistory.length;
376
+ return this.prepareVisibleHistory({
377
+ history: (0, import_utils.filterCompacted)(fullHistory),
378
+ originalCount: fullHistory.length,
379
+ source: "prepareHistory"
380
+ });
381
+ }
382
+ /**
383
+ * Prepares model-visible history without first materializing the whole durable session.
384
+ * This is the model execution boundary; Worker/Workflow model calls should use this
385
+ * method instead of prepareHistory().
386
+ */
387
+ async prepareModelHistory() {
388
+ const modelHistory = await this.conversationStore.loadModelHistory({
389
+ sessionId: this.sessionId
390
+ });
391
+ return this.prepareVisibleHistory({
392
+ history: modelHistory.messages,
393
+ originalCount: modelHistory.stats.returnedMessages + modelHistory.stats.skippedPreSummaryMessages,
394
+ source: "prepareModelHistory"
395
+ });
396
+ }
397
+ async getModelHistory() {
398
+ const modelHistory = await this.conversationStore.loadModelHistory({
399
+ sessionId: this.sessionId
400
+ });
401
+ return modelHistory.messages;
402
+ }
403
+ prepareVisibleHistory(input) {
375
404
  const visibleToolCallIds = /* @__PURE__ */ new Set();
376
- let history = (0, import_utils.filterCompacted)(fullHistory).filter((message) => {
405
+ let history = input.history.filter((message) => {
377
406
  const isVisible = isVisibleInPreparedHistory(message);
378
407
  if (isVisible && message.role === "assistant") {
379
408
  for (const toolCall of message.toolCalls ?? []) {
@@ -386,9 +415,9 @@ class ContextManager {
386
415
  return message.role !== "tool" || visibleToolCallIds.has(message.toolCallId);
387
416
  });
388
417
  const filteredCount = history.length;
389
- if (filteredCount < originalCount) {
418
+ if (filteredCount < input.originalCount) {
390
419
  this.logger.debug(
391
- `prepareHistory: reduced from ${originalCount} to ${filteredCount} model-visible messages`
420
+ `${input.source}: reduced from ${input.originalCount} to ${filteredCount} model-visible messages`
392
421
  );
393
422
  }
394
423
  let prunedToolCount = 0;
@@ -406,13 +435,13 @@ class ContextManager {
406
435
  });
407
436
  if (prunedToolCount > 0) {
408
437
  this.logger.debug(
409
- `prepareHistory: Transformed ${prunedToolCount} pruned tool messages to placeholders`
438
+ `${input.source}: Transformed ${prunedToolCount} pruned tool messages to placeholders`
410
439
  );
411
440
  }
412
441
  return {
413
442
  preparedHistory: history,
414
443
  stats: {
415
- originalCount,
444
+ originalCount: input.originalCount,
416
445
  filteredCount,
417
446
  prunedToolCount
418
447
  }
@@ -642,8 +671,11 @@ ${prompt}`);
642
671
  `ContextManager: Adding message to conversation store: ${JSON.stringify(message, null, 2)}`
643
672
  );
644
673
  await this.conversationStore.saveMessage({ sessionId: this.sessionId, message });
645
- const history = await this.conversationStore.listMessages({ sessionId: this.sessionId });
646
- this.logger.debug(`ContextManager: History now contains ${history.length} messages`);
674
+ this.logger.debug("ContextManager: Message saved to conversation store", {
675
+ messageId: message.id,
676
+ role: message.role
677
+ });
678
+ return message;
647
679
  }
648
680
  /**
649
681
  * Adds a user message to the conversation.
@@ -689,7 +721,7 @@ ${prompt}`);
689
721
  throw import_errors.ContextError.assistantMessageContentOrToolsRequired();
690
722
  }
691
723
  const contentArray = content !== null ? [{ type: "text", text: content }] : null;
692
- await this.addMessage({
724
+ const message = await this.addMessage({
693
725
  role: "assistant",
694
726
  content: contentArray,
695
727
  ...toolCalls && toolCalls.length > 0 && { toolCalls },
@@ -702,6 +734,10 @@ ${prompt}`);
702
734
  ...metadata?.usageScopeId && { usageScopeId: metadata.usageScopeId },
703
735
  assistantOutput: metadata?.assistantOutput ?? { status: "complete" }
704
736
  });
737
+ if (message.id === void 0) {
738
+ throw import_errors.ContextError.assistantMessageIdMissing();
739
+ }
740
+ return message.id;
705
741
  }
706
742
  /**
707
743
  * Adds a tool result message to the conversation.
@@ -853,7 +889,7 @@ ${prompt}`);
853
889
  */
854
890
  async getFormattedMessagesForLLM(contributorContext, llmContext) {
855
891
  const systemPrompt = await this.getSystemPrompt(contributorContext);
856
- const { preparedHistory } = await this.prepareHistory();
892
+ const { preparedHistory } = await this.prepareModelHistory();
857
893
  const formattedMessages = await this.getFormattedMessages(
858
894
  contributorContext,
859
895
  llmContext,
@@ -868,7 +904,8 @@ ${prompt}`);
868
904
  }
869
905
  /**
870
906
  * Estimates context token usage for the /context command and compaction decisions.
871
- * Uses the same prepareHistory() logic as getFormattedMessagesForLLM() to ensure consistency.
907
+ * Uses the same model-history preparation logic as getFormattedMessagesForLLM() to ensure
908
+ * consistency.
872
909
  *
873
910
  * When actuals are available from previous LLM calls:
874
911
  * estimatedNextInput = lastInputTokens + lastOutputTokens + newMessagesEstimate
@@ -886,13 +923,18 @@ ${prompt}`);
886
923
  */
887
924
  async getContextTokenEstimate(contributorContext, tools) {
888
925
  const systemPrompt = await this.getSystemPrompt(contributorContext);
889
- const { preparedHistory, stats } = await this.prepareHistory();
926
+ const modelHistory = await this.conversationStore.loadModelHistory({
927
+ sessionId: this.sessionId
928
+ });
929
+ const { preparedHistory, stats } = this.prepareVisibleHistory({
930
+ history: modelHistory.messages,
931
+ originalCount: modelHistory.stats.returnedMessages + modelHistory.stats.skippedPreSummaryMessages,
932
+ source: "getContextTokenEstimate"
933
+ });
890
934
  const lastInput = this.lastActualInputTokens;
891
935
  const lastOutput = this.lastActualOutputTokens;
892
936
  const lastMsgCount = this.lastCallMessageCount;
893
- const currentHistory = await this.conversationStore.listMessages({
894
- sessionId: this.sessionId
895
- });
937
+ const currentHistory = modelHistory.messages;
896
938
  const pureEstimate = (0, import_utils.estimateContextTokens)(systemPrompt, preparedHistory, tools);
897
939
  let total;
898
940
  let calculationBasis;
@@ -992,11 +1034,11 @@ ${prompt}`);
992
1034
  const lastInput = this.lastActualInputTokens;
993
1035
  const lastOutput = this.lastActualOutputTokens;
994
1036
  const lastMsgCount = this.lastCallMessageCount;
995
- const currentHistory = await this.conversationStore.listMessages({
996
- sessionId: this.sessionId
997
- });
998
1037
  if (lastInput !== null && lastOutput !== null && lastMsgCount !== null) {
999
- const newMessages = currentHistory.slice(lastMsgCount);
1038
+ const modelHistory = await this.conversationStore.loadModelHistory({
1039
+ sessionId: this.sessionId
1040
+ });
1041
+ const newMessages = modelHistory.messages.slice(lastMsgCount);
1000
1042
  const newMessagesEstimate = (0, import_utils.estimateMessagesTokens)(newMessages);
1001
1043
  const total = lastInput + lastOutput + newMessagesEstimate;
1002
1044
  this.logger.debug(
@@ -9,6 +9,17 @@ import type { ConversationStore } from '../storage/conversation/types.js';
9
9
  import { ValidatedLLMConfig } from '../llm/schemas.js';
10
10
  import type { ToolPresentationSnapshotV1 } from '../tools/types.js';
11
11
  import type { ToolCallMetadata } from '../tools/tool-call-metadata.js';
12
+ export type PreparedHistoryResult = {
13
+ preparedHistory: InternalMessage[];
14
+ stats: {
15
+ /** Total messages in raw or model-history source */
16
+ originalCount: number;
17
+ /** Messages after model-history filters */
18
+ filteredCount: number;
19
+ /** Messages with compactedAt that were transformed to placeholders */
20
+ prunedToolCount: number;
21
+ };
22
+ };
12
23
  /**
13
24
  * Manages conversation history and provides message formatting capabilities for the LLM context.
14
25
  * The ContextManager is responsible for:
@@ -53,7 +64,7 @@ export declare class ContextManager<TMessage = unknown> {
53
64
  */
54
65
  private lastActualOutputTokens;
55
66
  /**
56
- * Message count at the time of the last LLM call.
67
+ * Model-visible message count at the time of the last LLM call.
57
68
  * Used to identify which messages are "new" since the last call.
58
69
  * Messages after this index are estimated with length/4 heuristic.
59
70
  */
@@ -116,12 +127,12 @@ export declare class ContextManager<TMessage = unknown> {
116
127
  */
117
128
  setLastActualOutputTokens(tokens: number): void;
118
129
  /**
119
- * Returns the message count at the time of the last LLM call.
130
+ * Returns the model-visible message count at the time of the last LLM call.
120
131
  * Returns null if no LLM call has been made yet.
121
132
  */
122
133
  getLastCallMessageCount(): number | null;
123
134
  /**
124
- * Records the current message count after an LLM call completes.
135
+ * Records the current model-visible message count after an LLM call completes.
125
136
  * This marks the boundary for "new messages" calculation.
126
137
  */
127
138
  recordLastCallMessageCount(): Promise<void>;
@@ -150,17 +161,15 @@ export declare class ContextManager<TMessage = unknown> {
150
161
  *
151
162
  * @returns Prepared history and statistics about the transformations
152
163
  */
153
- prepareHistory(): Promise<{
154
- preparedHistory: InternalMessage[];
155
- stats: {
156
- /** Total messages in raw history */
157
- originalCount: number;
158
- /** Messages after model-history filters */
159
- filteredCount: number;
160
- /** Messages with compactedAt that were transformed to placeholders */
161
- prunedToolCount: number;
162
- };
163
- }>;
164
+ prepareHistory(): Promise<PreparedHistoryResult>;
165
+ /**
166
+ * Prepares model-visible history without first materializing the whole durable session.
167
+ * This is the model execution boundary; Worker/Workflow model calls should use this
168
+ * method instead of prepareHistory().
169
+ */
170
+ prepareModelHistory(): Promise<PreparedHistoryResult>;
171
+ getModelHistory(): Promise<Readonly<InternalMessage[]>>;
172
+ private prepareVisibleHistory;
164
173
  /**
165
174
  * Assembles and returns the current system prompt by invoking the SystemPromptManager.
166
175
  */
@@ -224,7 +233,7 @@ export declare class ContextManager<TMessage = unknown> {
224
233
  * @param message The message to add to the history
225
234
  * @throws Error if message validation fails
226
235
  */
227
- addMessage(message: InternalMessage): Promise<void>;
236
+ addMessage(message: InternalMessage): Promise<InternalMessage>;
228
237
  /**
229
238
  * Adds a user message to the conversation.
230
239
  * Supports multiple images and files via ContentPart[].
@@ -249,7 +258,7 @@ export declare class ContextManager<TMessage = unknown> {
249
258
  pricingStatus?: AssistantMessage['pricingStatus'];
250
259
  usageScopeId?: AssistantMessage['usageScopeId'];
251
260
  assistantOutput?: AssistantMessage['assistantOutput'];
252
- }): Promise<void>;
261
+ }): Promise<string>;
253
262
  /**
254
263
  * Adds a tool result message to the conversation.
255
264
  * The result must already be sanitized - this method only persists it.
@@ -299,7 +308,8 @@ export declare class ContextManager<TMessage = unknown> {
299
308
  }>;
300
309
  /**
301
310
  * Estimates context token usage for the /context command and compaction decisions.
302
- * Uses the same prepareHistory() logic as getFormattedMessagesForLLM() to ensure consistency.
311
+ * Uses the same model-history preparation logic as getFormattedMessagesForLLM() to ensure
312
+ * consistency.
303
313
  *
304
314
  * When actuals are available from previous LLM calls:
305
315
  * estimatedNextInput = lastInputTokens + lastOutputTokens + newMessagesEstimate
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/context/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAUpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAE1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAYvE;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc,CAAC,QAAQ,GAAG,OAAO;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,+BAA+B,CAAK;IAE5D;;OAEG;IACH,OAAO,CAAC,SAAS,CAAqB;IAEtC;;OAEG;IACH,OAAO,CAAC,mBAAmB,CAAsB;IAEjD;;OAEG;IACH,OAAO,CAAC,SAAS,CAAyB;IAE1C;;OAEG;IACH,OAAO,CAAC,cAAc,CAAS;IAE/B;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAAuB;IAEpD;;;;OAIG;IACH,OAAO,CAAC,sBAAsB,CAAuB;IAErD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAkD;IAEzE,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAYjC,OAAO,CAAC,MAAM,CAAC,kBAAkB;YAyBnB,kBAAkB;IAuGhC;;;;;;;;;;OAUG;gBAEC,SAAS,EAAE,kBAAkB,EAC7B,SAAS,EAAE,sBAAsB,EACjC,mBAAmB,EAAE,mBAAmB,EACxC,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,uBAAuB,EAAE,eAAe,EAChE,MAAM,EAAE,MAAM;IAgBlB;;OAEG;IACI,kBAAkB,IAAI,OAAO,uBAAuB,EAAE,eAAe;IAI5E;;;OAGG;YACW,gBAAgB;IAyF9B;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;;OAGG;IACH,wBAAwB,IAAI,MAAM,GAAG,IAAI;IAIzC;;;OAGG;IACH,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK9C;;;OAGG;IACH,yBAAyB,IAAI,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/C;;;OAGG;IACH,uBAAuB,IAAI,MAAM,GAAG,IAAI;IAIxC;;;OAGG;IACG,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjD;;;OAGG;IACH,wBAAwB,IAAI,IAAI;IAShC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAuC;IAEtF;;;;;;;;;;;;;;OAcG;IACG,cAAc,IAAI,OAAO,CAAC;QAC5B,eAAe,EAAE,eAAe,EAAE,CAAC;QACnC,KAAK,EAAE;YACH,oCAAoC;YACpC,aAAa,EAAE,MAAM,CAAC;YACtB,2CAA2C;YAC3C,aAAa,EAAE,MAAM,CAAC;YACtB,sEAAsE;YACtE,eAAe,EAAE,MAAM,CAAC;SAC3B,CAAC;KACL,CAAC;IA6DF;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;IAM1E;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;IAKxD;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;;;;;;OAQG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBnC;;;OAGG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCzE;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvE;;;OAGG;IACG,sBAAsB,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAClC,OAAO,CAAC,IAAI,CAAC;IAqBhB;;;;;;;;;;;OAWG;IACG,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IA2CpE;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA8EzD;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,OAAO,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgChF;;;;;;;;OAQG;IACG,mBAAmB,CACrB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,CAAC,EAAE,gBAAgB,CAAC,WAAW,CAAC,EACzC,QAAQ,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAClD,aAAa,CAAC,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAClD,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QAChD,eAAe,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;KACzD,GACF,OAAO,CAAC,IAAI,CAAC;IAyBhB;;;;;;;;;;;OAWG;IACG,aAAa,CACf,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,mBAAmB,EACpC,QAAQ,CAAC,EAAE;QACP,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;QACzC,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;QAClD,IAAI,CAAC,EAAE,gBAAgB,CAAC;KAC3B,GACF,OAAO,CAAC,IAAI,CAAC;IAuDhB;;;;;;;;;;;;OAYG;IACG,oBAAoB,CACtB,kBAAkB,EAAE,yBAAyB,EAC7C,UAAU,EAAE,UAAU,EACtB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,CAAC,EAAE,eAAe,EAAE,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC;IA8FtB;;;;;;;;;OASG;IACG,0BAA0B,CAC5B,kBAAkB,EAAE,yBAAyB,EAC7C,UAAU,EAAE,UAAU,GACvB,OAAO,CAAC;QACP,iBAAiB,EAAE,QAAQ,EAAE,CAAC;QAC9B,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,eAAe,EAAE,CAAC;KACtC,CAAC;IAsBF;;;;;;;;;;;;;;;;;OAiBG;IACG,uBAAuB,CACzB,kBAAkB,EAAE,yBAAyB,EAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,GACrF,OAAO,CAAC;QACP,6BAA6B;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,uEAAuE;QACvE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,4BAA4B;QAC5B,SAAS,EAAE;YACP,YAAY,EAAE,MAAM,CAAC;YACrB,KAAK,EAAE;gBACH,KAAK,EAAE,MAAM,CAAC;gBACd,OAAO,EAAE,KAAK,CAAC;oBAAE,IAAI,EAAE,MAAM,CAAC;oBAAC,MAAM,EAAE,MAAM,CAAA;iBAAE,CAAC,CAAC;aACpD,CAAC;YACF,QAAQ,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,wBAAwB;QACxB,KAAK,EAAE;YACH,oBAAoB,EAAE,MAAM,CAAC;YAC7B,oBAAoB,EAAE,MAAM,CAAC;YAC7B,eAAe,EAAE,MAAM,CAAC;SAC3B,CAAC;QACF,8CAA8C;QAC9C,gBAAgB,CAAC,EAAE;YACf,kEAAkE;YAClE,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;YAC/B,iEAAiE;YACjE,eAAe,CAAC,EAAE,MAAM,CAAC;YACzB,kEAAkE;YAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAC1B,iFAAiF;YACjF,mBAAmB,CAAC,EAAE,MAAM,CAAC;SAChC,CAAC;KACL,CAAC;IAiGF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0CG;IACG,2BAA2B,CAC7B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,SAAS,eAAe,EAAE,EAC3C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,GACrF,OAAO,CAAC,MAAM,CAAC;IA0BlB;;;;;;OAMG;IACG,wBAAwB,CAC1B,QAAQ,EAAE,yBAAyB,GACpC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAKrC;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ3C"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/context/manager.ts"],"names":[],"mappings":"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"}
@@ -49,7 +49,7 @@ class ContextManager {
49
49
  */
50
50
  lastActualOutputTokens = null;
51
51
  /**
52
- * Message count at the time of the last LLM call.
52
+ * Model-visible message count at the time of the last LLM call.
53
53
  * Used to identify which messages are "new" since the last call.
54
54
  * Messages after this index are estimated with length/4 heuristic.
55
55
  */
@@ -296,19 +296,21 @@ class ContextManager {
296
296
  this.logger.debug(`Updated lastActualOutputTokens: ${tokens}`);
297
297
  }
298
298
  /**
299
- * Returns the message count at the time of the last LLM call.
299
+ * Returns the model-visible message count at the time of the last LLM call.
300
300
  * Returns null if no LLM call has been made yet.
301
301
  */
302
302
  getLastCallMessageCount() {
303
303
  return this.lastCallMessageCount;
304
304
  }
305
305
  /**
306
- * Records the current message count after an LLM call completes.
306
+ * Records the current model-visible message count after an LLM call completes.
307
307
  * This marks the boundary for "new messages" calculation.
308
308
  */
309
309
  async recordLastCallMessageCount() {
310
- const history = await this.conversationStore.listMessages({ sessionId: this.sessionId });
311
- this.lastCallMessageCount = history.length;
310
+ const history = await this.conversationStore.loadModelHistory({
311
+ sessionId: this.sessionId
312
+ });
313
+ this.lastCallMessageCount = history.messages.length;
312
314
  this.logger.debug(`Recorded lastCallMessageCount: ${this.lastCallMessageCount}`);
313
315
  }
314
316
  /**
@@ -346,9 +348,36 @@ class ContextManager {
346
348
  const fullHistory = await this.conversationStore.listMessages({
347
349
  sessionId: this.sessionId
348
350
  });
349
- const originalCount = fullHistory.length;
351
+ return this.prepareVisibleHistory({
352
+ history: filterCompacted(fullHistory),
353
+ originalCount: fullHistory.length,
354
+ source: "prepareHistory"
355
+ });
356
+ }
357
+ /**
358
+ * Prepares model-visible history without first materializing the whole durable session.
359
+ * This is the model execution boundary; Worker/Workflow model calls should use this
360
+ * method instead of prepareHistory().
361
+ */
362
+ async prepareModelHistory() {
363
+ const modelHistory = await this.conversationStore.loadModelHistory({
364
+ sessionId: this.sessionId
365
+ });
366
+ return this.prepareVisibleHistory({
367
+ history: modelHistory.messages,
368
+ originalCount: modelHistory.stats.returnedMessages + modelHistory.stats.skippedPreSummaryMessages,
369
+ source: "prepareModelHistory"
370
+ });
371
+ }
372
+ async getModelHistory() {
373
+ const modelHistory = await this.conversationStore.loadModelHistory({
374
+ sessionId: this.sessionId
375
+ });
376
+ return modelHistory.messages;
377
+ }
378
+ prepareVisibleHistory(input) {
350
379
  const visibleToolCallIds = /* @__PURE__ */ new Set();
351
- let history = filterCompacted(fullHistory).filter((message) => {
380
+ let history = input.history.filter((message) => {
352
381
  const isVisible = isVisibleInPreparedHistory(message);
353
382
  if (isVisible && message.role === "assistant") {
354
383
  for (const toolCall of message.toolCalls ?? []) {
@@ -361,9 +390,9 @@ class ContextManager {
361
390
  return message.role !== "tool" || visibleToolCallIds.has(message.toolCallId);
362
391
  });
363
392
  const filteredCount = history.length;
364
- if (filteredCount < originalCount) {
393
+ if (filteredCount < input.originalCount) {
365
394
  this.logger.debug(
366
- `prepareHistory: reduced from ${originalCount} to ${filteredCount} model-visible messages`
395
+ `${input.source}: reduced from ${input.originalCount} to ${filteredCount} model-visible messages`
367
396
  );
368
397
  }
369
398
  let prunedToolCount = 0;
@@ -381,13 +410,13 @@ class ContextManager {
381
410
  });
382
411
  if (prunedToolCount > 0) {
383
412
  this.logger.debug(
384
- `prepareHistory: Transformed ${prunedToolCount} pruned tool messages to placeholders`
413
+ `${input.source}: Transformed ${prunedToolCount} pruned tool messages to placeholders`
385
414
  );
386
415
  }
387
416
  return {
388
417
  preparedHistory: history,
389
418
  stats: {
390
- originalCount,
419
+ originalCount: input.originalCount,
391
420
  filteredCount,
392
421
  prunedToolCount
393
422
  }
@@ -617,8 +646,11 @@ ${prompt}`);
617
646
  `ContextManager: Adding message to conversation store: ${JSON.stringify(message, null, 2)}`
618
647
  );
619
648
  await this.conversationStore.saveMessage({ sessionId: this.sessionId, message });
620
- const history = await this.conversationStore.listMessages({ sessionId: this.sessionId });
621
- this.logger.debug(`ContextManager: History now contains ${history.length} messages`);
649
+ this.logger.debug("ContextManager: Message saved to conversation store", {
650
+ messageId: message.id,
651
+ role: message.role
652
+ });
653
+ return message;
622
654
  }
623
655
  /**
624
656
  * Adds a user message to the conversation.
@@ -664,7 +696,7 @@ ${prompt}`);
664
696
  throw ContextError.assistantMessageContentOrToolsRequired();
665
697
  }
666
698
  const contentArray = content !== null ? [{ type: "text", text: content }] : null;
667
- await this.addMessage({
699
+ const message = await this.addMessage({
668
700
  role: "assistant",
669
701
  content: contentArray,
670
702
  ...toolCalls && toolCalls.length > 0 && { toolCalls },
@@ -677,6 +709,10 @@ ${prompt}`);
677
709
  ...metadata?.usageScopeId && { usageScopeId: metadata.usageScopeId },
678
710
  assistantOutput: metadata?.assistantOutput ?? { status: "complete" }
679
711
  });
712
+ if (message.id === void 0) {
713
+ throw ContextError.assistantMessageIdMissing();
714
+ }
715
+ return message.id;
680
716
  }
681
717
  /**
682
718
  * Adds a tool result message to the conversation.
@@ -828,7 +864,7 @@ ${prompt}`);
828
864
  */
829
865
  async getFormattedMessagesForLLM(contributorContext, llmContext) {
830
866
  const systemPrompt = await this.getSystemPrompt(contributorContext);
831
- const { preparedHistory } = await this.prepareHistory();
867
+ const { preparedHistory } = await this.prepareModelHistory();
832
868
  const formattedMessages = await this.getFormattedMessages(
833
869
  contributorContext,
834
870
  llmContext,
@@ -843,7 +879,8 @@ ${prompt}`);
843
879
  }
844
880
  /**
845
881
  * Estimates context token usage for the /context command and compaction decisions.
846
- * Uses the same prepareHistory() logic as getFormattedMessagesForLLM() to ensure consistency.
882
+ * Uses the same model-history preparation logic as getFormattedMessagesForLLM() to ensure
883
+ * consistency.
847
884
  *
848
885
  * When actuals are available from previous LLM calls:
849
886
  * estimatedNextInput = lastInputTokens + lastOutputTokens + newMessagesEstimate
@@ -861,13 +898,18 @@ ${prompt}`);
861
898
  */
862
899
  async getContextTokenEstimate(contributorContext, tools) {
863
900
  const systemPrompt = await this.getSystemPrompt(contributorContext);
864
- const { preparedHistory, stats } = await this.prepareHistory();
901
+ const modelHistory = await this.conversationStore.loadModelHistory({
902
+ sessionId: this.sessionId
903
+ });
904
+ const { preparedHistory, stats } = this.prepareVisibleHistory({
905
+ history: modelHistory.messages,
906
+ originalCount: modelHistory.stats.returnedMessages + modelHistory.stats.skippedPreSummaryMessages,
907
+ source: "getContextTokenEstimate"
908
+ });
865
909
  const lastInput = this.lastActualInputTokens;
866
910
  const lastOutput = this.lastActualOutputTokens;
867
911
  const lastMsgCount = this.lastCallMessageCount;
868
- const currentHistory = await this.conversationStore.listMessages({
869
- sessionId: this.sessionId
870
- });
912
+ const currentHistory = modelHistory.messages;
871
913
  const pureEstimate = estimateContextTokens(systemPrompt, preparedHistory, tools);
872
914
  let total;
873
915
  let calculationBasis;
@@ -967,11 +1009,11 @@ ${prompt}`);
967
1009
  const lastInput = this.lastActualInputTokens;
968
1010
  const lastOutput = this.lastActualOutputTokens;
969
1011
  const lastMsgCount = this.lastCallMessageCount;
970
- const currentHistory = await this.conversationStore.listMessages({
971
- sessionId: this.sessionId
972
- });
973
1012
  if (lastInput !== null && lastOutput !== null && lastMsgCount !== null) {
974
- const newMessages = currentHistory.slice(lastMsgCount);
1013
+ const modelHistory = await this.conversationStore.loadModelHistory({
1014
+ sessionId: this.sessionId
1015
+ });
1016
+ const newMessages = modelHistory.messages.slice(lastMsgCount);
975
1017
  const newMessagesEstimate = estimateMessagesTokens(newMessages);
976
1018
  const total = lastInput + lastOutput + newMessagesEstimate;
977
1019
  this.logger.debug(
@@ -147,11 +147,13 @@ class StreamProcessor {
147
147
  setStreamAttribute("last_delta_received_ms", lastDeltaReceivedAtMs);
148
148
  setStreamAttribute("last_delta_kind", "text");
149
149
  if (!this.assistantMessageId) {
150
- this.assistantMessageId = await this.contextManager.addAssistantMessage("", [], {
151
- assistantOutput: { status: "draft" }
152
- }).then(() => {
153
- return this.getLastMessageId();
154
- });
150
+ this.assistantMessageId = await this.contextManager.addAssistantMessage(
151
+ "",
152
+ [],
153
+ {
154
+ assistantOutput: { status: "draft" }
155
+ }
156
+ );
155
157
  }
156
158
  await this.contextManager.appendAssistantText(
157
159
  this.assistantMessageId,
@@ -565,16 +567,9 @@ class StreamProcessor {
565
567
  this.reasoningMetadata = merged;
566
568
  }
567
569
  async createAssistantMessage() {
568
- await this.contextManager.addAssistantMessage("", [], {
570
+ return this.contextManager.addAssistantMessage("", [], {
569
571
  assistantOutput: { status: "draft" }
570
572
  });
571
- return this.getLastMessageId();
572
- }
573
- async getLastMessageId() {
574
- const history = await this.contextManager.getHistory();
575
- const last = history[history.length - 1];
576
- if (!last || !last.id) throw new Error("Failed to get last message ID");
577
- return last.id;
578
573
  }
579
574
  /**
580
575
  * Persist synthetic "cancelled" results for all pending tool calls.
@@ -58,7 +58,6 @@ export declare class StreamProcessor {
58
58
  private persistAssistantResponseMetadata;
59
59
  private mergeReasoningMetadata;
60
60
  private createAssistantMessage;
61
- private getLastMessageId;
62
61
  /**
63
62
  * Persist synthetic "cancelled" results for all pending tool calls.
64
63
  * This maintains the tool_use/tool_result pairing required by LLM APIs.
@@ -1 +1 @@
1
- {"version":3,"file":"stream-processor.d.ts","sourceRoot":"","sources":["../../../src/llm/executor/stream-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,IAAI,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAmB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAKvD,OAAO,KAAK,EAAE,WAAW,EAAoB,gBAAgB,EAAc,MAAM,YAAY,CAAC;AA4D9F,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,qBAAa,eAAe;IA6BpB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;IAlC3B,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,YAAY,CAAmE;IACvF,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,cAAc,CAAuB;IAC7C;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAgD;IACxE,OAAO,CAAC,gBAAgB,CAAkE;IAE1F;;;;;;;;;OASG;gBAES,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,qBAAqB,EACrC,MAAM,EAAE,MAAM,EACN,SAAS,GAAE,OAAc,EACzB,eAAe,GAAE,OAAc;IAMrC,OAAO,CACT,QAAQ,EAAE,MAAM,gBAAgB,CAAC,aAAa,EAAE,OAAO,CAAC,GACzD,OAAO,CAAC,qBAAqB,CAAC;IAsejC,OAAO,CAAC,kCAAkC;IAoB1C,OAAO,CAAC,cAAc;IA4CtB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,eAAe;YA8BT,gCAAgC;IA4B9C,OAAO,CAAC,sBAAsB;YAwChB,sBAAsB;YAOtB,gBAAgB;IAO9B;;;;OAIG;YACW,2BAA2B;IAQzC;;OAEG;YACW,wBAAwB;YAQxB,yBAAyB;CAuC1C"}
1
+ {"version":3,"file":"stream-processor.d.ts","sourceRoot":"","sources":["../../../src/llm/executor/stream-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,IAAI,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAmB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAKvD,OAAO,KAAK,EAAE,WAAW,EAAoB,gBAAgB,EAAc,MAAM,YAAY,CAAC;AA4D9F,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,qBAAa,eAAe;IA6BpB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;IAlC3B,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,YAAY,CAAmE;IACvF,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,cAAc,CAAuB;IAC7C;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAgD;IACxE,OAAO,CAAC,gBAAgB,CAAkE;IAE1F;;;;;;;;;OASG;gBAES,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,qBAAqB,EACrC,MAAM,EAAE,MAAM,EACN,SAAS,GAAE,OAAc,EACzB,eAAe,GAAE,OAAc;IAMrC,OAAO,CACT,QAAQ,EAAE,MAAM,gBAAgB,CAAC,aAAa,EAAE,OAAO,CAAC,GACzD,OAAO,CAAC,qBAAqB,CAAC;IAsejC,OAAO,CAAC,kCAAkC;IAoB1C,OAAO,CAAC,cAAc;IA4CtB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,eAAe;YA8BT,gCAAgC;IA4B9C,OAAO,CAAC,sBAAsB;YAwChB,sBAAsB;IAMpC;;;;OAIG;YACW,2BAA2B;IAQzC;;OAEG;YACW,wBAAwB;YAQxB,yBAAyB;CAuC1C"}
@@ -125,11 +125,13 @@ class StreamProcessor {
125
125
  setStreamAttribute("last_delta_received_ms", lastDeltaReceivedAtMs);
126
126
  setStreamAttribute("last_delta_kind", "text");
127
127
  if (!this.assistantMessageId) {
128
- this.assistantMessageId = await this.contextManager.addAssistantMessage("", [], {
129
- assistantOutput: { status: "draft" }
130
- }).then(() => {
131
- return this.getLastMessageId();
132
- });
128
+ this.assistantMessageId = await this.contextManager.addAssistantMessage(
129
+ "",
130
+ [],
131
+ {
132
+ assistantOutput: { status: "draft" }
133
+ }
134
+ );
133
135
  }
134
136
  await this.contextManager.appendAssistantText(
135
137
  this.assistantMessageId,
@@ -543,16 +545,9 @@ class StreamProcessor {
543
545
  this.reasoningMetadata = merged;
544
546
  }
545
547
  async createAssistantMessage() {
546
- await this.contextManager.addAssistantMessage("", [], {
548
+ return this.contextManager.addAssistantMessage("", [], {
547
549
  assistantOutput: { status: "draft" }
548
550
  });
549
- return this.getLastMessageId();
550
- }
551
- async getLastMessageId() {
552
- const history = await this.contextManager.getHistory();
553
- const last = history[history.length - 1];
554
- if (!last || !last.id) throw new Error("Failed to get last message ID");
555
- return last.id;
556
551
  }
557
552
  /**
558
553
  * Persist synthetic "cancelled" results for all pending tool calls.
@@ -976,7 +976,7 @@ class TurnExecutor {
976
976
  }
977
977
  },
978
978
  async () => {
979
- const preparedHistory2 = (await this.contextManager.prepareHistory()).preparedHistory;
979
+ const preparedHistory2 = (await this.contextManager.prepareModelHistory()).preparedHistory;
980
980
  const formattedMessages2 = await this.contextManager.getFormattedMessages(
981
981
  input.contributorContext,
982
982
  this.llmContext,
@@ -1058,7 +1058,7 @@ class TurnExecutor {
1058
1058
  }
1059
1059
  },
1060
1060
  async () => {
1061
- const preparedHistory2 = (await this.contextManager.prepareHistory()).preparedHistory;
1061
+ const preparedHistory2 = (await this.contextManager.prepareModelHistory()).preparedHistory;
1062
1062
  const formattedMessages2 = await this.contextManager.getFormattedMessages(
1063
1063
  input.contributorContext,
1064
1064
  this.llmContext,
@@ -1218,11 +1218,11 @@ class TurnExecutor {
1218
1218
  }
1219
1219
  async runModelStepWithRetry(request) {
1220
1220
  for (let failedAttempts = 0; ; failedAttempts += 1) {
1221
- const historyLengthBefore = (await this.contextManager.getHistory()).length;
1221
+ const historyLengthBefore = (await this.contextManager.getModelHistory()).length;
1222
1222
  try {
1223
1223
  return await this.runModelStep(request);
1224
1224
  } catch (error) {
1225
- const historyLengthAfter = (await this.contextManager.getHistory()).length;
1225
+ const historyLengthAfter = (await this.contextManager.getModelHistory()).length;
1226
1226
  const historyLengthChanged = historyLengthAfter !== historyLengthBefore;
1227
1227
  if (!this.canRetryModelRequest(error, historyLengthChanged) || failedAttempts >= MODEL_REQUEST_MAX_RETRIES) {
1228
1228
  throw error;
@@ -1664,7 +1664,7 @@ class TurnExecutor {
1664
1664
  /**
1665
1665
  * Prunes old tool outputs by marking them with compactedAt timestamp.
1666
1666
  * Does NOT modify content - transformation happens at format time in
1667
- * ContextManager.prepareHistory().
1667
+ * ContextManager.prepareModelHistory().
1668
1668
  *
1669
1669
  * Algorithm:
1670
1670
  * 1. Go backwards through history (most recent first)
@@ -1674,7 +1674,7 @@ class TurnExecutor {
1674
1674
  * 5. Only prune if savings exceed PRUNE_MINIMUM
1675
1675
  */
1676
1676
  async pruneOldToolOutputs() {
1677
- const history = await this.contextManager.getHistory();
1677
+ const history = await this.contextManager.getModelHistory();
1678
1678
  let totalToolTokens = 0;
1679
1679
  let prunedTokens = 0;
1680
1680
  const toPrune = [];
@@ -1776,7 +1776,7 @@ class TurnExecutor {
1776
1776
  this.logger.info(
1777
1777
  `Context overflow detected (${originalTokens} tokens), checking if compression is possible`
1778
1778
  );
1779
- const history = await this.contextManager.getHistory();
1779
+ const history = await this.contextManager.getModelHistory();
1780
1780
  const { filterCompacted } = await import("../../context/utils.js");
1781
1781
  const originalFiltered = filterCompacted(history);
1782
1782
  const originalMessages = originalFiltered.length;
@@ -354,7 +354,7 @@ export declare class TurnExecutor {
354
354
  /**
355
355
  * Prunes old tool outputs by marking them with compactedAt timestamp.
356
356
  * Does NOT modify content - transformation happens at format time in
357
- * ContextManager.prepareHistory().
357
+ * ContextManager.prepareModelHistory().
358
358
  *
359
359
  * Algorithm:
360
360
  * 1. Go backwards through history (most recent first)
@@ -953,7 +953,7 @@ class TurnExecutor {
953
953
  }
954
954
  },
955
955
  async () => {
956
- const preparedHistory2 = (await this.contextManager.prepareHistory()).preparedHistory;
956
+ const preparedHistory2 = (await this.contextManager.prepareModelHistory()).preparedHistory;
957
957
  const formattedMessages2 = await this.contextManager.getFormattedMessages(
958
958
  input.contributorContext,
959
959
  this.llmContext,
@@ -1035,7 +1035,7 @@ class TurnExecutor {
1035
1035
  }
1036
1036
  },
1037
1037
  async () => {
1038
- const preparedHistory2 = (await this.contextManager.prepareHistory()).preparedHistory;
1038
+ const preparedHistory2 = (await this.contextManager.prepareModelHistory()).preparedHistory;
1039
1039
  const formattedMessages2 = await this.contextManager.getFormattedMessages(
1040
1040
  input.contributorContext,
1041
1041
  this.llmContext,
@@ -1195,11 +1195,11 @@ class TurnExecutor {
1195
1195
  }
1196
1196
  async runModelStepWithRetry(request) {
1197
1197
  for (let failedAttempts = 0; ; failedAttempts += 1) {
1198
- const historyLengthBefore = (await this.contextManager.getHistory()).length;
1198
+ const historyLengthBefore = (await this.contextManager.getModelHistory()).length;
1199
1199
  try {
1200
1200
  return await this.runModelStep(request);
1201
1201
  } catch (error) {
1202
- const historyLengthAfter = (await this.contextManager.getHistory()).length;
1202
+ const historyLengthAfter = (await this.contextManager.getModelHistory()).length;
1203
1203
  const historyLengthChanged = historyLengthAfter !== historyLengthBefore;
1204
1204
  if (!this.canRetryModelRequest(error, historyLengthChanged) || failedAttempts >= MODEL_REQUEST_MAX_RETRIES) {
1205
1205
  throw error;
@@ -1641,7 +1641,7 @@ class TurnExecutor {
1641
1641
  /**
1642
1642
  * Prunes old tool outputs by marking them with compactedAt timestamp.
1643
1643
  * Does NOT modify content - transformation happens at format time in
1644
- * ContextManager.prepareHistory().
1644
+ * ContextManager.prepareModelHistory().
1645
1645
  *
1646
1646
  * Algorithm:
1647
1647
  * 1. Go backwards through history (most recent first)
@@ -1651,7 +1651,7 @@ class TurnExecutor {
1651
1651
  * 5. Only prune if savings exceed PRUNE_MINIMUM
1652
1652
  */
1653
1653
  async pruneOldToolOutputs() {
1654
- const history = await this.contextManager.getHistory();
1654
+ const history = await this.contextManager.getModelHistory();
1655
1655
  let totalToolTokens = 0;
1656
1656
  let prunedTokens = 0;
1657
1657
  const toPrune = [];
@@ -1753,7 +1753,7 @@ class TurnExecutor {
1753
1753
  this.logger.info(
1754
1754
  `Context overflow detected (${originalTokens} tokens), checking if compression is possible`
1755
1755
  );
1756
- const history = await this.contextManager.getHistory();
1756
+ const history = await this.contextManager.getModelHistory();
1757
1757
  const { filterCompacted } = await import("../../context/utils.js");
1758
1758
  const originalFiltered = filterCompacted(history);
1759
1759
  const originalMessages = originalFiltered.length;
@@ -22,6 +22,7 @@ __export(database_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(database_exports);
24
24
  var import_content_clone = require("../../context/content-clone.js");
25
+ var import_utils = require("../../context/utils.js");
25
26
  var import_types = require("../../logger/v2/types.js");
26
27
  var import_errors = require("../errors.js");
27
28
  class DatabaseConversationStore {
@@ -37,6 +38,20 @@ class DatabaseConversationStore {
37
38
  const state = await this.loadState(input.sessionId);
38
39
  return (0, import_content_clone.cloneInternalMessages)(state.cache ?? []);
39
40
  }
41
+ async loadModelHistory(input) {
42
+ const fullHistory = await this.listMessages(input);
43
+ const messages = (0, import_utils.filterCompacted)(fullHistory);
44
+ const firstMessage = messages[0];
45
+ const summaryMessageId = firstMessage?.metadata?.isSummary === true || firstMessage?.metadata?.isSessionSummary === true ? firstMessage.id ?? null : null;
46
+ return {
47
+ messages,
48
+ stats: {
49
+ returnedMessages: messages.length,
50
+ skippedPreSummaryMessages: fullHistory.length - messages.length,
51
+ summaryMessageId
52
+ }
53
+ };
54
+ }
40
55
  async saveMessage(input) {
41
56
  const state = await this.loadState(input.sessionId);
42
57
  const cache = state.cache ?? [];
@@ -1,7 +1,7 @@
1
1
  import type { InternalMessage } from '../../context/types.js';
2
2
  import type { Logger } from '../../logger/v2/types.js';
3
3
  import type { Database } from '../database/types.js';
4
- import type { ConversationStore } from './types.js';
4
+ import type { ConversationStore, ModelHistoryLoad } from './types.js';
5
5
  export declare class DatabaseConversationStore implements ConversationStore {
6
6
  private readonly database;
7
7
  private readonly logger;
@@ -12,6 +12,9 @@ export declare class DatabaseConversationStore implements ConversationStore {
12
12
  listMessages(input: {
13
13
  sessionId: string;
14
14
  }): Promise<InternalMessage[]>;
15
+ loadModelHistory(input: {
16
+ sessionId: string;
17
+ }): Promise<ModelHistoryLoad>;
15
18
  saveMessage(input: {
16
19
  sessionId: string;
17
20
  message: InternalMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/storage/conversation/database.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,qBAAa,yBAA0B,YAAW,iBAAiB;IAQ3D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+C;IAEtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGtB,QAAQ,EAAE,QAAQ,EACnC,MAAM,EAAE,MAAM;IAKZ,YAAY,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAKtE,WAAW,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BlF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBpF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB1D,KAAK,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAoB1C,SAAS;IA4BvB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,cAAc;YA6BR,UAAU;IAuBxB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY;CAGvB"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/storage/conversation/database.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAStE,qBAAa,yBAA0B,YAAW,iBAAiB;IAQ3D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+C;IAEtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGtB,QAAQ,EAAE,QAAQ,EACnC,MAAM,EAAE,MAAM;IAKZ,YAAY,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAKtE,gBAAgB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmBzE,WAAW,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BlF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBpF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB1D,KAAK,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAoB1C,SAAS;IA4BvB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,cAAc;YA6BR,UAAU;IAuBxB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY;CAGvB"}
@@ -1,5 +1,6 @@
1
1
  import "../../chunk-C6A6W6XS.js";
2
2
  import { cloneInternalMessage, cloneInternalMessages } from "../../context/content-clone.js";
3
+ import { filterCompacted } from "../../context/utils.js";
3
4
  import { DextoLogComponent } from "../../logger/v2/types.js";
4
5
  import { StorageError } from "../errors.js";
5
6
  class DatabaseConversationStore {
@@ -15,6 +16,20 @@ class DatabaseConversationStore {
15
16
  const state = await this.loadState(input.sessionId);
16
17
  return cloneInternalMessages(state.cache ?? []);
17
18
  }
19
+ async loadModelHistory(input) {
20
+ const fullHistory = await this.listMessages(input);
21
+ const messages = filterCompacted(fullHistory);
22
+ const firstMessage = messages[0];
23
+ const summaryMessageId = firstMessage?.metadata?.isSummary === true || firstMessage?.metadata?.isSessionSummary === true ? firstMessage.id ?? null : null;
24
+ return {
25
+ messages,
26
+ stats: {
27
+ returnedMessages: messages.length,
28
+ skippedPreSummaryMessages: fullHistory.length - messages.length,
29
+ summaryMessageId
30
+ }
31
+ };
32
+ }
18
33
  async saveMessage(input) {
19
34
  const state = await this.loadState(input.sessionId);
20
35
  const cache = state.cache ?? [];
@@ -1,8 +1,20 @@
1
1
  import type { InternalMessage } from '../../context/types.js';
2
+ export type ModelHistoryLoadStats = {
3
+ returnedMessages: number;
4
+ skippedPreSummaryMessages: number;
5
+ summaryMessageId: string | null;
6
+ };
7
+ export type ModelHistoryLoad = {
8
+ messages: InternalMessage[];
9
+ stats: ModelHistoryLoadStats;
10
+ };
2
11
  export interface ConversationStore {
3
12
  listMessages(input: {
4
13
  sessionId: string;
5
14
  }): Promise<InternalMessage[]>;
15
+ loadModelHistory(input: {
16
+ sessionId: string;
17
+ }): Promise<ModelHistoryLoad>;
6
18
  saveMessage(input: {
7
19
  sessionId: string;
8
20
  message: InternalMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/storage/conversation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAC9B,YAAY,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACvE,WAAW,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,KAAK,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/storage/conversation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,MAAM,qBAAqB,GAAG;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,CAAC;IAClC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,qBAAqB,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAC9B,YAAY,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACvE,gBAAgB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1E,WAAW,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,KAAK,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
@@ -14,7 +14,7 @@ export { BackendDextoStores, DatabaseBackedApprovalStore, DatabaseBackedArtifact
14
14
  export type { DextoStoresLifecycle } from './stores/backend.js';
15
15
  export type { DextoStoreMap, DextoStoreName, DextoStores } from './stores/types.js';
16
16
  export { DatabaseConversationStore } from './conversation/database.js';
17
- export type { ConversationStore } from './conversation/types.js';
17
+ export type { ConversationStore, ModelHistoryLoad, ModelHistoryLoadStats, } from './conversation/types.js';
18
18
  export type { SessionStore } from './sessions/types.js';
19
19
  export type { MemoryStore } from './memories/types.js';
20
20
  export type { WorkspaceStore } from './workspaces/types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EACR,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,SAAS,GACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EACH,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,+BAA+B,EAC/B,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,0BAA0B,EAC1B,gCAAgC,EAChC,iCAAiC,EACjC,4BAA4B,EAC5B,4BAA4B,EAC5B,kCAAkC,EAClC,8BAA8B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAChF,YAAY,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACR,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,sBAAsB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACvF,YAAY,EACR,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,GACrB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EACR,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,SAAS,GACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EACH,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,+BAA+B,EAC/B,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,0BAA0B,EAC1B,gCAAgC,EAChC,iCAAiC,EACjC,4BAA4B,EAC5B,4BAA4B,EAC5B,kCAAkC,EAClC,8BAA8B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EACR,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAChF,YAAY,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACR,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,sBAAsB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACvF,YAAY,EACR,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,GACrB,MAAM,4BAA4B,CAAC"}
@@ -23,6 +23,7 @@ __export(in_memory_exports, {
23
23
  module.exports = __toCommonJS(in_memory_exports);
24
24
  var import_crypto = require("crypto");
25
25
  var import_content_clone = require("../../context/content-clone.js");
26
+ var import_utils = require("../../context/utils.js");
26
27
  var import_queue_clone = require("../../session/queue-clone.js");
27
28
  var import_types = require("../tool-executions/types.js");
28
29
  var import_errors = require("../errors.js");
@@ -39,6 +40,20 @@ class InMemoryConversationStore {
39
40
  async listMessages(input) {
40
41
  return (0, import_content_clone.cloneInternalMessages)(this.messages.get(input.sessionId) ?? []);
41
42
  }
43
+ async loadModelHistory(input) {
44
+ const fullHistory = await this.listMessages(input);
45
+ const messages = (0, import_utils.filterCompacted)(fullHistory);
46
+ const firstMessage = messages[0];
47
+ const summaryMessageId = firstMessage?.metadata?.isSummary === true || firstMessage?.metadata?.isSessionSummary === true ? firstMessage.id ?? null : null;
48
+ return {
49
+ messages,
50
+ stats: {
51
+ returnedMessages: messages.length,
52
+ skippedPreSummaryMessages: fullHistory.length - messages.length,
53
+ summaryMessageId
54
+ }
55
+ };
56
+ }
42
57
  async saveMessage(input) {
43
58
  const messages = this.messages.get(input.sessionId) ?? [];
44
59
  if (input.message.id && messages.some((message) => message.id === input.message.id)) {
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../../src/storage/stores/in-memory.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA2lB7E,qBAAa,mBAAoB,YAAW,WAAW;IACnD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAcrB;IAEF,QAAQ,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAIvD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,MAAM;CAGzB"}
1
+ {"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../../src/storage/stores/in-memory.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA8mB7E,qBAAa,mBAAoB,YAAW,WAAW;IACnD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAcrB;IAEF,QAAQ,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAIvD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,MAAM;CAGzB"}
@@ -1,6 +1,7 @@
1
1
  import "../../chunk-C6A6W6XS.js";
2
2
  import { createHash, randomUUID } from "crypto";
3
3
  import { cloneInternalMessage, cloneInternalMessages } from "../../context/content-clone.js";
4
+ import { filterCompacted } from "../../context/utils.js";
4
5
  import { cloneQueuedMessage, cloneQueuedMessages } from "../../session/queue-clone.js";
5
6
  import { splitToolExecutionResult } from "../tool-executions/types.js";
6
7
  import { StorageError } from "../errors.js";
@@ -17,6 +18,20 @@ class InMemoryConversationStore {
17
18
  async listMessages(input) {
18
19
  return cloneInternalMessages(this.messages.get(input.sessionId) ?? []);
19
20
  }
21
+ async loadModelHistory(input) {
22
+ const fullHistory = await this.listMessages(input);
23
+ const messages = filterCompacted(fullHistory);
24
+ const firstMessage = messages[0];
25
+ const summaryMessageId = firstMessage?.metadata?.isSummary === true || firstMessage?.metadata?.isSessionSummary === true ? firstMessage.id ?? null : null;
26
+ return {
27
+ messages,
28
+ stats: {
29
+ returnedMessages: messages.length,
30
+ skippedPreSummaryMessages: fullHistory.length - messages.length,
31
+ summaryMessageId
32
+ }
33
+ };
34
+ }
20
35
  async saveMessage(input) {
21
36
  const messages = this.messages.get(input.sessionId) ?? [];
22
37
  if (input.message.id && messages.some((message) => message.id === input.message.id)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexto/core",
3
- "version": "1.9.2",
3
+ "version": "1.9.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -162,7 +162,7 @@
162
162
  "nanoid": "^5.1.6",
163
163
  "winston": "^3.17.0",
164
164
  "yaml": "^2.8.3",
165
- "@dexto/llm": "1.9.2"
165
+ "@dexto/llm": "1.9.3"
166
166
  },
167
167
  "devDependencies": {
168
168
  "@opentelemetry/context-async-hooks": "^1.28.0",