wave-agent-sdk 1.0.4 → 1.0.5

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.
@@ -1,4 +1,4 @@
1
- import { addAssistantMessageToMessages, updateToolBlockInMessage, addErrorBlockToMessage, addUserMessageToMessages, updateUserMessageInMessages, addBangMessage, updateBangInMessage, completeBangInMessage, removeLastUserMessage, addToolBlockToMessageInMessages, addNotificationMessageToMessages, generateMessageId, } from "../utils/messageOperations.js";
1
+ import { addAssistantMessageToMessages, updateToolBlockInMessage, addErrorBlockToMessage, addUserMessageToMessages, updateUserMessageInMessages, addBangMessage, updateBangInMessage, completeBangInMessage, removeLastUserMessage, addToolBlockToMessageInMessages, addNotificationMessageToMessages, generateMessageId, sliceFromLastCompact, } from "../utils/messageOperations.js";
2
2
  import { getLastApiRounds } from "../utils/groupMessagesByApiRound.js";
3
3
  import { join, isAbsolute, relative } from "path";
4
4
  import { appendMessages, createSession, generateSessionId, SESSION_DIR, } from "../services/session.js";
@@ -717,9 +717,12 @@ export class MessageManager {
717
717
  if (reversionManager && messageIdsToRemove.length > 0) {
718
718
  await reversionManager.revertTo(messageIdsToRemove, messages);
719
719
  }
720
- // Rewrite file with truncated messages
720
+ // Rewrite file with truncated messages (full history kept on disk)
721
721
  await this.rewriteSessionFile(newMessages);
722
- this.setMessages(newMessages);
722
+ // Fold the in-memory messages at the last compact boundary so the agent
723
+ // only sees messages from the latest compact summary forward — matching
724
+ // the compact and resume behaviors (which also fold memory).
725
+ this.setMessages(sliceFromLastCompact(newMessages));
723
726
  this.savedMessageCount = newMessages.length;
724
727
  }
725
728
  /**
@@ -22,7 +22,7 @@ import { PathEncoder } from "../utils/pathEncoder.js";
22
22
  import { JsonlHandler } from "../services/jsonlHandler.js";
23
23
  import { extractLatestTotalTokens } from "../utils/tokenCalculation.js";
24
24
  import { logger } from "../utils/globalLogger.js";
25
- import { getMessageContent } from "../utils/messageOperations.js";
25
+ import { getMessageContent, sliceFromLastCompact, } from "../utils/messageOperations.js";
26
26
  /**
27
27
  * Generate a new session ID using Node.js native crypto.randomUUID()
28
28
  * @returns UUID string for session identification
@@ -149,14 +149,7 @@ export async function loadSessionFromJsonl(sessionId, workdir, sessionType = "ma
149
149
  }
150
150
  const allMessages = await jsonlHandler.read(filePath);
151
151
  // Find the last compact boundary — only return messages from there forward
152
- let lastCompactIndex = -1;
153
- for (let i = allMessages.length - 1; i >= 0; i--) {
154
- if (allMessages[i].blocks?.some((b) => b.type === "compact")) {
155
- lastCompactIndex = i;
156
- break;
157
- }
158
- }
159
- const messages = lastCompactIndex >= 0 ? allMessages.slice(lastCompactIndex) : allMessages;
152
+ const messages = sliceFromLastCompact(allMessages);
160
153
  // Extract metadata from messages
161
154
  const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null;
162
155
  const sessionData = {
@@ -112,6 +112,14 @@ export declare function cloneMessage(message: Message): Message;
112
112
  * Helper to format tool and token summary
113
113
  */
114
114
  export declare function formatToolTokenSummary(toolCount: number, tokens: number): string;
