@codebolt/agent 6.0.0 → 6.1.2
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/README.md +118 -153
- package/dist/index.d.ts +2 -0
- package/dist/index.js +41 -0
- package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.js +2 -4
- package/dist/processor-pieces/messageModifiers/contextAssemblyModifier.d.ts +81 -0
- package/dist/processor-pieces/messageModifiers/contextAssemblyModifier.js +316 -0
- package/dist/processor-pieces/messageModifiers/coreSystemPromptModifier.js +2 -19
- package/dist/processor-pieces/messageModifiers/directoryContextModifier.js +2 -6
- package/dist/processor-pieces/messageModifiers/environmentContextModifier.js +2 -7
- package/dist/processor-pieces/messageModifiers/ideContextModifier.js +2 -21
- package/dist/processor-pieces/messageModifiers/index.d.ts +3 -0
- package/dist/processor-pieces/messageModifiers/index.js +7 -1
- package/dist/processor-pieces/messageModifiers/toolInjectionModifier.js +2 -1
- package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.d.ts +34 -5
- package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.js +374 -89
- package/dist/processor-pieces/preInferenceProcessors/chatCompressionModifier.d.ts +3 -0
- package/dist/processor-pieces/preInferenceProcessors/chatCompressionModifier.js +50 -27
- package/dist/unified/agent/agent.d.ts +10 -0
- package/dist/unified/agent/agent.js +198 -10
- package/dist/unified/agent/codeboltAgent.d.ts +19 -100
- package/dist/unified/agent/codeboltAgent.js +209 -109
- package/dist/unified/base/agentStep.js +17 -17
- package/dist/unified/base/initialPromptGenerator.js +13 -31
- package/dist/unified/base/promptContext.d.ts +13 -0
- package/dist/unified/base/promptContext.js +213 -0
- package/dist/unified/base/responseExecutor.d.ts +7 -19
- package/dist/unified/base/responseExecutor.js +280 -259
- package/dist/unified/index.d.ts +9 -0
- package/dist/unified/index.js +20 -13
- package/dist/unified/services/CompressionCoordinator.d.ts +67 -0
- package/dist/unified/services/CompressionCoordinator.js +214 -0
- package/dist/unified/services/compaction/autoCompact.d.ts +52 -0
- package/dist/unified/services/compaction/autoCompact.js +294 -0
- package/dist/unified/services/compaction/compactionOrchestrator.d.ts +78 -0
- package/dist/unified/services/compaction/compactionOrchestrator.js +230 -0
- package/dist/unified/services/compaction/contextCollapse.d.ts +63 -0
- package/dist/unified/services/compaction/contextCollapse.js +291 -0
- package/dist/unified/services/compaction/microCompact.d.ts +34 -0
- package/dist/unified/services/compaction/microCompact.js +195 -0
- package/dist/unified/services/compaction/postCompactCleanup.d.ts +15 -0
- package/dist/unified/services/compaction/postCompactCleanup.js +37 -0
- package/dist/unified/services/compaction/reactiveCompact.d.ts +65 -0
- package/dist/unified/services/compaction/reactiveCompact.js +301 -0
- package/dist/unified/services/compaction/snipCompact.d.ts +31 -0
- package/dist/unified/services/compaction/snipCompact.js +124 -0
- package/dist/unified/services/compaction/types.d.ts +66 -0
- package/dist/unified/services/compaction/types.js +39 -0
- package/package.json +25 -29
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ResponseExecutor = void 0;
|
|
7
7
|
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
8
|
+
const promptContext_1 = require("./promptContext");
|
|
8
9
|
class ResponseExecutor {
|
|
9
10
|
constructor(options) {
|
|
10
11
|
this.preToolCallProcessors = [];
|
|
@@ -13,340 +14,301 @@ class ResponseExecutor {
|
|
|
13
14
|
this.finalMessage = undefined;
|
|
14
15
|
this.preToolCallProcessors = options.preToolCallProcessors;
|
|
15
16
|
this.postToolCallProcessors = options.postToolCallProcessors;
|
|
16
|
-
|
|
17
|
-
this.loopDetectionService = options.loopDetectionService;
|
|
18
|
-
}
|
|
17
|
+
this.loopDetectionService = options.loopDetectionService;
|
|
19
18
|
}
|
|
20
19
|
async executeResponse(input) {
|
|
21
|
-
var _a, _b;
|
|
22
|
-
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
this.completed = false;
|
|
22
|
+
this.finalMessage = undefined;
|
|
23
|
+
let nextMessage = (0, promptContext_1.reconcileRuntimePromptContext)(input.nextMessage);
|
|
23
24
|
for (const preToolCallProcessor of this.preToolCallProcessors) {
|
|
24
25
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const { nextPrompt, shouldExit } = await preToolCallProcessor.modify({
|
|
27
|
+
llmMessageSent: input.actualMessageSentToLLM,
|
|
28
|
+
rawLLMResponseMessage: input.rawLLMOutput,
|
|
29
|
+
nextPrompt: nextMessage,
|
|
30
|
+
});
|
|
31
|
+
nextMessage = (0, promptContext_1.reconcileRuntimePromptContext)(nextPrompt);
|
|
28
32
|
if (shouldExit) {
|
|
29
33
|
this.completed = true;
|
|
30
|
-
|
|
31
|
-
nextPrompt,
|
|
32
|
-
completed: this.completed
|
|
33
|
-
});
|
|
34
|
+
break;
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
console.error(`[
|
|
38
|
-
// Continue with other modifiers
|
|
38
|
+
console.error(`[ResponseExecutor] Error in pre tool call processor:`, error);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
const toolExecution = await this.executeTools(input.rawLLMOutput);
|
|
42
|
+
this.completed = this.completed || toolExecution.completed;
|
|
43
|
+
this.finalMessage = (_a = toolExecution.finalMessage) !== null && _a !== void 0 ? _a : this.finalMessage;
|
|
44
|
+
this.injectDiscoveredTools(input.rawLLMOutput, toolExecution.toolResults, nextMessage);
|
|
45
|
+
if (toolExecution.toolResults.length > 0 || toolExecution.followUpMessages.length > 0) {
|
|
46
|
+
nextMessage = (0, promptContext_1.appendTranscriptMessages)(nextMessage, [
|
|
47
|
+
...toolExecution.toolResults.map((toolResult) => ({
|
|
47
48
|
role: toolResult.role,
|
|
48
|
-
content: typeof toolResult.content === 'string'
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// this.completed=true;
|
|
56
|
-
nextMessage.message.messages.push({
|
|
57
|
-
role: "user",
|
|
58
|
-
content: [{
|
|
59
|
-
type: "text",
|
|
60
|
-
text: "If you have completed the user's task, use the attempt_completion tool. if you have not completed the task and do not need additional information, then proceed with the next step of the task. (This is an automated message, so do not respond to it conversationally.)"
|
|
61
|
-
}]
|
|
62
|
-
});
|
|
49
|
+
content: typeof toolResult.content === 'string'
|
|
50
|
+
? toolResult.content
|
|
51
|
+
: JSON.stringify(toolResult.content),
|
|
52
|
+
tool_call_id: toolResult.tool_call_id,
|
|
53
|
+
})),
|
|
54
|
+
...toolExecution.followUpMessages,
|
|
55
|
+
]);
|
|
63
56
|
}
|
|
57
|
+
const transcriptLengthBeforePostToolProcessors = (0, promptContext_1.getTranscriptMessages)(nextMessage).length;
|
|
64
58
|
for (const postToolCallProcessor of this.postToolCallProcessors) {
|
|
65
59
|
try {
|
|
66
|
-
|
|
67
|
-
let { nextPrompt, shouldExit } = await postToolCallProcessor.modify({
|
|
60
|
+
const { nextPrompt, shouldExit } = await postToolCallProcessor.modify({
|
|
68
61
|
llmMessageSent: input.actualMessageSentToLLM,
|
|
69
62
|
rawLLMResponseMessage: input.rawLLMOutput,
|
|
70
63
|
nextPrompt: nextMessage,
|
|
71
|
-
toolResults: toolResults,
|
|
72
|
-
tokenLimit: (
|
|
73
|
-
maxOutputTokens: (
|
|
64
|
+
toolResults: toolExecution.toolResults,
|
|
65
|
+
tokenLimit: (_b = input.rawLLMOutput) === null || _b === void 0 ? void 0 : _b.tokenLimit,
|
|
66
|
+
maxOutputTokens: (_c = input.rawLLMOutput) === null || _c === void 0 ? void 0 : _c.maxOutputTokens
|
|
74
67
|
});
|
|
75
|
-
|
|
76
|
-
nextMessage = nextPrompt;
|
|
68
|
+
nextMessage = (0, promptContext_1.reconcileRuntimePromptContext)(nextPrompt);
|
|
77
69
|
if (shouldExit) {
|
|
78
70
|
this.completed = true;
|
|
79
|
-
|
|
80
|
-
nextPrompt,
|
|
81
|
-
completed: this.completed
|
|
82
|
-
});
|
|
71
|
+
break;
|
|
83
72
|
}
|
|
84
73
|
}
|
|
85
74
|
catch (error) {
|
|
86
75
|
console.error(`[ResponseExecutor] Error in post tool call processor:`, error);
|
|
87
|
-
// Continue with other processors
|
|
88
76
|
}
|
|
89
77
|
}
|
|
78
|
+
const transcriptLengthAfterPostToolProcessors = (0, promptContext_1.getTranscriptMessages)(nextMessage).length;
|
|
79
|
+
if (!toolExecution.hadToolCalls &&
|
|
80
|
+
transcriptLengthAfterPostToolProcessors > transcriptLengthBeforePostToolProcessors) {
|
|
81
|
+
this.completed = false;
|
|
82
|
+
this.finalMessage = undefined;
|
|
83
|
+
}
|
|
90
84
|
const output = {
|
|
91
85
|
completed: this.completed,
|
|
92
|
-
nextMessage
|
|
93
|
-
toolResults: toolResults
|
|
86
|
+
nextMessage,
|
|
87
|
+
toolResults: toolExecution.toolResults,
|
|
94
88
|
};
|
|
95
89
|
if (this.finalMessage !== undefined) {
|
|
96
90
|
output.finalMessage = this.finalMessage;
|
|
97
91
|
}
|
|
98
92
|
return output;
|
|
99
93
|
}
|
|
100
|
-
|
|
101
|
-
* Extract tool details from tool call
|
|
102
|
-
*/
|
|
103
|
-
getToolDetail(tool) {
|
|
94
|
+
parseToolCall(tool) {
|
|
104
95
|
let toolInput = {};
|
|
105
96
|
if (tool.function.arguments) {
|
|
106
97
|
try {
|
|
107
|
-
|
|
98
|
+
const parsedArguments = JSON.parse(tool.function.arguments);
|
|
99
|
+
if (parsedArguments && typeof parsedArguments === 'object' && !Array.isArray(parsedArguments)) {
|
|
100
|
+
toolInput = parsedArguments;
|
|
101
|
+
}
|
|
108
102
|
}
|
|
109
103
|
catch (parseError) {
|
|
110
104
|
throw new Error(`Failed to parse tool arguments: ${parseError}`);
|
|
111
105
|
}
|
|
112
106
|
}
|
|
113
107
|
return {
|
|
108
|
+
tool,
|
|
109
|
+
toolInput,
|
|
114
110
|
toolName: tool.function.name,
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
toolUseId: tool.id,
|
|
112
|
+
waitForPrevious: toolInput['waitForPreviousTools'] === true,
|
|
117
113
|
};
|
|
118
114
|
}
|
|
119
|
-
|
|
120
|
-
var _a, _b;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
for (const contentBlock of llmResponse.choices || []) {
|
|
125
|
-
if (contentBlock.message) {
|
|
126
|
-
if (contentBlock.message.content != null) {
|
|
127
|
-
lastMessageContent = contentBlock.message.content;
|
|
128
|
-
// await codebolt.chat.sendMessage(contentBlock.message.content, {});
|
|
129
|
-
}
|
|
130
|
-
if (contentBlock.message["reasoning_content"] != null && (!lastMessageContent || lastMessageContent.trim() === '')) {
|
|
131
|
-
lastMessageContent = contentBlock.message["reasoning_content"];
|
|
132
|
-
// await codebolt.chat.sendMessage((contentBlock.message as any)["reasoning_content"], {});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
115
|
+
extractLastMessageContent(llmResponse) {
|
|
116
|
+
var _a, _b, _c;
|
|
117
|
+
for (const choice of (_a = llmResponse.choices) !== null && _a !== void 0 ? _a : []) {
|
|
118
|
+
if ((_b = choice.message) === null || _b === void 0 ? void 0 : _b.content) {
|
|
119
|
+
return choice.message.content;
|
|
135
120
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
toolUseId,
|
|
156
|
-
waitForPrevious: (toolInput === null || toolInput === void 0 ? void 0 : toolInput.waitForPreviousTools) === true
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// Check for loops before execution
|
|
161
|
-
if (this.loopDetectionService) {
|
|
162
|
-
const toolCallsToCheck = toolsToExecute.map(t => ({ name: t.toolName, args: t.toolInput }));
|
|
163
|
-
for (const toolCall of toolCallsToCheck) {
|
|
164
|
-
const loopDetected = this.loopDetectionService.checkToolCallLoop(toolCall.name, toolCall.args);
|
|
165
|
-
if (loopDetected) {
|
|
166
|
-
this.completed = true;
|
|
167
|
-
this.finalMessage = `Loop Detected: The agent is stuck in a loop of identical tool calls (${toolCall.name}). Execution stopped to prevent infinite recurrence.`;
|
|
168
|
-
return [{
|
|
169
|
-
role: 'tool',
|
|
170
|
-
tool_call_id: 'system-loop-detection', // Virtual ID
|
|
171
|
-
content: JSON.stringify({ error: this.finalMessage })
|
|
172
|
-
}];
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
// Second pass: Execute tools sequentially (one by one)
|
|
177
|
-
for (const item of toolsToExecute) {
|
|
178
|
-
try {
|
|
179
|
-
if (!userRejectedToolUse) {
|
|
180
|
-
let [serverName] = item.toolName.replace('--', ':').split(':');
|
|
181
|
-
// codebolt.chat.sendMessage(`tool call ${serverName} ${item.toolName} ${item.toolInput}`, {});
|
|
182
|
-
if (serverName == 'subagent') {
|
|
183
|
-
await codeboltjs_1.default.agent.startAgent(item.toolName.replace("subagent--", ''), item.toolInput.task);
|
|
184
|
-
const [didUserReject, result] = [false, "tool result is successful"];
|
|
185
|
-
let toolResult = this.parseToolResult(item.toolUseId, result);
|
|
186
|
-
// Handle side effects (fallback messages)
|
|
187
|
-
if (toolResult.userMessage) {
|
|
188
|
-
fallBackMessages.push({
|
|
189
|
-
role: "user",
|
|
190
|
-
content: toolResult.userMessage.toString()
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
if (didUserReject) {
|
|
194
|
-
userRejectedToolUse = true;
|
|
195
|
-
}
|
|
196
|
-
toolResults.push({
|
|
197
|
-
role: "tool",
|
|
198
|
-
tool_call_id: toolResult.tool_call_id,
|
|
199
|
-
content: toolResult.content,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
else if (item.toolName == "codebolt--thread_management") {
|
|
203
|
-
const response = await codeboltjs_1.default.thread.createThreadInBackground({
|
|
204
|
-
title: item.toolInput.title || item.toolInput.task || 'Background Thread',
|
|
205
|
-
description: item.toolInput.description || item.toolInput.task || '',
|
|
206
|
-
userMessage: item.toolInput.task || item.toolInput.userMessage || '',
|
|
207
|
-
selectedAgent: item.toolInput.selectedAgent,
|
|
208
|
-
isGrouped: item.toolInput.isGrouped,
|
|
209
|
-
groupId: item.toolInput.groupId,
|
|
210
|
-
});
|
|
211
|
-
toolResults.push({
|
|
212
|
-
role: "tool",
|
|
213
|
-
tool_call_id: item.toolUseId,
|
|
214
|
-
content: JSON.stringify(response),
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
const [didUserReject, result] = await this.executeTool(item.toolName, item.toolInput);
|
|
219
|
-
let toolResult = this.parseToolResult(item.toolUseId, result);
|
|
220
|
-
if (toolResult.userMessage) {
|
|
221
|
-
fallBackMessages.push({
|
|
222
|
-
role: "user",
|
|
223
|
-
content: toolResult.userMessage.toString()
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
if (didUserReject) {
|
|
227
|
-
userRejectedToolUse = true;
|
|
228
|
-
}
|
|
229
|
-
toolResults.push({
|
|
230
|
-
role: "tool",
|
|
231
|
-
tool_call_id: toolResult.tool_call_id,
|
|
232
|
-
content: toolResult.content,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
let toolResult = this.parseToolResult(item.toolUseId, "Skipping tool execution due to previous tool user rejection.");
|
|
238
|
-
if (toolResult.userMessage) {
|
|
239
|
-
fallBackMessages.push({
|
|
240
|
-
role: "user",
|
|
241
|
-
content: toolResult.userMessage.toString()
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
toolResults.push({
|
|
245
|
-
role: "tool",
|
|
246
|
-
tool_call_id: toolResult.tool_call_id,
|
|
247
|
-
content: toolResult.content,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
toolResults.push({
|
|
253
|
-
role: "tool",
|
|
254
|
-
tool_call_id: item.tool.id,
|
|
255
|
-
content: String(error),
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
this.completed = true;
|
|
262
|
-
// Set final message from agent's last text response when completing without tool calls
|
|
263
|
-
if (lastMessageContent) {
|
|
264
|
-
this.finalMessage = lastMessageContent;
|
|
265
|
-
}
|
|
121
|
+
const reasoningContent = (_c = choice.message) === null || _c === void 0 ? void 0 : _c.reasoning_content;
|
|
122
|
+
if (reasoningContent) {
|
|
123
|
+
return reasoningContent;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
getToolCalls(llmResponse) {
|
|
129
|
+
var _a, _b, _c, _d;
|
|
130
|
+
const toolCallsById = new Map();
|
|
131
|
+
for (const toolCall of (_a = llmResponse.tool_calls) !== null && _a !== void 0 ? _a : []) {
|
|
132
|
+
if (toolCall === null || toolCall === void 0 ? void 0 : toolCall.id) {
|
|
133
|
+
toolCallsById.set(toolCall.id, toolCall);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const choice of (_b = llmResponse.choices) !== null && _b !== void 0 ? _b : []) {
|
|
137
|
+
for (const toolCall of (_d = (_c = choice.message) === null || _c === void 0 ? void 0 : _c.tool_calls) !== null && _d !== void 0 ? _d : []) {
|
|
138
|
+
if ((toolCall === null || toolCall === void 0 ? void 0 : toolCall.id) && !toolCallsById.has(toolCall.id)) {
|
|
139
|
+
toolCallsById.set(toolCall.id, toolCall);
|
|
266
140
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return Array.from(toolCallsById.values());
|
|
144
|
+
}
|
|
145
|
+
async executeTools(llmResponse) {
|
|
146
|
+
const lastMessageContent = this.extractLastMessageContent(llmResponse);
|
|
147
|
+
const toolCalls = this.getToolCalls(llmResponse);
|
|
148
|
+
if (toolCalls.length === 0) {
|
|
149
|
+
await this.sendFinalMessageToChat(lastMessageContent);
|
|
150
|
+
return {
|
|
151
|
+
toolResults: [],
|
|
152
|
+
followUpMessages: [],
|
|
153
|
+
completed: true,
|
|
154
|
+
finalMessage: lastMessageContent,
|
|
155
|
+
hadToolCalls: false,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
const parsedToolCalls = toolCalls.map((tool) => this.parseToolCall(tool));
|
|
159
|
+
const completionToolCalls = parsedToolCalls.filter((toolCall) => toolCall.toolName.includes('attempt_completion'));
|
|
160
|
+
const executionToolCalls = parsedToolCalls.filter((toolCall) => !toolCall.toolName.includes('attempt_completion'));
|
|
161
|
+
if (this.loopDetectionService) {
|
|
162
|
+
for (const toolCall of executionToolCalls) {
|
|
163
|
+
const loopDetected = this.loopDetectionService.checkToolCallLoop(toolCall.toolName, toolCall.toolInput);
|
|
164
|
+
if (loopDetected) {
|
|
165
|
+
const loopMessage = `Loop detected while calling "${toolCall.toolName}". Execution stopped to prevent infinite recurrence.`;
|
|
166
|
+
return {
|
|
167
|
+
toolResults: [{
|
|
168
|
+
role: 'tool',
|
|
169
|
+
tool_call_id: 'system-loop-detection',
|
|
170
|
+
content: JSON.stringify({ error: loopMessage }),
|
|
171
|
+
}],
|
|
172
|
+
followUpMessages: [],
|
|
173
|
+
completed: true,
|
|
174
|
+
finalMessage: loopMessage,
|
|
175
|
+
hadToolCalls: true,
|
|
176
|
+
};
|
|
290
177
|
}
|
|
291
|
-
return toolResults;
|
|
292
178
|
}
|
|
293
|
-
|
|
179
|
+
}
|
|
180
|
+
const toolResults = [];
|
|
181
|
+
const followUpMessages = [];
|
|
182
|
+
let userRejectedToolUse = false;
|
|
183
|
+
for (const currentToolCall of executionToolCalls) {
|
|
184
|
+
if (userRejectedToolUse) {
|
|
185
|
+
const skippedResult = this.parseToolResult(currentToolCall.toolUseId, 'Skipping tool execution due to previous tool user rejection.');
|
|
186
|
+
toolResults.push(skippedResult);
|
|
187
|
+
continue;
|
|
294
188
|
}
|
|
189
|
+
const executionResult = await this.executeSingleToolCall(currentToolCall);
|
|
190
|
+
toolResults.push(executionResult.toolResult);
|
|
191
|
+
followUpMessages.push(...executionResult.followUpMessages);
|
|
192
|
+
userRejectedToolUse = executionResult.didUserReject;
|
|
193
|
+
}
|
|
194
|
+
if (completionToolCalls.length > 0) {
|
|
195
|
+
const completionToolCall = completionToolCalls.at(-1);
|
|
196
|
+
if (completionToolCall) {
|
|
197
|
+
const completionArguments = completionToolCall.toolInput;
|
|
198
|
+
this.finalMessage = JSON.stringify(completionArguments);
|
|
199
|
+
const [, completionResult] = await this.executeTool(completionToolCall.toolName, completionArguments);
|
|
200
|
+
const parsedCompletionResult = this.parseToolResult(completionToolCall.toolUseId, completionResult === '' ? 'The user is satisfied with the result.' : completionResult);
|
|
201
|
+
toolResults.push(parsedCompletionResult);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
toolResults,
|
|
206
|
+
followUpMessages,
|
|
207
|
+
completed: completionToolCalls.length > 0,
|
|
208
|
+
finalMessage: this.finalMessage,
|
|
209
|
+
hadToolCalls: true,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
async sendFinalMessageToChat(message) {
|
|
213
|
+
if (!message || message.trim().length === 0) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
await Promise.resolve(codeboltjs_1.default.chat.sendMessage(message));
|
|
295
218
|
}
|
|
296
219
|
catch (error) {
|
|
220
|
+
console.error('[ResponseExecutor] Failed to send final chat message:', error);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async executeSingleToolCall(toolCall) {
|
|
224
|
+
try {
|
|
225
|
+
let resultTuple;
|
|
226
|
+
if (toolCall.toolName === 'codebolt--thread_management') {
|
|
227
|
+
resultTuple = [
|
|
228
|
+
false,
|
|
229
|
+
await codeboltjs_1.default.thread.createThreadInBackground({
|
|
230
|
+
title: String(toolCall.toolInput['title'] || toolCall.toolInput['task'] || 'Background Thread'),
|
|
231
|
+
description: String(toolCall.toolInput['description'] || toolCall.toolInput['task'] || ''),
|
|
232
|
+
userMessage: String(toolCall.toolInput['task'] || toolCall.toolInput['userMessage'] || ''),
|
|
233
|
+
selectedAgent: toolCall.toolInput['selectedAgent'],
|
|
234
|
+
isGrouped: Boolean(toolCall.toolInput['isGrouped']),
|
|
235
|
+
...(typeof toolCall.toolInput['groupId'] === 'string'
|
|
236
|
+
? { groupId: toolCall.toolInput['groupId'] }
|
|
237
|
+
: {}),
|
|
238
|
+
})
|
|
239
|
+
];
|
|
240
|
+
}
|
|
241
|
+
else if (toolCall.toolName.startsWith('subagent--')) {
|
|
242
|
+
const task = toolCall.toolInput['task'];
|
|
243
|
+
await codeboltjs_1.default.agent.startAgent(toolCall.toolName.replace('subagent--', ''), typeof task === 'string' ? task : JSON.stringify(task));
|
|
244
|
+
resultTuple = [false, 'tool result is successful'];
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
resultTuple = await this.executeTool(toolCall.toolName, toolCall.toolInput);
|
|
248
|
+
}
|
|
249
|
+
const [didUserReject, result] = resultTuple;
|
|
250
|
+
const parsedResult = this.parseToolResult(toolCall.toolUseId, result);
|
|
251
|
+
return {
|
|
252
|
+
toolResult: parsedResult,
|
|
253
|
+
followUpMessages: parsedResult.userMessage ? [{
|
|
254
|
+
role: 'user',
|
|
255
|
+
content: parsedResult.userMessage.toString(),
|
|
256
|
+
}] : [],
|
|
257
|
+
didUserReject,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
return {
|
|
262
|
+
toolResult: {
|
|
263
|
+
role: 'tool',
|
|
264
|
+
tool_call_id: toolCall.toolUseId,
|
|
265
|
+
content: String(error),
|
|
266
|
+
},
|
|
267
|
+
followUpMessages: [],
|
|
268
|
+
didUserReject: false,
|
|
269
|
+
};
|
|
297
270
|
}
|
|
298
|
-
return [];
|
|
299
271
|
}
|
|
300
|
-
/**
|
|
301
|
-
* Executes a tool with given name and input.
|
|
302
|
-
*
|
|
303
|
-
* @param toolName - The name of the tool to execute
|
|
304
|
-
* @param toolInput - The input parameters for the tool
|
|
305
|
-
* @returns Promise with tuple [userRejected, result]
|
|
306
|
-
*/
|
|
307
272
|
async executeTool(toolName, toolInput) {
|
|
308
273
|
var _a, _b, _c;
|
|
309
|
-
//codebolttools--readfile
|
|
310
|
-
// console.log("Executing tool: ", toolName, toolInput);
|
|
311
274
|
const parts = toolName.split('--');
|
|
312
275
|
const toolboxName = parts.length > 1 ? ((_a = parts[0]) !== null && _a !== void 0 ? _a : '') : 'codebolt';
|
|
313
276
|
const actualToolName = parts.length > 1 ? ((_b = parts[1]) !== null && _b !== void 0 ? _b : '') : ((_c = parts[0]) !== null && _c !== void 0 ? _c : '');
|
|
314
|
-
// console.log("Toolbox name: ", toolboxName, "Actual tool name: ", actualToolName);
|
|
315
277
|
const { data } = await codeboltjs_1.default.mcp.executeTool(toolboxName, actualToolName, toolInput);
|
|
316
|
-
// console.log("Tool result: ", data);
|
|
317
|
-
// Handle the case where data is an array [didUserReject, content]
|
|
318
278
|
if (Array.isArray(data) && data.length >= 2) {
|
|
319
279
|
const [didUserReject, content] = data;
|
|
320
280
|
return [Boolean(didUserReject), content];
|
|
321
281
|
}
|
|
322
|
-
// If data is not in the expected array format, return it as-is
|
|
323
282
|
return [false, data];
|
|
324
283
|
}
|
|
325
|
-
/**
|
|
326
|
-
* Creates a tool result object from the tool execution response.
|
|
327
|
-
*
|
|
328
|
-
* @param tool_call_id - The ID of the tool call
|
|
329
|
-
* @param content - The content returned by the tool
|
|
330
|
-
* @returns ToolResult object
|
|
331
|
-
*/
|
|
332
284
|
parseToolResult(tool_call_id, content) {
|
|
333
|
-
let
|
|
285
|
+
let serializedContent = typeof content === 'string'
|
|
286
|
+
? content
|
|
287
|
+
: JSON.stringify(content);
|
|
288
|
+
let userMessage;
|
|
334
289
|
try {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
290
|
+
const parsedContent = typeof serializedContent === 'string'
|
|
291
|
+
? JSON.parse(serializedContent)
|
|
292
|
+
: serializedContent;
|
|
293
|
+
if (parsedContent &&
|
|
294
|
+
typeof parsedContent === 'object' &&
|
|
295
|
+
'payload' in parsedContent &&
|
|
296
|
+
parsedContent.payload &&
|
|
297
|
+
typeof parsedContent.payload === 'object' &&
|
|
298
|
+
'content' in parsedContent.payload &&
|
|
299
|
+
typeof parsedContent.payload.content === 'string') {
|
|
300
|
+
serializedContent = 'The browser action has been executed. The screenshot has been captured for your analysis. The tool response is provided in the next user message.';
|
|
301
|
+
userMessage = parsedContent.payload.content;
|
|
341
302
|
}
|
|
342
303
|
}
|
|
343
|
-
catch
|
|
304
|
+
catch {
|
|
305
|
+
// Preserve the raw tool result when it is not JSON.
|
|
344
306
|
}
|
|
345
307
|
return {
|
|
346
|
-
role:
|
|
308
|
+
role: 'tool',
|
|
347
309
|
tool_call_id,
|
|
348
|
-
content,
|
|
349
|
-
userMessage
|
|
310
|
+
content: serializedContent,
|
|
311
|
+
userMessage,
|
|
350
312
|
};
|
|
351
313
|
}
|
|
352
314
|
setPreToolCallProcessors(processors) {
|
|
@@ -361,5 +323,64 @@ class ResponseExecutor {
|
|
|
361
323
|
getPostToolCallProcessors() {
|
|
362
324
|
return this.postToolCallProcessors;
|
|
363
325
|
}
|
|
326
|
+
injectDiscoveredTools(llmResponse, toolResults, nextMessage) {
|
|
327
|
+
var _a, _b;
|
|
328
|
+
try {
|
|
329
|
+
const toolCalls = this.getToolCalls(llmResponse);
|
|
330
|
+
if (!toolCalls || !((_a = nextMessage === null || nextMessage === void 0 ? void 0 : nextMessage.message) === null || _a === void 0 ? void 0 : _a.tools))
|
|
331
|
+
return;
|
|
332
|
+
for (const toolCall of toolCalls) {
|
|
333
|
+
if (!toolCall)
|
|
334
|
+
continue;
|
|
335
|
+
const toolName = ((_b = toolCall.function) === null || _b === void 0 ? void 0 : _b.name) || '';
|
|
336
|
+
const isToolSearch = toolName === 'tool_search' ||
|
|
337
|
+
toolName === 'codebolt--tool_search' ||
|
|
338
|
+
toolName.endsWith('--tool_search');
|
|
339
|
+
if (!isToolSearch)
|
|
340
|
+
continue;
|
|
341
|
+
const toolCallId = toolCall.id;
|
|
342
|
+
const toolResult = toolResults.find(r => r.tool_call_id === toolCallId);
|
|
343
|
+
if (!(toolResult === null || toolResult === void 0 ? void 0 : toolResult.content))
|
|
344
|
+
continue;
|
|
345
|
+
const content = typeof toolResult.content === 'string'
|
|
346
|
+
? toolResult.content
|
|
347
|
+
: JSON.stringify(toolResult.content);
|
|
348
|
+
const jsonMatch = content.match(/\[[\s\S]*\]/);
|
|
349
|
+
if (!jsonMatch)
|
|
350
|
+
continue;
|
|
351
|
+
let discoveredSchemas;
|
|
352
|
+
try {
|
|
353
|
+
discoveredSchemas = JSON.parse(jsonMatch[0]);
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (!Array.isArray(discoveredSchemas))
|
|
359
|
+
continue;
|
|
360
|
+
const existingToolNames = new Set(nextMessage.message.tools.map((tool) => { var _a; return (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name; }));
|
|
361
|
+
for (const schema of discoveredSchemas) {
|
|
362
|
+
const schemaFunction = schema['function'];
|
|
363
|
+
const rawName = schemaFunction === null || schemaFunction === void 0 ? void 0 : schemaFunction.name;
|
|
364
|
+
if (!rawName)
|
|
365
|
+
continue;
|
|
366
|
+
const prefixedName = rawName.startsWith('codebolt--') ? rawName : `codebolt--${rawName}`;
|
|
367
|
+
if (existingToolNames.has(prefixedName))
|
|
368
|
+
continue;
|
|
369
|
+
const prefixedSchema = {
|
|
370
|
+
...schema,
|
|
371
|
+
function: {
|
|
372
|
+
...schemaFunction,
|
|
373
|
+
name: prefixedName
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
nextMessage.message.tools.push(prefixedSchema);
|
|
377
|
+
existingToolNames.add(prefixedName);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
console.error('[ResponseExecutor] Error injecting discovered tools:', error);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
364
385
|
}
|
|
365
386
|
exports.ResponseExecutor = ResponseExecutor;
|
package/dist/unified/index.d.ts
CHANGED
|
@@ -15,9 +15,18 @@ export { InitialPromptGenerator } from './base/initialPromptGenerator';
|
|
|
15
15
|
export { AgentStep } from './base/agentStep';
|
|
16
16
|
export { ResponseExecutor } from './base/responseExecutor';
|
|
17
17
|
export { LoopDetectionService, LoopType } from './services/LoopDetectionService';
|
|
18
|
+
export { CompressionCoordinator, type CompressionCoordinatorOptions, type CompressionDecision, type CompressionMetadata, type CompressionRecoveryResult, type CompressionStage, } from './services/CompressionCoordinator';
|
|
18
19
|
export { Agent } from './agent/agent';
|
|
19
20
|
export { CodeboltAgent, createCodeboltAgent, type CodeboltAgentConfig } from './agent/codeboltAgent';
|
|
20
21
|
export { Tool, createTool } from './agent/tools';
|
|
21
22
|
export { Workflow } from './agent/workflow';
|
|
22
23
|
export { type OpenAIMessage, type OpenAITool, type ToolResult, type CodeboltAPI, type AgentExecutionResult, type StreamChunk, type StreamCallback } from './types/libTypes';
|
|
23
24
|
export { type LLMConfig } from './types/libTypes';
|
|
25
|
+
export { CompactionOrchestrator, type CompactionPipelineResult, } from './services/compaction/compactionOrchestrator';
|
|
26
|
+
export { SnipCompact, type SnipCompactOptions } from './services/compaction/snipCompact';
|
|
27
|
+
export { MicroCompact, type MicroCompactOptions } from './services/compaction/microCompact';
|
|
28
|
+
export { ContextCollapse, type ContextCollapseOptions } from './services/compaction/contextCollapse';
|
|
29
|
+
export { AutoCompact, type AutoCompactOptions, type AutoCompactTracking } from './services/compaction/autoCompact';
|
|
30
|
+
export { ReactiveCompact, type ReactiveCompactOptions, type ReactiveRecoveryResult } from './services/compaction/reactiveCompact';
|
|
31
|
+
export { PostCompactCleanup, type PostCompactCleanupOptions } from './services/compaction/postCompactCleanup';
|
|
32
|
+
export { TokenEstimator, type CompactionContext, type CompactionLayer, type CompactionLayerKind, type CompactionBoundary, type CompactionOrchestratorOptions, } from './services/compaction/types';
|