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.
- package/builtin/skills/code-review/SKILL.md +137 -0
- package/builtin/skills/simplify/SKILL.md +55 -0
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +2 -7
- package/dist/managers/messageManager.d.ts +25 -12
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +70 -48
- package/dist/managers/subagentManager.d.ts +17 -5
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +12 -6
- package/dist/services/authService.d.ts +2 -2
- package/dist/services/authService.d.ts.map +1 -1
- package/dist/services/authService.js +7 -7
- package/dist/services/remoteSettingsService.d.ts +6 -0
- package/dist/services/remoteSettingsService.d.ts.map +1 -1
- package/dist/services/remoteSettingsService.js +29 -0
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +7 -2
- package/dist/utils/messageOperations.d.ts +7 -1
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +6 -4
- package/package.json +1 -1
- package/src/managers/aiManager.ts +2 -7
- package/src/managers/messageManager.ts +103 -74
- package/src/managers/subagentManager.ts +41 -26
- package/src/services/authService.ts +13 -10
- package/src/services/remoteSettingsService.ts +35 -0
- package/src/utils/containerSetup.ts +8 -2
- package/src/utils/messageOperations.ts +15 -5
- package/dist/utils/microcompact.d.ts +0 -7
- package/dist/utils/microcompact.d.ts.map +0 -1
- package/dist/utils/microcompact.js +0 -78
- 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;
|
|
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,
|
|
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) =>
|
|
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
|
-
|
|
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
|
-
|
|
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,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
|
|
821
|
+
// Get recent message history
|
|
823
822
|
const rawMessages = this.messageManager.getMessages();
|
|
824
|
-
const
|
|
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?: (
|
|
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?: (
|
|
48
|
-
|
|
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.
|
|
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.
|
|
463
|
-
const newMessages =
|
|
464
|
-
|
|
465
|
-
|
|
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
|
-
|
|
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.
|
|
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?.({
|
|
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
|
-
|
|
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?.(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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?: (
|
|
37
|
-
/** Triggered during subagent content streaming updates */
|
|
38
|
-
onSubagentAssistantContentUpdated?: (
|
|
36
|
+
onSubagentAssistantMessageAdded?: (
|
|
39
37
|
subagentId: string,
|
|
40
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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:
|
|
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: (
|
|
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
|
-
|
|
793
|
-
accumulated,
|
|
794
|
-
);
|
|
805
|
+
});
|
|
795
806
|
}
|
|
796
807
|
},
|
|
797
|
-
onAssistantReasoningUpdated: (
|
|
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
|
-
|
|
803
|
-
accumulated,
|
|
804
|
-
);
|
|
819
|
+
});
|
|
805
820
|
}
|
|
806
821
|
},
|
|
807
822
|
|
|
808
|
-
onToolBlockUpdated: (params:
|
|
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
|