115
+ /**
116
+ * Fold a message list at the last compact boundary — returns only messages from
117
+ * the most recent compact summary forward. Mirrors what is sent to the LLM
118
+ * (convertMessagesForAPI stops at the last compact block), so the display layer
119
+ * matches the AI context. The session file keeps the full history; folding is
120
+ * display-only.
121
+ */
122
+ export declare function sliceFromLastCompact(messages: Message[]): Message[];
115
123
  /**
116
124
  * Extracts displayable text from a Message object, handling various block types.
117
125
  * Returns the first available content block.
@@ -415,6 +415,23 @@ export function formatToolTokenSummary(toolCount, tokens) {
415
415
  summary += ")";
416
416
  return summary;
417
417
  }
418
+ /**
419
+ * Fold a message list at the last compact boundary — returns only messages from
420
+ * the most recent compact summary forward. Mirrors what is sent to the LLM
421
+ * (convertMessagesForAPI stops at the last compact block), so the display layer
422
+ * matches the AI context. The session file keeps the full history; folding is
423
+ * display-only.
424
+ */
425
+ export function sliceFromLastCompact(messages) {
426
+ let lastCompactIndex = -1;
427
+ for (let i = messages.length - 1; i >= 0; i--) {
428
+ if (messages[i].blocks?.some((b) => b.type === "compact")) {
429
+ lastCompactIndex = i;
430
+ break;
431
+ }
432
+ }
433
+ return lastCompactIndex >= 0 ? messages.slice(lastCompactIndex) : messages;
434
+ }
418
435
  /**
419
436
  * Extracts displayable text from a Message object, handling various block types.
420
437
  * Returns the first available content block.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
@@ -15,6 +15,7 @@ import {
15
15
  type ToolBlockUpdateCallbackParams,
16
16
  type AddNotificationMessageParams,
17
17
  generateMessageId,
18
+ sliceFromLastCompact,
18
19
  } from "../utils/messageOperations.js";
19
20
  import type { Message, Usage, ToolBlock } from "../types/index.js";
20
21
  import { getLastApiRounds } from "../utils/groupMessagesByApiRound.js";
@@ -1014,9 +1015,12 @@ export class MessageManager {
1014
1015
  await reversionManager.revertTo(messageIdsToRemove, messages);
1015
1016
  }
1016
1017
 
1017
- // Rewrite file with truncated messages
1018
+ // Rewrite file with truncated messages (full history kept on disk)
1018
1019
  await this.rewriteSessionFile(newMessages);
1019
- this.setMessages(newMessages);
1020
+ // Fold the in-memory messages at the last compact boundary so the agent
1021
+ // only sees messages from the latest compact summary forward — matching
1022
+ // the compact and resume behaviors (which also fold memory).
1023
+ this.setMessages(sliceFromLastCompact(newMessages));
1020
1024
  this.savedMessageCount = newMessages.length;
1021
1025
  }
1022
1026
 
@@ -24,7 +24,10 @@ import { PathEncoder } from "../utils/pathEncoder.js";
24
24
  import { JsonlHandler } from "../services/jsonlHandler.js";
25
25
  import { extractLatestTotalTokens } from "../utils/tokenCalculation.js";
26
26
  import { logger } from "../utils/globalLogger.js";
27
- import { getMessageContent } from "../utils/messageOperations.js";
27
+ import {
28
+ getMessageContent,
29
+ sliceFromLastCompact,
30
+ } from "../utils/messageOperations.js";
28
31
 
29
32
  export interface SessionData {
30
33
  id: string;
@@ -222,15 +225,7 @@ export async function loadSessionFromJsonl(
222
225
  const allMessages = await jsonlHandler.read(filePath);
223
226
 
224
227
  // Find the last compact boundary — only return messages from there forward
225
- let lastCompactIndex = -1;
226
- for (let i = allMessages.length - 1; i >= 0; i--) {
227
- if (allMessages[i].blocks?.some((b) => b.type === "compact")) {
228
- lastCompactIndex = i;
229
- break;
230
- }
231
- }
232
- const messages =
233
- lastCompactIndex >= 0 ? allMessages.slice(lastCompactIndex) : allMessages;
228
+ const messages = sliceFromLastCompact(allMessages);
234
229
 
235
230
  // Extract metadata from messages
236
231
  const lastMessage =
@@ -580,6 +580,24 @@ export function formatToolTokenSummary(
580
580
  return summary;
581
581
  }
582
582
 
583
+ /**
584
+ * Fold a message list at the last compact boundary — returns only messages from
585
+ * the most recent compact summary forward. Mirrors what is sent to the LLM
586
+ * (convertMessagesForAPI stops at the last compact block), so the display layer
587
+ * matches the AI context. The session file keeps the full history; folding is
588
+ * display-only.
589
+ */
590
+ export function sliceFromLastCompact(messages: Message[]): Message[] {
591
+ let lastCompactIndex = -1;
592
+ for (let i = messages.length - 1; i >= 0; i--) {
593
+ if (messages[i].blocks?.some((b) => b.type === "compact")) {
594
+ lastCompactIndex = i;
595
+ break;
596
+ }
597
+ }
598
+ return lastCompactIndex >= 0 ? messages.slice(lastCompactIndex) : messages;
599
+ }
600
+
583
601
  /**
584
602
  * Extracts displayable text from a Message object, handling various block types.
585
603
  * Returns the first available content block.