wave-agent-sdk 0.17.11 → 0.18.0
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 +5 -5
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +18 -6
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +2 -1
- package/dist/managers/subagentManager.d.ts +5 -5
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +6 -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 +40 -12
- package/src/managers/skillManager.ts +3 -1
- package/src/managers/subagentManager.ts +24 -9
- 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
|
@@ -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,20 @@ 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?: (
|
|
47
|
+
messageId: string,
|
|
48
|
+
chunk: string,
|
|
49
|
+
accumulated: string,
|
|
50
|
+
) => void;
|
|
46
51
|
// NEW: Streaming reasoning callback
|
|
47
|
-
onAssistantReasoningUpdated?: (
|
|
48
|
-
|
|
52
|
+
onAssistantReasoningUpdated?: (
|
|
53
|
+
messageId: string,
|
|
54
|
+
chunk: string,
|
|
55
|
+
accumulated: string,
|
|
56
|
+
) => void;
|
|
57
|
+
onToolBlockUpdated?: (params: ToolBlockUpdateCallbackParams) => void;
|
|
49
58
|
onErrorBlockAdded?: (error: string) => void;
|
|
50
59
|
onCompactBlockAdded?: (content: string) => void;
|
|
51
60
|
onCompactionStateChange?: (isCompacting: boolean) => void;
|
|
@@ -419,7 +428,8 @@ export class MessageManager {
|
|
|
419
428
|
additionalFieldsRecord,
|
|
420
429
|
);
|
|
421
430
|
this.setMessages(newMessages);
|
|
422
|
-
this.
|
|
431
|
+
const messageId = this.messages[this.messages.length - 1]?.id;
|
|
432
|
+
this.callbacks.onAssistantMessageAdded?.(messageId);
|
|
423
433
|
|
|
424
434
|
// Note: Subagent-specific callbacks are now handled by SubagentManager
|
|
425
435
|
}
|
|
@@ -460,12 +470,21 @@ export class MessageManager {
|
|
|
460
470
|
public updateToolBlock(params: AgentToolBlockUpdateParams): void {
|
|
461
471
|
// Finalize any streaming text/reasoning blocks before adding/updating a tool block
|
|
462
472
|
this.finalizeCurrentStreamingBlocks();
|
|
463
|
-
const newMessages =
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
473
|
+
const { messages: newMessages, messageId: resolvedMessageId } =
|
|
474
|
+
updateToolBlockInMessage({
|
|
475
|
+
messages: this.messages,
|
|
476
|
+
...params,
|
|
477
|
+
});
|
|
467
478
|
this.setMessages(newMessages);
|
|
468
|
-
|
|
479
|
+
const callbackParams: ToolBlockUpdateCallbackParams = {
|
|
480
|
+
...params,
|
|
481
|
+
messageId:
|
|
482
|
+
params.messageId ||
|
|
483
|
+
resolvedMessageId ||
|
|
484
|
+
this.messages[this.messages.length - 1]?.id ||
|
|
485
|
+
"",
|
|
486
|
+
};
|
|
487
|
+
this.callbacks.onToolBlockUpdated?.(callbackParams);
|
|
469
488
|
|
|
470
489
|
// Note: Subagent-specific callbacks are now handled by SubagentManager
|
|
471
490
|
}
|
|
@@ -482,7 +501,11 @@ export class MessageManager {
|
|
|
482
501
|
const { messages: newMessages, toolBlockId } =
|
|
483
502
|
addToolBlockToMessageInMessages(this.messages, messageId, params);
|
|
484
503
|
this.setMessages(newMessages);
|
|
485
|
-
this.callbacks.onToolBlockUpdated?.({
|
|
504
|
+
this.callbacks.onToolBlockUpdated?.({
|
|
505
|
+
...params,
|
|
506
|
+
id: toolBlockId,
|
|
507
|
+
messageId,
|
|
508
|
+
});
|
|
486
509
|
return toolBlockId;
|
|
487
510
|
}
|
|
488
511
|
|
|
@@ -722,7 +745,11 @@ export class MessageManager {
|
|
|
722
745
|
}
|
|
723
746
|
|
|
724
747
|
// FR-001: Trigger callbacks with chunk and accumulated content
|
|
725
|
-
this.callbacks.onAssistantContentUpdated?.(
|
|
748
|
+
this.callbacks.onAssistantContentUpdated?.(
|
|
749
|
+
lastMessage.id,
|
|
750
|
+
chunk,
|
|
751
|
+
newAccumulatedContent,
|
|
752
|
+
);
|
|
726
753
|
|
|
727
754
|
// Note: Subagent-specific callbacks are now handled by SubagentManager
|
|
728
755
|
|
|
@@ -793,6 +820,7 @@ export class MessageManager {
|
|
|
793
820
|
|
|
794
821
|
// Trigger callbacks with chunk and accumulated reasoning content
|
|
795
822
|
this.callbacks.onAssistantReasoningUpdated?.(
|
|
823
|
+
lastMessage.id,
|
|
796
824
|
chunk,
|
|
797
825
|
newAccumulatedReasoning,
|
|
798
826
|
);
|
|
@@ -503,7 +503,9 @@ export class SkillManager extends EventEmitter {
|
|
|
503
503
|
private async executeBashInSkillContent(content: string): Promise<string> {
|
|
504
504
|
const { commands } = parseBashCommands(content);
|
|
505
505
|
if (commands.length > 0) {
|
|
506
|
-
const
|
|
506
|
+
const currentWorkdir =
|
|
507
|
+
this.container.get<string>("Workdir") ?? this.workdir;
|
|
508
|
+
const results = await executeBashCommands(commands, currentWorkdir);
|
|
507
509
|
return replaceBashCommandsWithOutput(content, results);
|
|
508
510
|
}
|
|
509
511
|
return content;
|
|
@@ -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,35 @@ 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?: (
|
|
36
|
+
onSubagentAssistantMessageAdded?: (
|
|
37
|
+
subagentId: string,
|
|
38
|
+
messageId: string,
|
|
39
|
+
) => void;
|
|
37
40
|
/** Triggered during subagent content streaming updates */
|
|
38
41
|
onSubagentAssistantContentUpdated?: (
|
|
39
42
|
subagentId: string,
|
|
43
|
+
messageId: string,
|
|
40
44
|
chunk: string,
|
|
41
45
|
accumulated: string,
|
|
42
46
|
) => void;
|
|
43
47
|
/** Triggered during subagent reasoning streaming updates */
|
|
44
48
|
onSubagentAssistantReasoningUpdated?: (
|
|
45
49
|
subagentId: string,
|
|
50
|
+
messageId: string,
|
|
46
51
|
chunk: string,
|
|
47
52
|
accumulated: string,
|
|
48
53
|
) => void;
|
|
49
54
|
/** Triggered when subagent tool block is updated */
|
|
50
55
|
onSubagentToolBlockUpdated?: (
|
|
51
56
|
subagentId: string,
|
|
52
|
-
params:
|
|
57
|
+
params: ToolBlockUpdateCallbackParams,
|
|
53
58
|
) => void;
|
|
54
59
|
/** Triggered when subagent messages change */
|
|
55
60
|
onSubagentMessagesChange?: (subagentId: string, messages: Message[]) => void;
|
|
@@ -777,35 +782,45 @@ export class SubagentManager {
|
|
|
777
782
|
}
|
|
778
783
|
},
|
|
779
784
|
|
|
780
|
-
onAssistantMessageAdded: () => {
|
|
785
|
+
onAssistantMessageAdded: (messageId: string) => {
|
|
781
786
|
// Forward assistant message events to parent via SubagentManager callbacks
|
|
782
787
|
if (this.callbacks?.onSubagentAssistantMessageAdded) {
|
|
783
|
-
this.callbacks.onSubagentAssistantMessageAdded(subagentId);
|
|
788
|
+
this.callbacks.onSubagentAssistantMessageAdded(subagentId, messageId);
|
|
784
789
|
}
|
|
785
790
|
},
|
|
786
791
|
|
|
787
|
-
onAssistantContentUpdated: (
|
|
792
|
+
onAssistantContentUpdated: (
|
|
793
|
+
messageId: string,
|
|
794
|
+
chunk: string,
|
|
795
|
+
accumulated: string,
|
|
796
|
+
) => {
|
|
788
797
|
// Forward assistant content updates to parent via SubagentManager callbacks
|
|
789
798
|
if (this.callbacks?.onSubagentAssistantContentUpdated) {
|
|
790
799
|
this.callbacks.onSubagentAssistantContentUpdated(
|
|
791
800
|
subagentId,
|
|
801
|
+
messageId,
|
|
792
802
|
chunk,
|
|
793
803
|
accumulated,
|
|
794
804
|
);
|
|
795
805
|
}
|
|
796
806
|
},
|
|
797
|
-
onAssistantReasoningUpdated: (
|
|
807
|
+
onAssistantReasoningUpdated: (
|
|
808
|
+
messageId: string,
|
|
809
|
+
chunk: string,
|
|
810
|
+
accumulated: string,
|
|
811
|
+
) => {
|
|
798
812
|
// Forward assistant reasoning updates to parent via SubagentManager callbacks
|
|
799
813
|
if (this.callbacks?.onSubagentAssistantReasoningUpdated) {
|
|
800
814
|
this.callbacks.onSubagentAssistantReasoningUpdated(
|
|
801
815
|
subagentId,
|
|
816
|
+
messageId,
|
|
802
817
|
chunk,
|
|
803
818
|
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
|
|
@@ -28,8 +28,9 @@ let _anonymousId: string | undefined;
|
|
|
28
28
|
export class AuthService {
|
|
29
29
|
private static instance: AuthService;
|
|
30
30
|
private _serverUrl: string | undefined;
|
|
31
|
-
private onAuthChangeCallbacks: Array<
|
|
32
|
-
|
|
31
|
+
private onAuthChangeCallbacks: Array<
|
|
32
|
+
(event: "login" | "logout") => void | Promise<void>
|
|
33
|
+
> = [];
|
|
33
34
|
private _refreshPromise: Promise<boolean> | null = null;
|
|
34
35
|
private _authFileMtime: number = 0;
|
|
35
36
|
private static readonly REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
@@ -53,7 +54,9 @@ export class AuthService {
|
|
|
53
54
|
* Register a callback for auth state changes.
|
|
54
55
|
* Returns an unsubscribe function.
|
|
55
56
|
*/
|
|
56
|
-
onAuthChange(
|
|
57
|
+
onAuthChange(
|
|
58
|
+
callback: (event: "login" | "logout") => void | Promise<void>,
|
|
59
|
+
): () => void {
|
|
57
60
|
this.onAuthChangeCallbacks.push(callback);
|
|
58
61
|
return () => {
|
|
59
62
|
this.onAuthChangeCallbacks = this.onAuthChangeCallbacks.filter(
|
|
@@ -62,10 +65,10 @@ export class AuthService {
|
|
|
62
65
|
};
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
private notifyAuthChange(event: "login" | "logout"): void {
|
|
68
|
+
private async notifyAuthChange(event: "login" | "logout"): Promise<void> {
|
|
66
69
|
for (const cb of this.onAuthChangeCallbacks) {
|
|
67
70
|
try {
|
|
68
|
-
cb(event);
|
|
71
|
+
await cb(event);
|
|
69
72
|
} catch {
|
|
70
73
|
// Don't let callback errors break auth flow
|
|
71
74
|
}
|
|
@@ -112,7 +115,7 @@ export class AuthService {
|
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
clearAuth(): void {
|
|
118
|
+
async clearAuth(): Promise<void> {
|
|
116
119
|
const config = this.loadAuth();
|
|
117
120
|
delete config.SSO_TOKEN;
|
|
118
121
|
delete config.SSO_REFRESH_TOKEN;
|
|
@@ -125,7 +128,7 @@ export class AuthService {
|
|
|
125
128
|
} else {
|
|
126
129
|
this.saveAuth(config);
|
|
127
130
|
}
|
|
128
|
-
this.notifyAuthChange("logout");
|
|
131
|
+
await this.notifyAuthChange("logout");
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
getSSOToken(): string | undefined {
|
|
@@ -177,7 +180,7 @@ export class AuthService {
|
|
|
177
180
|
user,
|
|
178
181
|
});
|
|
179
182
|
|
|
180
|
-
this.notifyAuthChange("login");
|
|
183
|
+
await this.notifyAuthChange("login");
|
|
181
184
|
|
|
182
185
|
return token;
|
|
183
186
|
}
|
|
@@ -385,7 +388,7 @@ export class AuthService {
|
|
|
385
388
|
logger.info(
|
|
386
389
|
`[Auth] Refresh token rejected (${response.status}), clearing auth`,
|
|
387
390
|
);
|
|
388
|
-
this.clearAuth();
|
|
391
|
+
await this.clearAuth();
|
|
389
392
|
return false;
|
|
390
393
|
}
|
|
391
394
|
|
|
@@ -412,7 +415,7 @@ export class AuthService {
|
|
|
412
415
|
logger.info(
|
|
413
416
|
`[Auth] Token refreshed successfully, new token expires at ${newExpiresAt ? new Date(newExpiresAt).toISOString() : "never"}`,
|
|
414
417
|
);
|
|
415
|
-
this.notifyAuthChange("login");
|
|
418
|
+
await this.notifyAuthChange("login");
|
|
416
419
|
return true;
|
|
417
420
|
} catch (err) {
|
|
418
421
|
// Network error — don't clear auth (might be transient)
|
|
@@ -18,6 +18,32 @@ const FETCH_TIMEOUT_MS = 10_000;
|
|
|
18
18
|
|
|
19
19
|
let _cachedSettings: RemoteSettingsCache | null = null;
|
|
20
20
|
let _pollingTimer: ReturnType<typeof setInterval> | null = null;
|
|
21
|
+
let _onSettingsUpdateCallbacks: Array<() => void | Promise<void>> = [];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Register a callback invoked when remote settings change (checksum differs).
|
|
25
|
+
* Returns an unsubscribe function.
|
|
26
|
+
*/
|
|
27
|
+
export function onSettingsUpdate(
|
|
28
|
+
callback: () => void | Promise<void>,
|
|
29
|
+
): () => void {
|
|
30
|
+
_onSettingsUpdateCallbacks.push(callback);
|
|
31
|
+
return () => {
|
|
32
|
+
_onSettingsUpdateCallbacks = _onSettingsUpdateCallbacks.filter(
|
|
33
|
+
(cb) => cb !== callback,
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function notifySettingsUpdate(): Promise<void> {
|
|
39
|
+
for (const cb of _onSettingsUpdateCallbacks) {
|
|
40
|
+
try {
|
|
41
|
+
await cb();
|
|
42
|
+
} catch {
|
|
43
|
+
// Don't let callback errors break the fetch flow
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
21
47
|
|
|
22
48
|
function loadCacheFromDisk(): void {
|
|
23
49
|
try {
|
|
@@ -77,6 +103,8 @@ async function fetchRemoteSettings(): Promise<RemoteSettingsFetchResult> {
|
|
|
77
103
|
return { success: false, error: "Missing SSO token or server URL" };
|
|
78
104
|
}
|
|
79
105
|
|
|
106
|
+
const oldChecksum = _cachedSettings?.checksum;
|
|
107
|
+
|
|
80
108
|
const headers: Record<string, string> = {
|
|
81
109
|
Authorization: `Bearer ${token}`,
|
|
82
110
|
};
|
|
@@ -107,6 +135,9 @@ async function fetchRemoteSettings(): Promise<RemoteSettingsFetchResult> {
|
|
|
107
135
|
logger.debug("remoteSettings: 404 not configured — clearing stale cache");
|
|
108
136
|
_cachedSettings = null;
|
|
109
137
|
removeCacheFromDisk();
|
|
138
|
+
if (oldChecksum) {
|
|
139
|
+
await notifySettingsUpdate();
|
|
140
|
+
}
|
|
110
141
|
return { success: true, notConfigured: true, settings: null };
|
|
111
142
|
}
|
|
112
143
|
|
|
@@ -134,6 +165,9 @@ async function fetchRemoteSettings(): Promise<RemoteSettingsFetchResult> {
|
|
|
134
165
|
logger.debug("remoteSettings: fetched new settings", {
|
|
135
166
|
checksum: data.checksum,
|
|
136
167
|
});
|
|
168
|
+
if (data.checksum !== oldChecksum) {
|
|
169
|
+
await notifySettingsUpdate();
|
|
170
|
+
}
|
|
137
171
|
return {
|
|
138
172
|
success: true,
|
|
139
173
|
settings: data.settings,
|
|
@@ -312,4 +346,5 @@ export const remoteSettingsService = {
|
|
|
312
346
|
clear,
|
|
313
347
|
shutdown,
|
|
314
348
|
mergeRemoteSettings,
|
|
349
|
+
onSettingsUpdate,
|
|
315
350
|
} as const;
|
|
@@ -161,9 +161,9 @@ export function setupAgentContainer(
|
|
|
161
161
|
container.register("McpManager", mcpManager);
|
|
162
162
|
|
|
163
163
|
// Wire up auth change callback to refresh/clear remote settings
|
|
164
|
-
authService.onAuthChange((event) => {
|
|
164
|
+
authService.onAuthChange(async (event) => {
|
|
165
165
|
if (event === "login") {
|
|
166
|
-
remoteSettingsService.refresh();
|
|
166
|
+
await remoteSettingsService.refresh();
|
|
167
167
|
} else if (event === "logout") {
|
|
168
168
|
remoteSettingsService.clear();
|
|
169
169
|
}
|
|
@@ -300,6 +300,12 @@ export function setupAgentContainer(
|
|
|
300
300
|
});
|
|
301
301
|
container.register("LiveConfigManager", liveConfigManager);
|
|
302
302
|
|
|
303
|
+
// Wire up remote settings hot-update: when polling detects changed settings,
|
|
304
|
+
// reload configuration so admin changes propagate to the running agent.
|
|
305
|
+
remoteSettingsService.onSettingsUpdate(async () => {
|
|
306
|
+
await liveConfigManager.reload();
|
|
307
|
+
});
|
|
308
|
+
|
|
303
309
|
const subagentManager = new SubagentManager(container, {
|
|
304
310
|
workdir,
|
|
305
311
|
callbacks: {
|
|
@@ -58,6 +58,14 @@ export type AgentToolBlockUpdateParams = Omit<
|
|
|
58
58
|
"messages"
|
|
59
59
|
>;
|
|
60
60
|
|
|
61
|
+
// Callback payload type — SDK always fills messageId (required)
|
|
62
|
+
export type ToolBlockUpdateCallbackParams = Omit<
|
|
63
|
+
AgentToolBlockUpdateParams,
|
|
64
|
+
"messageId"
|
|
65
|
+
> & {
|
|
66
|
+
messageId: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
61
69
|
export interface AddErrorBlockParams {
|
|
62
70
|
messages: Message[];
|
|
63
71
|
error: string;
|
|
@@ -289,7 +297,7 @@ export const updateToolBlockInMessage = ({
|
|
|
289
297
|
compactParams,
|
|
290
298
|
parametersChunk,
|
|
291
299
|
isManuallyBackgrounded,
|
|
292
|
-
}: UpdateToolBlockParams): Message[] => {
|
|
300
|
+
}: UpdateToolBlockParams): { messages: Message[]; messageId?: string } => {
|
|
293
301
|
const newMessages = [...messages];
|
|
294
302
|
|
|
295
303
|
// If messageId is provided, target that specific message
|
|
@@ -321,7 +329,7 @@ export const updateToolBlockInMessage = ({
|
|
|
321
329
|
}
|
|
322
330
|
}
|
|
323
331
|
}
|
|
324
|
-
return newMessages;
|
|
332
|
+
return { messages: newMessages, messageId };
|
|
325
333
|
}
|
|
326
334
|
|
|
327
335
|
// Find the last assistant or user message
|
|
@@ -350,7 +358,8 @@ export const updateToolBlockInMessage = ({
|
|
|
350
358
|
if (isManuallyBackgrounded !== undefined)
|
|
351
359
|
toolBlock.isManuallyBackgrounded = isManuallyBackgrounded;
|
|
352
360
|
}
|
|
353
|
-
|
|
361
|
+
const foundMessageId = newMessages[i].id;
|
|
362
|
+
return { messages: newMessages, messageId: foundMessageId };
|
|
354
363
|
} else if (newMessages[i].role === "assistant") {
|
|
355
364
|
// If existing block not found in assistant message, create new one
|
|
356
365
|
// This handles cases where we're streaming tool parameters before execution
|
|
@@ -370,11 +379,12 @@ export const updateToolBlockInMessage = ({
|
|
|
370
379
|
parametersChunk: parametersChunk,
|
|
371
380
|
isManuallyBackgrounded: isManuallyBackgrounded,
|
|
372
381
|
});
|
|
373
|
-
|
|
382
|
+
const foundMessageId = newMessages[i].id;
|
|
383
|
+
return { messages: newMessages, messageId: foundMessageId };
|
|
374
384
|
}
|
|
375
385
|
}
|
|
376
386
|
}
|
|
377
|
-
return newMessages;
|
|
387
|
+
return { messages: newMessages };
|
|
378
388
|
};
|
|
379
389
|
|
|
380
390
|
// Add Error Block to the last assistant message
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Message } from "../types/messaging.js";
|
|
2
|
-
export interface MicrocompactOptions {
|
|
3
|
-
timeThresholdMS: number;
|
|
4
|
-
recentResultsToKeep: number;
|
|
5
|
-
}
|
|
6
|
-
export declare function microcompactMessages(messages: Message[], options: MicrocompactOptions): Message[];
|
|
7
|
-
//# sourceMappingURL=microcompact.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"microcompact.d.ts","sourceRoot":"","sources":["../../src/utils/microcompact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,uBAAuB,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,EAAE,CAwFX"}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
const CLEARED_RESULT = "[Old tool result content cleared]";
|
|
2
|
-
export function microcompactMessages(messages, options) {
|
|
3
|
-
const { timeThresholdMS, recentResultsToKeep } = options;
|
|
4
|
-
// 1. Find the latest tool block timestamp across all assistant messages
|
|
5
|
-
let lastAssistantTime = 0;
|
|
6
|
-
for (const msg of messages) {
|
|
7
|
-
if (msg.role === "assistant") {
|
|
8
|
-
for (const block of msg.blocks) {
|
|
9
|
-
if (block.type === "tool" && block.stage === "end" && block.timestamp) {
|
|
10
|
-
if (block.timestamp > lastAssistantTime) {
|
|
11
|
-
lastAssistantTime = block.timestamp;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
// 2. If no prior assistant messages with completed tools, return unchanged
|
|
18
|
-
if (lastAssistantTime === 0) {
|
|
19
|
-
return messages;
|
|
20
|
-
}
|
|
21
|
-
// 3. If within threshold, return unchanged
|
|
22
|
-
if (Date.now() - lastAssistantTime < timeThresholdMS) {
|
|
23
|
-
return messages;
|
|
24
|
-
}
|
|
25
|
-
const toolRefs = [];
|
|
26
|
-
for (let mi = 0; mi < messages.length; mi++) {
|
|
27
|
-
const msg = messages[mi];
|
|
28
|
-
if (msg.role === "assistant") {
|
|
29
|
-
for (let bi = 0; bi < msg.blocks.length; bi++) {
|
|
30
|
-
const block = msg.blocks[bi];
|
|
31
|
-
if (block.type === "tool" && block.stage === "end" && block.timestamp) {
|
|
32
|
-
toolRefs.push({
|
|
33
|
-
msgIndex: mi,
|
|
34
|
-
blockIndex: bi,
|
|
35
|
-
timestamp: block.timestamp,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
toolRefs.sort((a, b) => b.timestamp - a.timestamp);
|
|
42
|
-
// 5. Mark the top N as "keep"
|
|
43
|
-
const keepSet = new Set();
|
|
44
|
-
for (let i = 0; i < Math.min(recentResultsToKeep, toolRefs.length); i++) {
|
|
45
|
-
const ref = toolRefs[i];
|
|
46
|
-
keepSet.add(`${ref.msgIndex}:${ref.blockIndex}`);
|
|
47
|
-
}
|
|
48
|
-
// 6. Deep-copy messages and clear result + shortResult on non-kept blocks
|
|
49
|
-
const result = messages.map((msg) => ({
|
|
50
|
-
...msg,
|
|
51
|
-
blocks: msg.blocks.map((block) => {
|
|
52
|
-
if (block.type === "tool" && block.stage === "end" && block.timestamp) {
|
|
53
|
-
return { ...block };
|
|
54
|
-
}
|
|
55
|
-
return block;
|
|
56
|
-
}),
|
|
57
|
-
}));
|
|
58
|
-
// Clear non-kept tool blocks
|
|
59
|
-
for (const ref of toolRefs) {
|
|
60
|
-
const key = `${ref.msgIndex}:${ref.blockIndex}`;
|
|
61
|
-
if (!keepSet.has(key)) {
|
|
62
|
-
result[ref.msgIndex] = {
|
|
63
|
-
...result[ref.msgIndex],
|
|
64
|
-
blocks: result[ref.msgIndex].blocks.map((b, idx) => {
|
|
65
|
-
if (idx === ref.blockIndex && b.type === "tool") {
|
|
66
|
-
return {
|
|
67
|
-
...b,
|
|
68
|
-
result: CLEARED_RESULT,
|
|
69
|
-
shortResult: undefined,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
return b;
|
|
73
|
-
}),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return result;
|
|
78
|
-
}
|