wave-agent-sdk 0.17.12 → 0.18.1

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 (33) hide show
  1. package/builtin/skills/code-review/SKILL.md +137 -0
  2. package/builtin/skills/simplify/SKILL.md +55 -0
  3. package/dist/managers/aiManager.d.ts.map +1 -1
  4. package/dist/managers/aiManager.js +2 -7
  5. package/dist/managers/messageManager.d.ts +25 -12
  6. package/dist/managers/messageManager.d.ts.map +1 -1
  7. package/dist/managers/messageManager.js +70 -48
  8. package/dist/managers/subagentManager.d.ts +17 -5
  9. package/dist/managers/subagentManager.d.ts.map +1 -1
  10. package/dist/managers/subagentManager.js +12 -6
  11. package/dist/services/authService.d.ts +2 -2
  12. package/dist/services/authService.d.ts.map +1 -1
  13. package/dist/services/authService.js +7 -7
  14. package/dist/services/remoteSettingsService.d.ts +6 -0
  15. package/dist/services/remoteSettingsService.d.ts.map +1 -1
  16. package/dist/services/remoteSettingsService.js +29 -0
  17. package/dist/utils/containerSetup.d.ts.map +1 -1
  18. package/dist/utils/containerSetup.js +7 -2
  19. package/dist/utils/messageOperations.d.ts +7 -1
  20. package/dist/utils/messageOperations.d.ts.map +1 -1
  21. package/dist/utils/messageOperations.js +6 -4
  22. package/package.json +1 -1
  23. package/src/managers/aiManager.ts +2 -7
  24. package/src/managers/messageManager.ts +103 -74
  25. package/src/managers/subagentManager.ts +41 -26
  26. package/src/services/authService.ts +13 -10
  27. package/src/services/remoteSettingsService.ts +35 -0
  28. package/src/utils/containerSetup.ts +8 -2
  29. package/src/utils/messageOperations.ts +15 -5
  30. package/dist/utils/microcompact.d.ts +0 -7
  31. package/dist/utils/microcompact.d.ts.map +0 -1
  32. package/dist/utils/microcompact.js +0 -78
  33. package/src/utils/microcompact.ts +0 -101
@@ -42,10 +42,10 @@ export class AuthService {
42
42
  this.onAuthChangeCallbacks = this.onAuthChangeCallbacks.filter((cb) => cb !== callback);
43
43
  };
44
44
  }
