@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.
Files changed (48) hide show
  1. package/README.md +118 -153
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +41 -0
  4. package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.js +2 -4
  5. package/dist/processor-pieces/messageModifiers/contextAssemblyModifier.d.ts +81 -0
  6. package/dist/processor-pieces/messageModifiers/contextAssemblyModifier.js +316 -0
  7. package/dist/processor-pieces/messageModifiers/coreSystemPromptModifier.js +2 -19
  8. package/dist/processor-pieces/messageModifiers/directoryContextModifier.js +2 -6
  9. package/dist/processor-pieces/messageModifiers/environmentContextModifier.js +2 -7
  10. package/dist/processor-pieces/messageModifiers/ideContextModifier.js +2 -21
  11. package/dist/processor-pieces/messageModifiers/index.d.ts +3 -0
  12. package/dist/processor-pieces/messageModifiers/index.js +7 -1
  13. package/dist/processor-pieces/messageModifiers/toolInjectionModifier.js +2 -1
  14. package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.d.ts +34 -5
  15. package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.js +374 -89
  16. package/dist/processor-pieces/preInferenceProcessors/chatCompressionModifier.d.ts +3 -0
  17. package/dist/processor-pieces/preInferenceProcessors/chatCompressionModifier.js +50 -27
  18. package/dist/unified/agent/agent.d.ts +10 -0
  19. package/dist/unified/agent/agent.js +198 -10
  20. package/dist/unified/agent/codeboltAgent.d.ts +19 -100
  21. package/dist/unified/agent/codeboltAgent.js +209 -109
  22. package/dist/unified/base/agentStep.js +17 -17
  23. package/dist/unified/base/initialPromptGenerator.js +13 -31
  24. package/dist/unified/base/promptContext.d.ts +13 -0
  25. package/dist/unified/base/promptContext.js +213 -0
  26. package/dist/unified/base/responseExecutor.d.ts +7 -19
  27. package/dist/unified/base/responseExecutor.js +280 -259
  28. package/dist/unified/index.d.ts +9 -0
  29. package/dist/unified/index.js +20 -13
  30. package/dist/unified/services/CompressionCoordinator.d.ts +67 -0
  31. package/dist/unified/services/CompressionCoordinator.js +214 -0
  32. package/dist/unified/services/compaction/autoCompact.d.ts +52 -0
  33. package/dist/unified/services/compaction/autoCompact.js +294 -0
  34. package/dist/unified/services/compaction/compactionOrchestrator.d.ts +78 -0
  35. package/dist/unified/services/compaction/compactionOrchestrator.js +230 -0
  36. package/dist/unified/services/compaction/contextCollapse.d.ts +63 -0
  37. package/dist/unified/services/compaction/contextCollapse.js +291 -0
  38. package/dist/unified/services/compaction/microCompact.d.ts +34 -0
  39. package/dist/unified/services/compaction/microCompact.js +195 -0
  40. package/dist/unified/services/compaction/postCompactCleanup.d.ts +15 -0
  41. package/dist/unified/services/compaction/postCompactCleanup.js +37 -0
  42. package/dist/unified/services/compaction/reactiveCompact.d.ts +65 -0
  43. package/dist/unified/services/compaction/reactiveCompact.js +301 -0
  44. package/dist/unified/services/compaction/snipCompact.d.ts +31 -0
  45. package/dist/unified/services/compaction/snipCompact.js +124 -0
  46. package/dist/unified/services/compaction/types.d.ts +66 -0
  47. package/dist/unified/services/compaction/types.js +39 -0
  48. 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
- if (options.loopDetectionService) {
17
- this.loopDetectionService = options.loopDetectionService;
18
- }
17
+ this.loopDetectionService = options.loopDetectionService;
19
18
  }
20
19
  async executeResponse(input) {
21
- var _a, _b;
22
- let nextMessage = input.nextMessage;
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
- // TODO: Extract required properties from input for PreToolCallProcessorInput
26
- let { nextPrompt, shouldExit } = await preToolCallProcessor.modify({ llmMessageSent: input.actualMessageSentToLLM, rawLLMResponseMessage: input.rawLLMOutput, nextPrompt: input.nextMessage });
27
- nextMessage = nextPrompt;
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
- Promise.resolve({
31
- nextPrompt,
32
- completed: this.completed
33
- });
34
+ break;
34
35
  }
35
36
  }
