wave-agent-sdk 0.5.0 → 0.6.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/dist/agent.d.ts +14 -6
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +65 -88
- package/dist/constants/prompts.d.ts +18 -14
- package/dist/constants/prompts.d.ts.map +1 -1
- package/dist/constants/prompts.js +130 -54
- package/dist/constants/tools.d.ts +4 -1
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/managers/aiManager.d.ts +2 -5
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +59 -48
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +59 -53
- package/dist/managers/foregroundTaskManager.d.ts.map +1 -1
- package/dist/managers/foregroundTaskManager.js +3 -2
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/messageManager.d.ts +14 -10
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +102 -62
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +25 -15
- package/dist/managers/planManager.d.ts +1 -1
- package/dist/managers/planManager.d.ts.map +1 -1
- package/dist/managers/planManager.js +2 -2
- package/dist/managers/slashCommandManager.d.ts +3 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +7 -2
- package/dist/managers/subagentManager.d.ts +4 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +22 -14
- package/dist/managers/toolManager.d.ts +11 -0
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +20 -2
- package/dist/services/aiService.d.ts +0 -1
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +4 -140
- package/dist/services/memory.d.ts +0 -3
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +0 -59
- package/dist/services/session.d.ts +15 -1
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +57 -1
- package/dist/services/taskManager.d.ts +21 -0
- package/dist/services/taskManager.d.ts.map +1 -0
- package/dist/services/taskManager.js +158 -0
- package/dist/tools/askUserQuestion.d.ts.map +1 -1
- package/dist/tools/askUserQuestion.js +39 -25
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +7 -9
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +2 -1
- package/dist/tools/exitPlanMode.d.ts.map +1 -1
- package/dist/tools/exitPlanMode.js +25 -1
- package/dist/tools/globTool.d.ts.map +1 -1
- package/dist/tools/globTool.js +8 -2
- package/dist/tools/grepTool.d.ts.map +1 -1
- package/dist/tools/grepTool.js +17 -6
- package/dist/tools/lsTool.d.ts.map +1 -1
- package/dist/tools/lsTool.js +3 -1
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +16 -1
- package/dist/tools/taskManagementTools.d.ts +6 -0
- package/dist/tools/taskManagementTools.d.ts.map +1 -0
- package/dist/tools/taskManagementTools.js +453 -0
- package/dist/tools/taskOutputTool.d.ts.map +1 -1
- package/dist/tools/taskOutputTool.js +32 -8
- package/dist/tools/taskStopTool.d.ts.map +1 -1
- package/dist/tools/taskStopTool.js +7 -1
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +6 -1
- package/dist/tools/types.d.ts +9 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +9 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/messaging.d.ts +2 -8
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/processes.d.ts +11 -6
- package/dist/types/processes.d.ts.map +1 -1
- package/dist/types/tasks.d.ts +13 -0
- package/dist/types/tasks.d.ts.map +1 -0
- package/dist/types/tasks.js +1 -0
- package/dist/types/tools.d.ts +4 -1
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/builtinSubagents.d.ts.map +1 -1
- package/dist/utils/builtinSubagents.js +38 -1
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +18 -12
- package/dist/utils/constants.d.ts +0 -4
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +0 -4
- package/dist/utils/convertMessagesForAPI.js +2 -2
- package/dist/utils/messageOperations.d.ts +2 -35
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +4 -97
- package/dist/utils/nameGenerator.d.ts +1 -1
- package/dist/utils/nameGenerator.d.ts.map +1 -1
- package/dist/utils/nameGenerator.js +19 -3
- package/package.json +1 -1
- package/src/agent.ts +90 -101
- package/src/constants/prompts.ts +156 -65
- package/src/constants/tools.ts +4 -1
- package/src/index.ts +1 -0
- package/src/managers/aiManager.ts +79 -70
- package/src/managers/backgroundTaskManager.ts +53 -54
- package/src/managers/foregroundTaskManager.ts +3 -2
- package/src/managers/mcpManager.ts +6 -3
- package/src/managers/messageManager.ts +137 -73
- package/src/managers/permissionManager.ts +32 -21
- package/src/managers/planManager.ts +2 -2
- package/src/managers/slashCommandManager.ts +11 -2
- package/src/managers/subagentManager.ts +33 -14
- package/src/managers/toolManager.ts +32 -2
- package/src/services/aiService.ts +3 -145
- package/src/services/memory.ts +0 -72
- package/src/services/session.ts +73 -0
- package/src/services/taskManager.ts +188 -0
- package/src/tools/askUserQuestion.ts +51 -29
- package/src/tools/bashTool.ts +9 -15
- package/src/tools/editTool.ts +3 -1
- package/src/tools/exitPlanMode.ts +26 -2
- package/src/tools/globTool.ts +10 -2
- package/src/tools/grepTool.ts +17 -6
- package/src/tools/lsTool.ts +3 -1
- package/src/tools/readTool.ts +17 -1
- package/src/tools/taskManagementTools.ts +498 -0
- package/src/tools/taskOutputTool.ts +34 -12
- package/src/tools/taskStopTool.ts +7 -1
- package/src/tools/taskTool.ts +7 -1
- package/src/tools/types.ts +10 -0
- package/src/tools/writeTool.ts +9 -2
- package/src/types/index.ts +1 -0
- package/src/types/messaging.ts +1 -9
- package/src/types/processes.ts +13 -7
- package/src/types/tasks.ts +13 -0
- package/src/types/tools.ts +4 -1
- package/src/utils/builtinSubagents.ts +47 -1
- package/src/utils/cacheControlUtils.ts +26 -18
- package/src/utils/constants.ts +0 -5
- package/src/utils/convertMessagesForAPI.ts +2 -2
- package/src/utils/messageOperations.ts +5 -136
- package/src/utils/nameGenerator.ts +20 -3
- package/dist/tools/todoWriteTool.d.ts +0 -6
- package/dist/tools/todoWriteTool.d.ts.map +0 -1
- package/dist/tools/todoWriteTool.js +0 -220
- package/src/tools/todoWriteTool.ts +0 -257
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
import { MessageSource } from "../types/index.js";
|
|
2
|
-
import { DEFAULT_KEEP_LAST_MESSAGES_COUNT } from "./constants.js";
|
|
3
1
|
import { readFileSync } from "fs";
|
|
4
2
|
import { extname } from "path";
|
|
5
3
|
import { logger } from "./globalLogger.js";
|
|
6
|
-
/**
|
|
7
|
-
* Extract text content from user messages in the messages array
|
|
8
|
-
* Excludes messages with source HOOK to prevent hook-generated content from entering user history
|
|
9
|
-
*/
|
|
10
|
-
export const extractUserInputHistory = (messages) => {
|
|
11
|
-
return messages
|
|
12
|
-
.filter((message) => message.role === "user")
|
|
13
|
-
.map((message) => {
|
|
14
|
-
// Extract text block content, excluding HOOK-sourced blocks
|
|
15
|
-
const textBlocks = message.blocks.filter((block) => block.type === "text" && block.source !== MessageSource.HOOK);
|
|
16
|
-
return textBlocks
|
|
17
|
-
.map((block) => block.content)
|
|
18
|
-
.join(" ")
|
|
19
|
-
.trim();
|
|
20
|
-
})
|
|
21
|
-
.filter((text) => text.length > 0); // Filter out empty text
|
|
22
|
-
};
|
|
23
4
|
/**
|
|
24
5
|
* Convert image file path to base64 format
|
|
25
6
|
* @param imagePath Image file path
|
|
@@ -116,7 +97,7 @@ export const addAssistantMessageToMessages = (messages, content, toolCalls, usag
|
|
|
116
97
|
return [...messages, initialAssistantMessage];
|
|
117
98
|
};
|
|
118
99
|
// Update Tool Block of the last assistant message
|
|
119
|
-
export const updateToolBlockInMessage = ({ messages, id, parameters, result, success, error, stage, name, shortResult, images, compactParams, parametersChunk, }) => {
|
|
100
|
+
export const updateToolBlockInMessage = ({ messages, id, parameters, result, success, error, stage, name, shortResult, images, compactParams, parametersChunk, isManuallyBackgrounded, }) => {
|
|
120
101
|
const newMessages = [...messages];
|
|
121
102
|
// Find the last assistant message
|
|
122
103
|
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
@@ -141,6 +122,8 @@ export const updateToolBlockInMessage = ({ messages, id, parameters, result, suc
|
|
|
141
122
|
toolBlock.compactParams = compactParams;
|
|
142
123
|
if (parametersChunk !== undefined)
|
|
143
124
|
toolBlock.parametersChunk = parametersChunk;
|
|
125
|
+
if (isManuallyBackgrounded !== undefined)
|
|
126
|
+
toolBlock.isManuallyBackgrounded = isManuallyBackgrounded;
|
|
144
127
|
}
|
|
145
128
|
}
|
|
146
129
|
else {
|
|
@@ -159,6 +142,7 @@ export const updateToolBlockInMessage = ({ messages, id, parameters, result, suc
|
|
|
159
142
|
stage: stage ?? "start",
|
|
160
143
|
compactParams: compactParams,
|
|
161
144
|
parametersChunk: parametersChunk,
|
|
145
|
+
isManuallyBackgrounded: isManuallyBackgrounded,
|
|
162
146
|
});
|
|
163
147
|
}
|
|
164
148
|
break;
|
|
@@ -198,83 +182,6 @@ export const addErrorBlockToMessage = ({ messages, error, }) => {
|
|
|
198
182
|
}
|
|
199
183
|
return newMessages;
|
|
200
184
|
};
|
|
201
|
-
// Add Memory Block as new assistant message
|
|
202
|
-
export const addMemoryBlockToMessage = ({ messages, content, isSuccess, memoryType, storagePath, }) => {
|
|
203
|
-
const newMessages = [...messages];
|
|
204
|
-
// Create new assistant message containing MemoryBlock
|
|
205
|
-
const memoryMessage = {
|
|
206
|
-
role: "assistant",
|
|
207
|
-
blocks: [
|
|
208
|
-
{
|
|
209
|
-
type: "memory",
|
|
210
|
-
content,
|
|
211
|
-
isSuccess,
|
|
212
|
-
memoryType,
|
|
213
|
-
storagePath,
|
|
214
|
-
},
|
|
215
|
-
],
|
|
216
|
-
};
|
|
217
|
-
// Add to end of message list
|
|
218
|
-
newMessages.push(memoryMessage);
|
|
219
|
-
return newMessages;
|
|
220
|
-
};
|
|
221
|
-
/**
|
|
222
|
-
* Count valid blocks from the end
|
|
223
|
-
* Only text, image, and tool type blocks are counted
|
|
224
|
-
* @param messages Message array
|
|
225
|
-
* @param targetCount Number of valid blocks to count
|
|
226
|
-
* @returns { messageIndex: number, blockCount: number } Message index and actual counted block count
|
|
227
|
-
*/
|
|
228
|
-
export const countValidBlocksFromEnd = (messages, targetCount) => {
|
|
229
|
-
let validBlockCount = 0;
|
|
230
|
-
// Iterate messages from end to beginning
|
|
231
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
232
|
-
const message = messages[i];
|
|
233
|
-
// Iterate through all blocks of current message
|
|
234
|
-
for (const block of message.blocks) {
|
|
235
|
-
// Only count valid block types
|
|
236
|
-
if (block.type === "text" ||
|
|
237
|
-
block.type === "image" ||
|
|
238
|
-
block.type === "tool") {
|
|
239
|
-
validBlockCount++;
|
|
240
|
-
// If target count reached, return current message index
|
|
241
|
-
if (validBlockCount >= targetCount) {
|
|
242
|
-
return { messageIndex: i, blockCount: validBlockCount };
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
// If target count not reached, return index 0
|
|
248
|
-
return { messageIndex: 0, blockCount: validBlockCount };
|
|
249
|
-
};
|
|
250
|
-
/**
|
|
251
|
-
* Get messages to be compressed and insertion position
|
|
252
|
-
* @param messages Message array
|
|
253
|
-
* @param keepLastCount Keep the last few valid blocks uncompressed
|
|
254
|
-
* @returns { messagesToCompress: Message[], insertIndex: number }
|
|
255
|
-
*/
|
|
256
|
-
export const getMessagesToCompress = (messages, keepLastCount = DEFAULT_KEEP_LAST_MESSAGES_COUNT) => {
|
|
257
|
-
// Calculate message position to keep from end to beginning
|
|
258
|
-
const { messageIndex } = countValidBlocksFromEnd(messages, keepLastCount);
|
|
259
|
-
// Find the last message containing compression block
|
|
260
|
-
let lastCompressIndex = -1;
|
|
261
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
262
|
-
const hasCompressBlock = messages[i].blocks.some((block) => block.type === "compress");
|
|
263
|
-
if (hasCompressBlock) {
|
|
264
|
-
lastCompressIndex = i;
|
|
265
|
-
break;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
// Determine compression start position
|
|
269
|
-
// If compression block exists, start from compression block position (include compression block)
|
|
270
|
-
// If no compression block, start from beginning
|
|
271
|
-
const startIndex = lastCompressIndex >= 0 ? lastCompressIndex : 0;
|
|
272
|
-
// Messages to compress are all messages from start position to before calculated position
|
|
273
|
-
const messagesToCompress = messages.slice(startIndex, messageIndex);
|
|
274
|
-
// Change insertion position to negative number, indicating position from end
|
|
275
|
-
const insertIndex = messageIndex - messages.length;
|
|
276
|
-
return { messagesToCompress, insertIndex };
|
|
277
|
-
};
|
|
278
185
|
// Add command output block to message list
|
|
279
186
|
export const addCommandOutputMessage = ({ messages, command, }) => {
|
|
280
187
|
const outputMessage = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nameGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/nameGenerator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoEH;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"nameGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/nameGenerator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoEH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAqBxD"}
|
|
@@ -68,8 +68,24 @@ const nouns = [
|
|
|
68
68
|
/**
|
|
69
69
|
* Generates a random English name (adjective-noun)
|
|
70
70
|
*/
|
|
71
|
-
export function generateRandomName() {
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
export function generateRandomName(seed) {
|
|
72
|
+
let adjIndex;
|
|
73
|
+
let nounIndex;
|
|
74
|
+
if (seed) {
|
|
75
|
+
// Simple hash function to derive indices from seed
|
|
76
|
+
let hash = 0;
|
|
77
|
+
for (let i = 0; i < seed.length; i++) {
|
|
78
|
+
hash = (hash << 5) - hash + seed.charCodeAt(i);
|
|
79
|
+
hash |= 0; // Convert to 32bit integer
|
|
80
|
+
}
|
|
81
|
+
adjIndex = Math.abs(hash) % adjectives.length;
|
|
82
|
+
nounIndex = Math.abs(hash >> 8) % nouns.length;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
adjIndex = Math.floor(Math.random() * adjectives.length);
|
|
86
|
+
nounIndex = Math.floor(Math.random() * nouns.length);
|
|
87
|
+
}
|
|
88
|
+
const adj = adjectives[adjIndex];
|
|
89
|
+
const noun = nouns[nounIndex];
|
|
74
90
|
return `${adj}-${noun}`;
|
|
75
91
|
}
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
SubagentManager,
|
|
10
10
|
type SubagentManagerCallbacks,
|
|
11
11
|
} from "./managers/subagentManager.js";
|
|
12
|
-
import * as memory from "./services/memory.js";
|
|
13
12
|
import { McpManager, type McpManagerCallbacks } from "./managers/mcpManager.js";
|
|
14
13
|
import { LspManager } from "./managers/lspManager.js";
|
|
15
14
|
import { BashManager } from "./managers/bashManager.js";
|
|
@@ -46,6 +45,7 @@ import { MemoryRuleManager } from "./managers/MemoryRuleManager.js";
|
|
|
46
45
|
import { LiveConfigManager } from "./managers/liveConfigManager.js";
|
|
47
46
|
import { configValidator } from "./utils/configValidator.js";
|
|
48
47
|
import { SkillManager } from "./managers/skillManager.js";
|
|
48
|
+
import { TaskManager } from "./services/taskManager.js";
|
|
49
49
|
import {
|
|
50
50
|
loadSessionFromJsonl,
|
|
51
51
|
handleSessionRestoration,
|
|
@@ -107,7 +107,12 @@ export interface AgentCallbacks
|
|
|
107
107
|
McpManagerCallbacks,
|
|
108
108
|
SubagentManagerCallbacks {
|
|
109
109
|
onTasksChange?: (tasks: BackgroundTask[]) => void;
|
|
110
|
+
onSessionTasksChange?: (tasks: import("./types/tasks.js").Task[]) => void;
|
|
110
111
|
onPermissionModeChange?: (mode: PermissionMode) => void;
|
|
112
|
+
onSubagentLatestTotalTokensChange?: (
|
|
113
|
+
subagentId: string,
|
|
114
|
+
tokens: number,
|
|
115
|
+
) => void;
|
|
111
116
|
onBackgroundCurrentTask?: () => void;
|
|
112
117
|
}
|
|
113
118
|
|
|
@@ -131,6 +136,7 @@ export class Agent {
|
|
|
131
136
|
private reversionManager: ReversionManager;
|
|
132
137
|
private memoryRuleManager: MemoryRuleManager; // Add memory rule manager instance
|
|
133
138
|
private liveConfigManager: LiveConfigManager; // Add live configuration manager
|
|
139
|
+
private taskManager: TaskManager;
|
|
134
140
|
private foregroundTaskManager: ForegroundTaskManager;
|
|
135
141
|
private configurationService: ConfigurationService; // Add configuration service
|
|
136
142
|
private workdir: string; // Working directory
|
|
@@ -208,6 +214,46 @@ export class Agent {
|
|
|
208
214
|
|
|
209
215
|
this.foregroundTaskManager = new ForegroundTaskManager();
|
|
210
216
|
|
|
217
|
+
// Initialize memory rule manager
|
|
218
|
+
this.memoryRuleManager = new MemoryRuleManager({
|
|
219
|
+
workdir: this.workdir,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Initialize MessageManager
|
|
223
|
+
this.messageManager = new MessageManager({
|
|
224
|
+
callbacks: {
|
|
225
|
+
...callbacks,
|
|
226
|
+
onSessionIdChange: (sessionId) => {
|
|
227
|
+
// When session ID changes (e.g. due to compression),
|
|
228
|
+
// we update the task manager to use the root session ID
|
|
229
|
+
// to ensure the task list remains consistent.
|
|
230
|
+
this.taskManager.setTaskListId(
|
|
231
|
+
this.messageManager.getRootSessionId(),
|
|
232
|
+
);
|
|
233
|
+
callbacks.onSessionIdChange?.(sessionId);
|
|
234
|
+
},
|
|
235
|
+
onSubagentTaskStopRequested: (subagentId) => {
|
|
236
|
+
this.backgroundTaskManager.stopTask(subagentId);
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
workdir: this.workdir,
|
|
240
|
+
logger: this.logger,
|
|
241
|
+
memoryRuleManager: this.memoryRuleManager,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Resolve taskListId once during construction to ensure stability
|
|
245
|
+
const resolvedTaskListId =
|
|
246
|
+
this.configurationService.getEnvironmentVars().WAVE_TASK_LIST_ID ||
|
|
247
|
+
process.env.WAVE_TASK_LIST_ID ||
|
|
248
|
+
this.messageManager.getRootSessionId();
|
|
249
|
+
|
|
250
|
+
this.taskManager = new TaskManager(resolvedTaskListId);
|
|
251
|
+
this.taskManager.on("tasksChange", async () => {
|
|
252
|
+
const tasks = await this.taskManager.listTasks();
|
|
253
|
+
this.options.callbacks?.onSessionTasksChange?.(tasks);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Initialize BackgroundTaskManager
|
|
211
257
|
this.backgroundTaskManager = new BackgroundTaskManager({
|
|
212
258
|
callbacks: {
|
|
213
259
|
...callbacks,
|
|
@@ -243,20 +289,7 @@ export class Agent {
|
|
|
243
289
|
workdir: this.workdir,
|
|
244
290
|
});
|
|
245
291
|
|
|
246
|
-
//
|
|
247
|
-
this.memoryRuleManager = new MemoryRuleManager({
|
|
248
|
-
workdir: this.workdir,
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Initialize MessageManager
|
|
252
|
-
this.messageManager = new MessageManager({
|
|
253
|
-
callbacks,
|
|
254
|
-
workdir: this.workdir,
|
|
255
|
-
logger: this.logger,
|
|
256
|
-
memoryRuleManager: this.memoryRuleManager,
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// Initialize ReversionManager
|
|
292
|
+
// ReversionManager depends on MessageManager
|
|
260
293
|
this.reversionManager = new ReversionManager(
|
|
261
294
|
new ReversionService(this.messageManager.getTranscriptPath()),
|
|
262
295
|
);
|
|
@@ -312,6 +345,7 @@ export class Agent {
|
|
|
312
345
|
reversionManager: this.reversionManager,
|
|
313
346
|
permissionMode: options.permissionMode, // Let PermissionManager handle defaultMode resolution
|
|
314
347
|
canUseToolCallback: canUseToolWithNotification,
|
|
348
|
+
taskManager: this.taskManager,
|
|
315
349
|
backgroundTaskManager: this.backgroundTaskManager,
|
|
316
350
|
foregroundTaskManager: this.foregroundTaskManager,
|
|
317
351
|
}); // Initialize tool registry with permission support
|
|
@@ -339,6 +373,8 @@ export class Agent {
|
|
|
339
373
|
callbacks.onSubagentAssistantReasoningUpdated,
|
|
340
374
|
onSubagentToolBlockUpdated: callbacks.onSubagentToolBlockUpdated,
|
|
341
375
|
onSubagentMessagesChange: callbacks.onSubagentMessagesChange,
|
|
376
|
+
onSubagentLatestTotalTokensChange:
|
|
377
|
+
callbacks.onSubagentLatestTotalTokensChange,
|
|
342
378
|
}, // Pass subagent callbacks for forwarding
|
|
343
379
|
logger: this.logger,
|
|
344
380
|
getGatewayConfig: () => this.getGatewayConfig(),
|
|
@@ -348,6 +384,7 @@ export class Agent {
|
|
|
348
384
|
hookManager: this.hookManager,
|
|
349
385
|
onUsageAdded: (usage) => this.addUsage(usage),
|
|
350
386
|
backgroundTaskManager: this.backgroundTaskManager,
|
|
387
|
+
taskManager: this.taskManager,
|
|
351
388
|
memoryRuleManager: this.memoryRuleManager,
|
|
352
389
|
});
|
|
353
390
|
|
|
@@ -355,6 +392,7 @@ export class Agent {
|
|
|
355
392
|
this.aiManager = new AIManager({
|
|
356
393
|
messageManager: this.messageManager,
|
|
357
394
|
toolManager: this.toolManager,
|
|
395
|
+
taskManager: this.taskManager,
|
|
358
396
|
logger: this.logger,
|
|
359
397
|
backgroundTaskManager: this.backgroundTaskManager,
|
|
360
398
|
hookManager: this.hookManager,
|
|
@@ -381,6 +419,7 @@ export class Agent {
|
|
|
381
419
|
messageManager: this.messageManager,
|
|
382
420
|
aiManager: this.aiManager,
|
|
383
421
|
backgroundTaskManager: this.backgroundTaskManager,
|
|
422
|
+
taskManager: this.taskManager,
|
|
384
423
|
workdir: this.workdir,
|
|
385
424
|
logger: this.logger,
|
|
386
425
|
});
|
|
@@ -455,10 +494,6 @@ export class Agent {
|
|
|
455
494
|
return this.messageManager.getlatestTotalTokens();
|
|
456
495
|
}
|
|
457
496
|
|
|
458
|
-
public get userInputHistory(): string[] {
|
|
459
|
-
return this.messageManager.getUserInputHistory();
|
|
460
|
-
}
|
|
461
|
-
|
|
462
497
|
/** Get working directory */
|
|
463
498
|
public get workingDirectory(): string {
|
|
464
499
|
return this.workdir;
|
|
@@ -780,8 +815,18 @@ export class Agent {
|
|
|
780
815
|
// After main session is restored, restore any associated subagent sessions
|
|
781
816
|
await this.restoreSubagentSessions(sessionToRestore?.messages || []);
|
|
782
817
|
|
|
783
|
-
if (sessionToRestore)
|
|
818
|
+
if (sessionToRestore) {
|
|
784
819
|
this.messageManager.initializeFromSession(sessionToRestore);
|
|
820
|
+
|
|
821
|
+
// Update task manager with the root session ID to ensure continuity across compressions
|
|
822
|
+
this.taskManager.setTaskListId(
|
|
823
|
+
sessionToRestore.rootSessionId || sessionToRestore.id,
|
|
824
|
+
);
|
|
825
|
+
|
|
826
|
+
// After session is initialized, load tasks for the session
|
|
827
|
+
const tasks = await this.taskManager.listTasks();
|
|
828
|
+
this.options.callbacks?.onSessionTasksChange?.(tasks);
|
|
829
|
+
}
|
|
785
830
|
}
|
|
786
831
|
}
|
|
787
832
|
|
|
@@ -904,6 +949,13 @@ export class Agent {
|
|
|
904
949
|
|
|
905
950
|
// 6. Initialize session state last
|
|
906
951
|
this.messageManager.initializeFromSession(sessionData);
|
|
952
|
+
|
|
953
|
+
// Update task manager with the root session ID to ensure continuity across compressions
|
|
954
|
+
this.taskManager.setTaskListId(sessionData.rootSessionId || sessionData.id);
|
|
955
|
+
|
|
956
|
+
// 7. Load tasks for the restored session
|
|
957
|
+
const tasks = await this.taskManager.listTasks();
|
|
958
|
+
this.options.callbacks?.onSessionTasksChange?.(tasks);
|
|
907
959
|
}
|
|
908
960
|
|
|
909
961
|
public abortAIMessage(): void {
|
|
@@ -912,12 +964,9 @@ export class Agent {
|
|
|
912
964
|
|
|
913
965
|
/** Execute bash command */
|
|
914
966
|
public async executeBashCommand(command: string): Promise<void> {
|
|
915
|
-
// Add user message to history (but not displayed in UI)
|
|
916
|
-
this.addToInputHistory(`!${command}`);
|
|
917
967
|
await this.bashManager?.executeCommand(command);
|
|
918
968
|
}
|
|
919
969
|
|
|
920
|
-
/** Clear messages and input history */
|
|
921
970
|
public clearMessages(): void {
|
|
922
971
|
this.messageManager.clearMessages();
|
|
923
972
|
}
|
|
@@ -929,11 +978,6 @@ export class Agent {
|
|
|
929
978
|
this.abortSlashCommand();
|
|
930
979
|
}
|
|
931
980
|
|
|
932
|
-
/** Add to input history */
|
|
933
|
-
private addToInputHistory(input: string): void {
|
|
934
|
-
this.messageManager.addToInputHistory(input);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
981
|
/** Interrupt bash command execution */
|
|
938
982
|
public abortBashCommand(): void {
|
|
939
983
|
this.bashManager?.abortCommand();
|
|
@@ -964,12 +1008,6 @@ export class Agent {
|
|
|
964
1008
|
public async backgroundCurrentTask(): Promise<void> {
|
|
965
1009
|
await this.foregroundTaskManager.backgroundCurrentTask();
|
|
966
1010
|
this.options.callbacks?.onBackgroundCurrentTask?.();
|
|
967
|
-
|
|
968
|
-
// If there was no foreground task (e.g. a tool that doesn't register one),
|
|
969
|
-
// or even if there was, we should stop the AI recursion loop.
|
|
970
|
-
if (!this.foregroundTaskManager.hasActiveTasks()) {
|
|
971
|
-
this.aiManager.abortRecursion();
|
|
972
|
-
}
|
|
973
1011
|
}
|
|
974
1012
|
|
|
975
1013
|
/** Destroy managers, clean up resources */
|
|
@@ -1061,8 +1099,6 @@ export class Agent {
|
|
|
1061
1099
|
// Execute valid slash command
|
|
1062
1100
|
await this.slashCommandManager.executeCommand(commandId, args);
|
|
1063
1101
|
|
|
1064
|
-
// Add slash command to history
|
|
1065
|
-
this.addToInputHistory(command);
|
|
1066
1102
|
return;
|
|
1067
1103
|
}
|
|
1068
1104
|
|
|
@@ -1071,9 +1107,6 @@ export class Agent {
|
|
|
1071
1107
|
}
|
|
1072
1108
|
|
|
1073
1109
|
// Handle normal AI message
|
|
1074
|
-
// Add user message to history
|
|
1075
|
-
this.addToInputHistory(content);
|
|
1076
|
-
|
|
1077
1110
|
// Add user message first, will automatically sync to UI
|
|
1078
1111
|
this.messageManager.addUserMessage({
|
|
1079
1112
|
content,
|
|
@@ -1130,67 +1163,6 @@ export class Agent {
|
|
|
1130
1163
|
}
|
|
1131
1164
|
}
|
|
1132
1165
|
|
|
1133
|
-
/** Save memory to project or user memory file */
|
|
1134
|
-
public async saveMemory(
|
|
1135
|
-
message: string,
|
|
1136
|
-
type: "project" | "user",
|
|
1137
|
-
): Promise<void> {
|
|
1138
|
-
try {
|
|
1139
|
-
// Ensure the message starts with # for memory functions
|
|
1140
|
-
const formattedMessage = message.startsWith("#")
|
|
1141
|
-
? message
|
|
1142
|
-
: `#${message}`;
|
|
1143
|
-
|
|
1144
|
-
if (type === "project") {
|
|
1145
|
-
await memory.addMemory(formattedMessage, this.workdir);
|
|
1146
|
-
// Update internal state after successful save
|
|
1147
|
-
this._projectMemoryContent = await memory.readMemoryFile(this.workdir);
|
|
1148
|
-
} else {
|
|
1149
|
-
await memory.addUserMemory(formattedMessage);
|
|
1150
|
-
// Update internal state after successful save
|
|
1151
|
-
this._userMemoryContent = await memory.getUserMemoryContent();
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
// Add successful MemoryBlock to the last assistant message
|
|
1155
|
-
const memoryText = message.substring(1).trim();
|
|
1156
|
-
const typeLabel = type === "project" ? "Project Memory" : "User Memory";
|
|
1157
|
-
const storagePath = "AGENTS.md";
|
|
1158
|
-
|
|
1159
|
-
const messages = this.messageManager.getMessages();
|
|
1160
|
-
const lastMessage = messages[messages.length - 1];
|
|
1161
|
-
if (lastMessage && lastMessage.role === "assistant") {
|
|
1162
|
-
lastMessage.blocks.push({
|
|
1163
|
-
type: "memory",
|
|
1164
|
-
content: `${typeLabel}: ${memoryText}`,
|
|
1165
|
-
isSuccess: true,
|
|
1166
|
-
memoryType: type,
|
|
1167
|
-
storagePath,
|
|
1168
|
-
});
|
|
1169
|
-
this.messageManager.setMessages(messages);
|
|
1170
|
-
}
|
|
1171
|
-
} catch (error) {
|
|
1172
|
-
// Add failed MemoryBlock to the last assistant message
|
|
1173
|
-
const memoryText = message.substring(1).trim();
|
|
1174
|
-
const typeLabel = type === "project" ? "Project Memory" : "User Memory";
|
|
1175
|
-
const storagePath = "AGENTS.md";
|
|
1176
|
-
const errorMessage =
|
|
1177
|
-
error instanceof Error ? error.message : String(error);
|
|
1178
|
-
|
|
1179
|
-
const messages = this.messageManager.getMessages();
|
|
1180
|
-
const lastMessage = messages[messages.length - 1];
|
|
1181
|
-
if (lastMessage && lastMessage.role === "assistant") {
|
|
1182
|
-
lastMessage.blocks.push({
|
|
1183
|
-
type: "memory",
|
|
1184
|
-
content: `${typeLabel}: ${memoryText} - Error: ${errorMessage}`,
|
|
1185
|
-
isSuccess: false,
|
|
1186
|
-
memoryType: type,
|
|
1187
|
-
storagePath,
|
|
1188
|
-
});
|
|
1189
|
-
this.messageManager.setMessages(messages);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
1166
|
// ========== MCP Management Methods ==========
|
|
1195
1167
|
|
|
1196
1168
|
/** Get all MCP server status */
|
|
@@ -1270,6 +1242,16 @@ export class Agent {
|
|
|
1270
1242
|
await this.messageManager.truncateHistory(index, this.reversionManager);
|
|
1271
1243
|
}
|
|
1272
1244
|
|
|
1245
|
+
/**
|
|
1246
|
+
* Get the full message thread including parent sessions
|
|
1247
|
+
*/
|
|
1248
|
+
public async getFullMessageThread(): Promise<{
|
|
1249
|
+
messages: Message[];
|
|
1250
|
+
sessionIds: string[];
|
|
1251
|
+
}> {
|
|
1252
|
+
return this.messageManager.getFullMessageThread();
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1273
1255
|
/**
|
|
1274
1256
|
* Get the current plan file path (for testing and UI)
|
|
1275
1257
|
*/
|
|
@@ -1338,7 +1320,7 @@ export class Agent {
|
|
|
1338
1320
|
private handlePlanModeTransition(mode: PermissionMode): void {
|
|
1339
1321
|
if (mode === "plan") {
|
|
1340
1322
|
this.planManager
|
|
1341
|
-
.getOrGeneratePlanFilePath()
|
|
1323
|
+
.getOrGeneratePlanFilePath(this.messageManager.getRootSessionId())
|
|
1342
1324
|
.then(({ path }) => {
|
|
1343
1325
|
this.logger?.debug("Plan file path generated", { path });
|
|
1344
1326
|
this.permissionManager.setPlanFilePath(path);
|
|
@@ -1350,4 +1332,11 @@ export class Agent {
|
|
|
1350
1332
|
this.permissionManager.setPlanFilePath(undefined);
|
|
1351
1333
|
}
|
|
1352
1334
|
}
|
|
1335
|
+
|
|
1336
|
+
/**
|
|
1337
|
+
* Get the current task list ID
|
|
1338
|
+
*/
|
|
1339
|
+
public get taskListId(): string {
|
|
1340
|
+
return this.taskManager.getTaskListId();
|
|
1341
|
+
}
|
|
1353
1342
|
}
|