45
- notifyAuthChange(event) {
45
+ async notifyAuthChange(event) {
46
46
  for (const cb of this.onAuthChangeCallbacks) {
47
47
  try {
48
- cb(event);
48
+ await cb(event);
49
49
  }
50
50
  catch {
51
51
  // Don't let callback errors break auth flow
@@ -92,7 +92,7 @@ export class AuthService {
92
92
  // ignore stat errors
93
93
  }
94
94
  }
95
- clearAuth() {
95
+ async clearAuth() {
96
96
  const config = this.loadAuth();
97
97
  delete config.SSO_TOKEN;
98
98
  delete config.SSO_REFRESH_TOKEN;
@@ -106,7 +106,7 @@ export class AuthService {
106
106
  else {
107
107
  this.saveAuth(config);
108
108
  }
109
- this.notifyAuthChange("logout");
109
+ await this.notifyAuthChange("logout");
110
110
  }
111
111
  getSSOToken() {
112
112
  const config = this.loadAuth();
@@ -139,7 +139,7 @@ export class AuthService {
139
139
  : undefined,
140
140
  user,
141
141
  });
142
- this.notifyAuthChange("login");
142
+ await this.notifyAuthChange("login");
143
143
  return token;
144
144
  }
145
145
  /**
@@ -303,7 +303,7 @@ export class AuthService {
303
303
  if (response.status === 400 || response.status === 401) {
304
304
  // Refresh token revoked — clear auth
305
305
  logger.info(`[Auth] Refresh token rejected (${response.status}), clearing auth`);
306
- this.clearAuth();
306
+ await this.clearAuth();
307
307
  return false;
308
308
  }
309
309
  if (!response.ok) {
@@ -324,7 +324,7 @@ export class AuthService {
324
324
  : config.user,
325
325
  });
326
326
  logger.info(`[Auth] Token refreshed successfully, new token expires at ${newExpiresAt ? new Date(newExpiresAt).toISOString() : "never"}`);
327
- this.notifyAuthChange("login");
327
+ await this.notifyAuthChange("login");
328
328
  return true;
329
329
  }
330
330
  catch (err) {
@@ -1,5 +1,10 @@
1
1
  import type { RemoteSettingsFetchResult } from "../types/configuration.js";
2
2
  import type { WaveConfiguration } from "../types/configuration.js";
3
+ /**
4
+ * Register a callback invoked when remote settings change (checksum differs).
5
+ * Returns an unsubscribe function.
6
+ */
7
+ export declare function onSettingsUpdate(callback: () => void | Promise<void>): () => void;
3
8
  export declare function initialize(): void;
4
9
  export declare function getRemoteSettingsSync(): WaveConfiguration | null;
5
10
  export declare function refresh(): Promise<RemoteSettingsFetchResult>;
@@ -17,5 +22,6 @@ export declare const remoteSettingsService: {
17
22
  readonly clear: typeof clear;
18
23
  readonly shutdown: typeof shutdown;
19
24
  readonly mergeRemoteSettings: typeof mergeRemoteSettings;
25
+ readonly onSettingsUpdate: typeof onSettingsUpdate;
20
26
  };
21
27
  //# sourceMappingURL=remoteSettingsService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remoteSettingsService.d.ts","sourceRoot":"","sources":["../../src/services/remoteSettingsService.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AA2JnE,wBAAgB,UAAU,IAAI,IAAI,CASjC;AAED,wBAAgB,qBAAqB,IAAI,iBAAiB,GAAG,IAAI,CAEhE;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAKlE;AAED,wBAAgB,KAAK,IAAI,IAAI,CAO5B;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAK/B;AAqCD,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,iBAAiB,GACxB,iBAAiB,CA4DnB;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;CAOxB,CAAC"}
1
+ {"version":3,"file":"remoteSettingsService.d.ts","sourceRoot":"","sources":["../../src/services/remoteSettingsService.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAYnE;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnC,MAAM,IAAI,CAOZ;AAoKD,wBAAgB,UAAU,IAAI,IAAI,CASjC;AAED,wBAAgB,qBAAqB,IAAI,iBAAiB,GAAG,IAAI,CAEhE;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAKlE;AAED,wBAAgB,KAAK,IAAI,IAAI,CAO5B;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAK/B;AAqCD,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,iBAAiB,GACxB,iBAAiB,CA4DnB;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC"}
@@ -8,6 +8,27 @@ const POLLING_INTERVAL_MS = 60 * 60 * 1000; // 60 minutes
8
8
  const FETCH_TIMEOUT_MS = 10000;
9
9
  let _cachedSettings = null;
10
10
  let _pollingTimer = null;
11
+ let _onSettingsUpdateCallbacks = [];
12
+ /**
13
+ * Register a callback invoked when remote settings change (checksum differs).
14
+ * Returns an unsubscribe function.
15
+ */
16
+ export function onSettingsUpdate(callback) {
17
+ _onSettingsUpdateCallbacks.push(callback);
18
+ return () => {
19
+ _onSettingsUpdateCallbacks = _onSettingsUpdateCallbacks.filter((cb) => cb !== callback);
20
+ };
21
+ }
22
+ async function notifySettingsUpdate() {
23
+ for (const cb of _onSettingsUpdateCallbacks) {
24
+ try {
25
+ await cb();
26
+ }
27
+ catch {
28
+ // Don't let callback errors break the fetch flow
29
+ }
30
+ }
31
+ }
11
32
  function loadCacheFromDisk() {
12
33
  try {
13
34
  if (!fs.existsSync(CACHE_FILE)) {
@@ -64,6 +85,7 @@ async function fetchRemoteSettings() {
64
85
  if (!token || !serverUrl) {
65
86
  return { success: false, error: "Missing SSO token or server URL" };
66
87
  }
88
+ const oldChecksum = _cachedSettings?.checksum;
67
89
  const headers = {
68
90
  Authorization: `Bearer ${token}`,
69
91
  };
@@ -91,6 +113,9 @@ async function fetchRemoteSettings() {
91
113
  logger.debug("remoteSettings: 404 not configured — clearing stale cache");
92
114
  _cachedSettings = null;
93
115
  removeCacheFromDisk();
116
+ if (oldChecksum) {
117
+ await notifySettingsUpdate();
118
+ }
94
119
  return { success: true, notConfigured: true, settings: null };
95
120
  }
96
121
  if (!response.ok) {
@@ -116,6 +141,9 @@ async function fetchRemoteSettings() {
116
141
  logger.debug("remoteSettings: fetched new settings", {
117
142
  checksum: data.checksum,
118
143
  });
144
+ if (data.checksum !== oldChecksum) {
145
+ await notifySettingsUpdate();
146
+ }
119
147
  return {
120
148
  success: true,
121
149
  settings: data.settings,
@@ -277,4 +305,5 @@ export const remoteSettingsService = {
277
305
  clear,
278
306
  shutdown,
279
307
  mergeRemoteSettings,
308
+ onSettingsUpdate,
280
309
  };
@@ -1 +1 @@
1
- {"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0B3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAM3E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,IAAI,EACJ,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAGhB,uBAAuB,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,sBAAsB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,wBAAwB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,0BAA0B,GACvC,SAAS,CAuSX"}
1
+ {"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0B3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAM3E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,IAAI,EACJ,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAGhB,uBAAuB,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,sBAAsB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,wBAAwB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,0BAA0B,GACvC,SAAS,CA6SX"}
@@ -101,9 +101,9 @@ export function setupAgentContainer(setupOptions) {
101
101
  });
102
102
  container.register("McpManager", mcpManager);
103
103
  // Wire up auth change callback to refresh/clear remote settings
104
- authService.onAuthChange((event) => {
104
+ authService.onAuthChange(async (event) => {
105
105
  if (event === "login") {
106
- remoteSettingsService.refresh();
106
+ await remoteSettingsService.refresh();
107
107
  }
108
108
  else if (event === "logout") {
109
109
  remoteSettingsService.clear();
@@ -215,6 +215,11 @@ export function setupAgentContainer(setupOptions) {
215
215
  },
216
216
  });
217
217
  container.register("LiveConfigManager", liveConfigManager);
218
+ // Wire up remote settings hot-update: when polling detects changed settings,
219
+ // reload configuration so admin changes propagate to the running agent.
220
+ remoteSettingsService.onSettingsUpdate(async () => {
221
+ await liveConfigManager.reload();
222
+ });
218
223
  const subagentManager = new SubagentManager(container, {
219
224
  workdir,
220
225
  callbacks: {
@@ -44,6 +44,9 @@ export interface UpdateToolBlockParams {
44
44
  timestamp?: number;
45
45
  }
46
46
  export type AgentToolBlockUpdateParams = Omit<UpdateToolBlockParams, "messages">;
47
+ export type ToolBlockUpdateCallbackParams = Omit<AgentToolBlockUpdateParams, "messageId"> & {
48
+ messageId: string;
49
+ };
47
50
  export interface AddErrorBlockParams {
48
51
  messages: Message[];
49
52
  error: string;
@@ -83,7 +86,10 @@ export declare const addToolBlockToMessageInMessages: (messages: Message[], mess
83
86
  messages: Message[];
84
87
  toolBlockId: string;
85
88
  };
86
- export declare const updateToolBlockInMessage: ({ messages, id, messageId, parameters, result, success, error, stage, name, shortResult, startLineNumber, images, compactParams, parametersChunk, isManuallyBackgrounded, }: UpdateToolBlockParams) => Message[];
89
+ export declare const updateToolBlockInMessage: ({ messages, id, messageId, parameters, result, success, error, stage, name, shortResult, startLineNumber, images, compactParams, parametersChunk, isManuallyBackgrounded, }: UpdateToolBlockParams) => {
90
+ messages: Message[];
91
+ messageId?: string;
92
+ };
87
93
  export declare const addErrorBlockToMessage: ({ messages, error, }: AddErrorBlockParams) => Message[];
88
94
  export declare const addBangMessage: ({ messages, command, }: AddBangParams) => Message[];
89
95
  export declare const updateBangInMessage: ({ messages, command, output, }: UpdateBangParams) => Message[];
@@ -1 +1 @@
1
- {"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
@@ -193,7 +193,7 @@ export const updateToolBlockInMessage = ({ messages, id, messageId, parameters,
193
193
  }
194
194
  }
195
195
  }
196
- return newMessages;
196
+ return { messages: newMessages, messageId };
197
197
  }
198
198
  // Find the last assistant or user message
199
199
  for (let i = newMessages.length - 1; i >= 0; i--) {
@@ -225,7 +225,8 @@ export const updateToolBlockInMessage = ({ messages, id, messageId, parameters,
225
225
  if (isManuallyBackgrounded !== undefined)
226
226
  toolBlock.isManuallyBackgrounded = isManuallyBackgrounded;
227
227
  }
228
- break; // Found and updated, stop searching
228
+ const foundMessageId = newMessages[i].id;
229
+ return { messages: newMessages, messageId: foundMessageId };
229
230
  }
230
231
  else if (newMessages[i].role === "assistant") {
231
232
  // If existing block not found in assistant message, create new one
@@ -246,11 +247,12 @@ export const updateToolBlockInMessage = ({ messages, id, messageId, parameters,
246
247
  parametersChunk: parametersChunk,
247
248
  isManuallyBackgrounded: isManuallyBackgrounded,
248
249
  });
249
- break; // Created and added, stop searching
250
+ const foundMessageId = newMessages[i].id;
251
+ return { messages: newMessages, messageId: foundMessageId };
250
252
  }
251
253
  }
252
254
  }
253
- return newMessages;
255
+ return { messages: newMessages };
254
256
  };
255
257
  // Add Error Block to the last assistant message
256
258
  export const addErrorBlockToMessage = ({ messages, error, }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "0.17.12",
3
+ "version": "0.18.1",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
@@ -1,7 +1,6 @@
1
1
  import { type CallAgentOptions } from "../services/aiService.js";
2
2
  import * as aiService from "../services/aiService.js";
3
3
  import { convertMessagesForAPI } from "../utils/convertMessagesForAPI.js";
4
- import { microcompactMessages } from "../utils/microcompact.js";
5
4
  import { parseTaskNotificationXml } from "../utils/notificationXml.js";
6
5
  import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
7
6
  import {
@@ -819,13 +818,9 @@ export class AIManager {
819
818
  // Add plan mode reminder as persistent meta message before getting messages
820
819
  this.maybeAddPlanModeMessage(currentMode);
821
820
 
822
- // Get recent message history with microcompact applied
821
+ // Get recent message history
823
822
  const rawMessages = this.messageManager.getMessages();
824
- const microcompactedMessages = microcompactMessages(rawMessages, {
825
- timeThresholdMS: 30 * 60 * 1000, // 30 minutes
826
- recentResultsToKeep: 3,
827
- });
828
- const recentMessages = convertMessagesForAPI(microcompactedMessages);
823
+ const recentMessages = convertMessagesForAPI(rawMessages);
829
824
 
830
825
  try {
831
826
  // Get combined memory content
@@ -12,6 +12,7 @@ import {
12
12
  addNotificationMessageToMessages,
13
13
  UserMessageParams,
14
14
  type AgentToolBlockUpdateParams,
15
+ type ToolBlockUpdateCallbackParams,
15
16
  type AddNotificationMessageParams,
16
17
  generateMessageId,
17
18
  } from "../utils/messageOperations.js";
@@ -40,12 +41,22 @@ export interface MessageManagerCallbacks {
40
41
  // Incremental callback
41
42
  onUserMessageAdded?: (params: UserMessageParams) => void;
42
43
  // MODIFIED: Remove arguments for separation of concerns
43
- onAssistantMessageAdded?: () => void;
44
+ onAssistantMessageAdded?: (messageId: string) => void;
44
45
  // NEW: Streaming content callback - FR-001: receives chunk and accumulated content
45
- onAssistantContentUpdated?: (chunk: string, accumulated: string) => void;
46
+ onAssistantContentUpdated?: (params: {
47
+ messageId: string;
48
+ chunk: string;
49
+ accumulated: string;
50
+ stage: "streaming" | "end";
51
+ }) => void;
46
52
  // NEW: Streaming reasoning callback
47
- onAssistantReasoningUpdated?: (chunk: string, accumulated: string) => void;
48
- onToolBlockUpdated?: (params: AgentToolBlockUpdateParams) => void;
53
+ onAssistantReasoningUpdated?: (params: {
54
+ messageId: string;
55
+ chunk: string;
56
+ accumulated: string;
57
+ stage: "streaming" | "end";
58
+ }) => void;
59
+ onToolBlockUpdated?: (params: ToolBlockUpdateCallbackParams) => void;
49
60
  onErrorBlockAdded?: (error: string) => void;
50
61
  onCompactBlockAdded?: (content: string) => void;
51
62
  onCompactionStateChange?: (isCompacting: boolean) => void;
@@ -419,7 +430,8 @@ export class MessageManager {
419
430
  additionalFieldsRecord,
420
431
  );
421
432
  this.setMessages(newMessages);
422
- this.callbacks.onAssistantMessageAdded?.();
433
+ const messageId = this.messages[this.messages.length - 1]?.id;
434
+ this.callbacks.onAssistantMessageAdded?.(messageId);
423
435
 
424
436
  // Note: Subagent-specific callbacks are now handled by SubagentManager
425
437
  }
@@ -459,13 +471,22 @@ export class MessageManager {
459
471
 
460
472
  public updateToolBlock(params: AgentToolBlockUpdateParams): void {
461
473
  // Finalize any streaming text/reasoning blocks before adding/updating a tool block
462
- this.finalizeCurrentStreamingBlocks();
463
- const newMessages = updateToolBlockInMessage({
464
- messages: this.messages,
465
- ...params,
466
- });
474
+ this.finalizeStreamingBlocks();
475
+ const { messages: newMessages, messageId: resolvedMessageId } =
476
+ updateToolBlockInMessage({
477
+ messages: this.messages,
478
+ ...params,
479
+ });
467
480
  this.setMessages(newMessages);
468
- this.callbacks.onToolBlockUpdated?.(params);
481
+ const callbackParams: ToolBlockUpdateCallbackParams = {
482
+ ...params,
483
+ messageId:
484
+ params.messageId ||
485
+ resolvedMessageId ||
486
+ this.messages[this.messages.length - 1]?.id ||
487
+ "",
488
+ };
489
+ this.callbacks.onToolBlockUpdated?.(callbackParams);
469
490
 
470
491
  // Note: Subagent-specific callbacks are now handled by SubagentManager
471
492
  }
@@ -478,11 +499,15 @@ export class MessageManager {
478
499
  params: Omit<AgentToolBlockUpdateParams, "id">,
479
500
  ): string {
480
501
  // Finalize any streaming text/reasoning blocks before adding a tool block
481
- this.finalizeCurrentStreamingBlocks();
502
+ this.finalizeStreamingBlocks();
482
503
  const { messages: newMessages, toolBlockId } =
483
504
  addToolBlockToMessageInMessages(this.messages, messageId, params);
484
505
  this.setMessages(newMessages);
485
- this.callbacks.onToolBlockUpdated?.({ ...params, id: toolBlockId });
506
+ this.callbacks.onToolBlockUpdated?.({
507
+ ...params,
508
+ id: toolBlockId,
509
+ messageId,
510
+ });
486
511
  return toolBlockId;
487
512
  }
488
513
 
@@ -658,6 +683,49 @@ export class MessageManager {
658
683
  this.callbacks.onUsagesChange?.([...this._usages]);
659
684
  }
660
685
 
686
+ /**
687
+ * Finalize a streaming block of the given type by setting its stage to "end".
688
+ * Fires the corresponding incremental callback with chunk="" to signal finalization.
689
+ * Does NOT call onMessagesChange — the caller is responsible for that.
690
+ * Returns true if a block was finalized.
691
+ */
692
+ private finalizeStreamingBlock(
693
+ lastMessage: Message,
694
+ type: "text" | "reasoning",
695
+ ): boolean {
696
+ const index = lastMessage.blocks.findIndex(
697
+ (block) =>
698
+ block.type === type &&
699
+ (block as { stage?: string }).stage === "streaming",
700
+ );
701
+ if (index < 0) return false;
702
+
703
+ const block = lastMessage.blocks[index] as {
704
+ type: "text" | "reasoning";
705
+ content: string;
706
+ stage?: string;
707
+ };
708
+ lastMessage.blocks[index] = {
709
+ type: block.type,
710
+ content: block.content,
711
+ stage: "end" as const,
712
+ };
713
+
714
+ // Fire incremental callback to signal finalization
715
+ const callbackParams = {
716
+ messageId: lastMessage.id,
717
+ chunk: "",
718
+ accumulated: block.content,
719
+ stage: "end" as const,
720
+ };
721
+ if (type === "text") {
722
+ this.callbacks.onAssistantContentUpdated?.(callbackParams);
723
+ } else {
724
+ this.callbacks.onAssistantReasoningUpdated?.(callbackParams);
725
+ }
726
+ return true;
727
+ }
728
+
661
729
  /**
662
730
  * Update the current assistant message content during streaming
663
731
  * This method updates the last assistant message's content without creating a new message
@@ -670,23 +738,7 @@ export class MessageManager {
670
738
  if (lastMessage.role !== "assistant") return;
671
739
 
672
740
  // Finalize any streaming reasoning blocks before text content arrives
673
- const reasoningIndex = lastMessage.blocks.findIndex(
674
- (block) =>
675
- block.type === "reasoning" &&
676
- (block as { stage?: string }).stage === "streaming",
677
- );
678
- if (reasoningIndex >= 0) {
679
- const reasoningBlock = lastMessage.blocks[reasoningIndex] as {
680
- type: "reasoning";
681
- content: string;
682
- stage?: string;
683
- };
684
- lastMessage.blocks[reasoningIndex] = {
685
- type: "reasoning" as const,
686
- content: reasoningBlock.content,
687
- stage: "end" as const,
688
- };
689
- }
741
+ this.finalizeStreamingBlock(lastMessage, "reasoning");
690
742
 
691
743
  // Get the current content to calculate the chunk
692
744
  const textBlockIndex = lastMessage.blocks.findIndex(
@@ -722,7 +774,12 @@ export class MessageManager {
722
774
  }
723
775
 
724
776
  // FR-001: Trigger callbacks with chunk and accumulated content
725
- this.callbacks.onAssistantContentUpdated?.(chunk, newAccumulatedContent);
777
+ this.callbacks.onAssistantContentUpdated?.({
778
+ messageId: lastMessage.id,
779
+ chunk,
780
+ accumulated: newAccumulatedContent,
781
+ stage: "streaming",
782
+ });
726
783
 
727
784
  // Note: Subagent-specific callbacks are now handled by SubagentManager
728
785
 
@@ -740,23 +797,7 @@ export class MessageManager {
740
797
  if (lastMessage.role !== "assistant") return;
741
798
 
742
799
  // Finalize any streaming text blocks before reasoning content arrives
743
- const textIndex = lastMessage.blocks.findIndex(
744
- (block) =>
745
- block.type === "text" &&
746
- (block as { stage?: string }).stage === "streaming",
747
- );
748
- if (textIndex >= 0) {
749
- const textBlock = lastMessage.blocks[textIndex] as {
750
- type: "text";
751
- content: string;
752
- stage?: string;
753
- };
754
- lastMessage.blocks[textIndex] = {
755
- type: "text" as const,
756
- content: textBlock.content,
757
- stage: "end" as const,
758
- };
759
- }
800
+ this.finalizeStreamingBlock(lastMessage, "text");
760
801
 
761
802
  // Get the current reasoning content to calculate the chunk
762
803
  const reasoningBlockIndex = lastMessage.blocks.findIndex(
@@ -792,45 +833,33 @@ export class MessageManager {
792
833
  }
793
834
 
794
835
  // Trigger callbacks with chunk and accumulated reasoning content
795
- this.callbacks.onAssistantReasoningUpdated?.(
836
+ this.callbacks.onAssistantReasoningUpdated?.({
837
+ messageId: lastMessage.id,
796
838
  chunk,
797
- newAccumulatedReasoning,
798
- );
839
+ accumulated: newAccumulatedReasoning,
840
+ stage: "streaming",
841
+ });
799
842
 
800
843
  this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
801
844
  }
802
845
 
803
- /**
804
- * Public wrapper for finalizeCurrentStreamingBlocks.
805
- * Finalizes text/reasoning blocks after streaming completes (e.g. final response with no tools).
806
- */
807
- public finalizeStreamingBlocks(): void {
808
- this.finalizeCurrentStreamingBlocks();
809
- }
810
-
811
846
  /**
812
847
  * Finalize streaming text/reasoning blocks by setting their stage to "end".
813
- * Called when a new block (e.g. tool) is appended during streaming.
848
+ * Called when a new block (e.g. tool) is appended during streaming, or when streaming completes.
849
+ * Fires incremental callbacks for each finalized block.
814
850
  */
815
- private finalizeCurrentStreamingBlocks(): void {
851
+ public finalizeStreamingBlocks(): void {
816
852
  if (this.messages.length === 0) return;
817
853
  const lastMessage = this.messages[this.messages.length - 1];
818
854
  if (lastMessage.role !== "assistant") return;
819
855
 
820
- const newBlocks = lastMessage.blocks.map((block) => {
821
- if (
822
- (block.type === "text" || block.type === "reasoning") &&
823
- block.stage === "streaming"
824
- ) {
825
- return { ...block, stage: "end" as const };
826
- }
827
- return block;
828
- });
856
+ const textFinalized = this.finalizeStreamingBlock(lastMessage, "text");
857
+ const reasoningFinalized = this.finalizeStreamingBlock(
858
+ lastMessage,
859
+ "reasoning",
860
+ );
829
861
 
830
- // Only update if something changed
831
- const changed = newBlocks.some((b, i) => b !== lastMessage.blocks[i]);
832
- if (changed) {
833
- lastMessage.blocks = newBlocks;
862
+ if (textFinalized || reasoningFinalized) {
834
863
  this.callbacks.onMessagesChange?.([...this.messages]);
835
864
  }
836
865
  }
@@ -17,7 +17,7 @@ import { NotificationQueue } from "./notificationQueue.js";
17
17
  import { logger } from "../utils/globalLogger.js";
18
18
  import {
19
19
  UserMessageParams,
20
- type AgentToolBlockUpdateParams,
20
+ type ToolBlockUpdateCallbackParams,
21
21
  } from "../utils/messageOperations.js";
22
22
 
23
23
  import { Container } from "../utils/container.js";
@@ -26,30 +26,37 @@ import type { PermissionMode } from "../types/permissions.js";
26
26
  import { ConfigurationService } from "../services/configurationService.js";
27
27
 
28
28
  export interface SubagentManagerCallbacks {
29
- // Granular subagent message callbacks (015-subagent-message-callbacks)
29
+ // Granular subagent message callbacks (009-subagent)
30
30
  /** Triggered when subagent adds user message */
31
31
  onSubagentUserMessageAdded?: (
32
32
  subagentId: string,
33
33
  params: UserMessageParams,
34
34
  ) => void;
35
35
  /** Triggered when subagent creates assistant message */
36
- onSubagentAssistantMessageAdded?: (subagentId: string) => void;
37
- /** Triggered during subagent content streaming updates */
38
- onSubagentAssistantContentUpdated?: (
36
+ onSubagentAssistantMessageAdded?: (
39
37
  subagentId: string,
40
- chunk: string,
41
- accumulated: string,
38
+ messageId: string,
42
39
  ) => void;
40
+ /** Triggered during subagent content streaming updates */
41
+ onSubagentAssistantContentUpdated?: (params: {
42
+ subagentId: string;
43
+ messageId: string;
44
+ chunk: string;
45
+ accumulated: string;
46
+ stage: "streaming" | "end";
47
+ }) => void;
43
48
  /** Triggered during subagent reasoning streaming updates */
44
- onSubagentAssistantReasoningUpdated?: (
45
- subagentId: string,
46
- chunk: string,
47
- accumulated: string,
48
- ) => void;
49
+ onSubagentAssistantReasoningUpdated?: (params: {
50
+ subagentId: string;
51
+ messageId: string;
52
+ chunk: string;
53
+ accumulated: string;
54
+ stage: "streaming" | "end";
55
+ }) => void;
49
56
  /** Triggered when subagent tool block is updated */
50
57
  onSubagentToolBlockUpdated?: (
51
58
  subagentId: string,
52
- params: AgentToolBlockUpdateParams,
59
+ params: ToolBlockUpdateCallbackParams,
53
60
  ) => void;
54
61
  /** Triggered when subagent messages change */
55
62
  onSubagentMessagesChange?: (subagentId: string, messages: Message[]) => void;
@@ -777,35 +784,43 @@ export class SubagentManager {
777
784
  }
778
785
  },
779
786
 
780
- onAssistantMessageAdded: () => {
787
+ onAssistantMessageAdded: (messageId: string) => {
781
788
  // Forward assistant message events to parent via SubagentManager callbacks
782
789
  if (this.callbacks?.onSubagentAssistantMessageAdded) {
783
- this.callbacks.onSubagentAssistantMessageAdded(subagentId);
790
+ this.callbacks.onSubagentAssistantMessageAdded(subagentId, messageId);
784
791
  }
785
792
  },
786
793
 
787
- onAssistantContentUpdated: (chunk: string, accumulated: string) => {
794
+ onAssistantContentUpdated: (params: {
795
+ messageId: string;
796
+ chunk: string;
797
+ accumulated: string;
798
+ stage: "streaming" | "end";
799
+ }) => {
788
800
  // Forward assistant content updates to parent via SubagentManager callbacks
789
801
  if (this.callbacks?.onSubagentAssistantContentUpdated) {
790
- this.callbacks.onSubagentAssistantContentUpdated(
802
+ this.callbacks.onSubagentAssistantContentUpdated({
803
+ ...params,
791
804
  subagentId,
792
- chunk,
793
- accumulated,
794
- );
805
+ });
795
806
  }
796
807
  },
797
- onAssistantReasoningUpdated: (chunk: string, accumulated: string) => {
808
+ onAssistantReasoningUpdated: (params: {
809
+ messageId: string;
810
+ chunk: string;
811
+ accumulated: string;
812
+ stage: "streaming" | "end";
813
+ }) => {
798
814
  // Forward assistant reasoning updates to parent via SubagentManager callbacks
799
815
  if (this.callbacks?.onSubagentAssistantReasoningUpdated) {
800
- this.callbacks.onSubagentAssistantReasoningUpdated(
816
+ this.callbacks.onSubagentAssistantReasoningUpdated({
817
+ ...params,
801
818
  subagentId,
802
- chunk,
803
- accumulated,
804
- );
819
+ });
805
820
  }
806
821
  },
807
822
 
808
- onToolBlockUpdated: (params: AgentToolBlockUpdateParams) => {
823
+ onToolBlockUpdated: (params: ToolBlockUpdateCallbackParams) => {
809
824
  const instance = this.instances.get(subagentId);
810
825
  if (instance) {
811
826
  // Log tool execution to file only when finalized