36
37
  catch (error) {
37
- console.error(`[InitialPromptGenerator] Error in message modifier:`, error);
38
- // Continue with other modifiers
38
+ console.error(`[ResponseExecutor] Error in pre tool call processor:`, error);
39
39
  }
40
40
  }
41
- //ToolCall here
42
- let toolResults = await this.executeTools(input.rawLLMOutput);
43
- // INSERT_YOUR_CODE
44
- if (nextMessage && toolResults && toolResults.length > 0 && nextMessage && nextMessage.message && Array.isArray(nextMessage.message.messages)) {
45
- for (const toolResult of toolResults) {
46
- const messageObject = {
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' ? toolResult.content : JSON.stringify(toolResult.content),
49
- tool_call_id: toolResult.tool_call_id
50
- };
51
- nextMessage.message.messages.push(messageObject);
52
- }
53
- }
54
- else {
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
- // Pass current nextMessage (with tool results) to the processor
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: (_a = input.rawLLMOutput) === null || _a === void 0 ? void 0 : _a.tokenLimit,
73
- maxOutputTokens: (_b = input.rawLLMOutput) === null || _b === void 0 ? void 0 : _b.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
- // Update nextMessage with the (potentially compressed) result
76
- nextMessage = nextPrompt;
68
+ nextMessage = (0, promptContext_1.reconcileRuntimePromptContext)(nextPrompt);
77
69
  if (shouldExit) {
78
70
  this.completed = true;
79
- Promise.resolve({
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: 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
- toolInput = JSON.parse(tool.function.arguments);
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
- toolInput: toolInput,
116
- toolUseId: tool.id
111
+ toolUseId: tool.id,
112
+ waitForPrevious: toolInput['waitForPreviousTools'] === true,
117
113
  };
118
114
  }
119
- async executeTools(llmResponse) {
120
- var _a, _b;
121
- try {
122
- let fallBackMessages = [];
123
- let lastMessageContent;
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
- try {
137
- let toolResults = [];
138
- let taskCompletedBlock;
139
- let userRejectedToolUse = false;
140
- const contentBlock = (_a = llmResponse.choices) === null || _a === void 0 ? void 0 : _a[0];
141
- if (contentBlock && ((_b = contentBlock.message) === null || _b === void 0 ? void 0 : _b.tool_calls)) {
142
- const toolsToExecute = [];
143
- // First pass: Parse all tools and identify "attempt_completion"
144
- for (const tool of contentBlock.message.tool_calls) {
145
- const { toolInput, toolName, toolUseId } = this.getToolDetail(tool);
146
- if (toolName.includes("attempt_completion")) {
147
- taskCompletedBlock = tool;
148
- this.completed = true;
149
- }
150
- else {
151
- toolsToExecute.push({
152
- tool,
153
- toolInput,
154
- toolName,
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
- if (taskCompletedBlock) {
268
- const completionArgs = JSON.parse(taskCompletedBlock.function.arguments || "{}");
269
- // Capture the final message from attempt_completion
270
- if (completionArgs) {
271
- this.finalMessage = JSON.stringify(completionArgs);
272
- }
273
- let [_, result] = await this.executeTool(taskCompletedBlock.function.name, completionArgs);
274
- if (result === "") {
275
- // this.completed = true;
276
- result = "The user is satisfied with the result.";
277
- }
278
- let toolResult = this.parseToolResult(taskCompletedBlock.id, result);
279
- toolResults.push({
280
- role: "tool",
281
- tool_call_id: toolResult.tool_call_id,
282
- content: toolResult.content,
283
- });
284
- if (toolResult.userMessage) {
285
- fallBackMessages.push({
286
- role: "user",
287
- content: toolResult.userMessage.toString()
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
- catch (error) {
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 userMessage = undefined;
285
+ let serializedContent = typeof content === 'string'
286
+ ? content
287
+ : JSON.stringify(content);
288
+ let userMessage;
334
289
  try {
335
- let parsed = JSON.parse(content);
336
- // console.log("Parsed Content: ", parsed);
337
- if (parsed.payload && parsed.payload.content) {
338
- content = `The browser action has been executed. The screenshot have been captured for your analysis. The tool response is provided in the next user message`;
339
- // this.apiConversationHistory.push()
340
- userMessage = parsed.payload.content;
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 (error) {
304
+ catch {
305
+ // Preserve the raw tool result when it is not JSON.
344
306
  }
345
307
  return {
346
- role: "tool",
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;
@@ -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';