@codebolt/agent 6.1.20 → 6.1.21

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 (41) hide show
  1. package/dist/processor-pieces/messageModifiers/argumentProcessorModifier.js +11 -15
  2. package/dist/processor-pieces/messageModifiers/atFileProcessorModifier.d.ts +0 -1
  3. package/dist/processor-pieces/messageModifiers/atFileProcessorModifier.js +16 -33
  4. package/dist/processor-pieces/messageModifiers/capabilityContextModifier.js +3 -2
  5. package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.d.ts +7 -0
  6. package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.js +135 -27
  7. package/dist/processor-pieces/messageModifiers/chatRecordingModifier.js +3 -3
  8. package/dist/processor-pieces/messageModifiers/contextAssemblyModifier.js +18 -12
  9. package/dist/processor-pieces/messageModifiers/directoryContextModifier.d.ts +1 -0
  10. package/dist/processor-pieces/messageModifiers/directoryContextModifier.js +15 -15
  11. package/dist/processor-pieces/messageModifiers/environmentContextModifier.d.ts +1 -0
  12. package/dist/processor-pieces/messageModifiers/environmentContextModifier.js +48 -2
  13. package/dist/processor-pieces/messageModifiers/ideContextModifier.js +3 -2
  14. package/dist/processor-pieces/messageModifiers/memoryImportModifier.js +9 -15
  15. package/dist/processor-pieces/messageModifiers/toolInjectionModifier.js +17 -20
  16. package/dist/processor-pieces/postInferenceProcessors/loopDetectionModifier.js +8 -19
  17. package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.d.ts +1 -1
  18. package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.js +15 -15
  19. package/dist/processor-pieces/postToolCallProcessors/shellProcessorModifier.js +3 -3
  20. package/dist/processor-pieces/preInferenceProcessors/chatCompressionModifier.js +2 -2
  21. package/dist/processor-pieces/utils/messageModifierHelper.js +3 -3
  22. package/dist/types/libFunctionTypes.d.ts +5 -0
  23. package/dist/unified/agent/agent.d.ts +10 -0
  24. package/dist/unified/agent/agent.js +166 -15
  25. package/dist/unified/agent/tools.d.ts +14 -0
  26. package/dist/unified/agent/tools.js +82 -51
  27. package/dist/unified/base/agentStep.d.ts +1 -0
  28. package/dist/unified/base/agentStep.js +39 -11
  29. package/dist/unified/base/initialPromptGenerator.d.ts +2 -0
  30. package/dist/unified/base/initialPromptGenerator.js +42 -19
  31. package/dist/unified/base/promptContext.d.ts +3 -0
  32. package/dist/unified/base/promptContext.js +193 -15
  33. package/dist/unified/base/responseExecutor.d.ts +6 -0
  34. package/dist/unified/base/responseExecutor.js +222 -58
  35. package/dist/unified/services/CompressionCoordinator.js +9 -9
  36. package/dist/unified/services/compaction/autoCompact.js +5 -5
  37. package/dist/unified/services/compaction/contextCollapse.js +2 -2
  38. package/dist/unified/services/compaction/reactiveCompact.js +5 -5
  39. package/dist/unified/types/libTypes.d.ts +6 -0
  40. package/dist/unified/utils/agentToolLoader.js +29 -24
  41. package/package.json +5 -1
@@ -7,6 +7,55 @@ exports.ResponseExecutor = void 0;
7
7
  const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
8
8
  const promptContext_1 = require("./promptContext");
9
9
  const agentToolLoader_1 = require("../utils/agentToolLoader");
10
+ function normalizeDiscoveredToolSchema(schema) {
11
+ const schemaFunction = schema['function'];
12
+ if (typeof (schemaFunction === null || schemaFunction === void 0 ? void 0 : schemaFunction.name) === 'string' && schemaFunction.name.length > 0) {
13
+ return schema;
14
+ }
15
+ if (schema['type'] !== 'function' || typeof schema['name'] !== 'string' || schema['name'].length === 0) {
16
+ return null;
17
+ }
18
+ return {
19
+ ...schema,
20
+ function: {
21
+ name: schema['name'],
22
+ description: schema['description'],
23
+ parameters: schema['parameters'] || { type: 'object', properties: {} },
24
+ },
25
+ };
26
+ }
27
+ function extractDiscoveredToolSchemas(content) {
28
+ let parsedContent = content;
29
+ if (typeof content === 'string') {
30
+ try {
31
+ parsedContent = JSON.parse(content);
32
+ }
33
+ catch {
34
+ const jsonMatch = content.match(/\[[\s\S]*\]/);
35
+ if (!jsonMatch)
36
+ return [];
37
+ try {
38
+ parsedContent = JSON.parse(jsonMatch[0]);
39
+ }
40
+ catch {
41
+ return [];
42
+ }
43
+ }
44
+ }
45
+ const rawSchemas = Array.isArray(parsedContent)
46
+ ? parsedContent
47
+ : (parsedContent &&
48
+ typeof parsedContent === 'object' &&
49
+ !Array.isArray(parsedContent) &&
50
+ parsedContent.type === 'tool_search_output' &&
51
+ Array.isArray(parsedContent.tools))
52
+ ? parsedContent.tools
53
+ : [];
54
+ return rawSchemas
55
+ .filter((schema) => !!schema && typeof schema === 'object' && !Array.isArray(schema))
56
+ .map(normalizeDiscoveredToolSchema)
57
+ .filter((schema) => !!schema);
58
+ }
10
59
  class ResponseExecutor {
11
60
  constructor(options) {
12
61
  this.preToolCallProcessors = [];
@@ -42,24 +91,22 @@ class ResponseExecutor {
42
91
  }
43
92
  const compactionMessagePromise = this.runRequiredCompaction(input.rawLLMOutput);
44
93
  const toolExecution = await this.executeTools(input);
45
- const compactionCompleted = await compactionMessagePromise;
46
- if (compactionCompleted) {
94
+ const compactionOutcome = await compactionMessagePromise;
95
+ if (compactionOutcome.completed) {
47
96
  await Promise.resolve(codeboltjs_1.default.chat.sendMessage('Conversation Compacted'));
48
97
  }
49
98
  this.completed = this.completed || toolExecution.completed;
50
99
  this.finalMessage = (_a = toolExecution.finalMessage) !== null && _a !== void 0 ? _a : this.finalMessage;
51
100
  await this.injectDiscoveredTools(input.rawLLMOutput, toolExecution.toolResults, nextMessage);
52
- if (toolExecution.toolResults.length > 0 || toolExecution.followUpMessages.length > 0) {
53
- nextMessage = (0, promptContext_1.appendTranscriptMessages)(nextMessage, [
54
- ...toolExecution.toolResults.map((toolResult) => ({
55
- role: toolResult.role,
56
- content: typeof toolResult.content === 'string'
57
- ? toolResult.content
58
- : JSON.stringify(toolResult.content),
59
- tool_call_id: toolResult.tool_call_id,
60
- })),
61
- ...toolExecution.followUpMessages,
62
- ]);
101
+ const toolResultMessages = this.buildToolResultMessages(toolExecution);
102
+ if (compactionOutcome.completed) {
103
+ const refreshedMessage = await this.refreshNextMessageFromCompactedContext(nextMessage, input.actualMessageSentToLLM, compactionOutcome, toolResultMessages);
104
+ nextMessage = refreshedMessage || (toolResultMessages.length > 0
105
+ ? (0, promptContext_1.appendTranscriptMessages)(nextMessage, toolResultMessages)
106
+ : nextMessage);
107
+ }
108
+ else if (toolResultMessages.length > 0) {
109
+ nextMessage = (0, promptContext_1.appendTranscriptMessages)(nextMessage, toolResultMessages);
63
110
  }
64
111
  const transcriptLengthBeforePostToolProcessors = (0, promptContext_1.getTranscriptMessages)(nextMessage).length;
65
112
  for (const postToolCallProcessor of this.postToolCallProcessors) {
@@ -88,6 +135,24 @@ class ResponseExecutor {
88
135
  this.completed = false;
89
136
  this.finalMessage = undefined;
90
137
  }
138
+ if (this.completed) {
139
+ const pendingAsyncTasks = await this.getPendingAsyncTasks();
140
+ if (pendingAsyncTasks.length > 0) {
141
+ nextMessage = (0, promptContext_1.appendTranscriptMessages)(nextMessage, [{
142
+ role: 'user',
143
+ content: [
144
+ '<async_tasks_require_decision>',
145
+ 'You attempted to complete while scoped async tasks owned by this run are still unresolved.',
146
+ 'Before completing, use async_task_control on each task with action "wait", "stop", or "detach".',
147
+ 'If a wait times out and the task is intentionally long-running, either stop it or detach it explicitly. background_detached tasks do not block completion and survive user force-stop.',
148
+ JSON.stringify(pendingAsyncTasks, null, 2),
149
+ '</async_tasks_require_decision>',
150
+ ].join('\n'),
151
+ }]);
152
+ this.completed = false;
153
+ this.finalMessage = undefined;
154
+ }
155
+ }
91
156
  const output = {
92
157
  completed: this.completed,
93
158
  nextMessage,
@@ -99,10 +164,12 @@ class ResponseExecutor {
99
164
  return output;
100
165
  }
101
166
  parseToolCall(tool) {
167
+ var _a, _b, _c;
102
168
  let toolInput = {};
103
- if (tool.function.arguments) {
169
+ const rawArguments = (_a = tool.arguments) !== null && _a !== void 0 ? _a : (_b = tool.function) === null || _b === void 0 ? void 0 : _b.arguments;
170
+ if (rawArguments) {
104
171
  try {
105
- const parsedArguments = JSON.parse(tool.function.arguments);
172
+ const parsedArguments = typeof rawArguments === 'string' ? JSON.parse(rawArguments) : rawArguments;
106
173
  if (parsedArguments && typeof parsedArguments === 'object' && !Array.isArray(parsedArguments)) {
107
174
  toolInput = parsedArguments;
108
175
  }
@@ -114,37 +181,32 @@ class ResponseExecutor {
114
181
  return {
115
182
  tool,
116
183
  toolInput,
117
- toolName: tool.function.name,
118
- toolUseId: tool.id,
184
+ toolName: tool.name || ((_c = tool.function) === null || _c === void 0 ? void 0 : _c.name) || '',
185
+ toolUseId: tool.call_id || tool.id || '',
119
186
  waitForPrevious: toolInput['waitForPreviousTools'] === true,
120
187
  };
121
188
  }
122
189
  extractLastMessageContent(llmResponse) {
123
- var _a, _b, _c;
124
- for (const choice of (_a = llmResponse.choices) !== null && _a !== void 0 ? _a : []) {
125
- if ((_b = choice.message) === null || _b === void 0 ? void 0 : _b.content) {
126
- return choice.message.content;
127
- }
128
- const reasoningContent = (_c = choice.message) === null || _c === void 0 ? void 0 : _c.reasoning_content;
129
- if (reasoningContent) {
130
- return reasoningContent;
131
- }
190
+ if (llmResponse.output_text) {
191
+ return llmResponse.output_text;
192
+ }
193
+ if (llmResponse.content) {
194
+ return llmResponse.content;
132
195
  }
133
196
  return undefined;
134
197
  }
135
198
  getToolCalls(llmResponse) {
136
- var _a, _b, _c, _d;
199
+ var _a, _b;
137
200
  const toolCallsById = new Map();
138
- for (const toolCall of (_a = llmResponse.tool_calls) !== null && _a !== void 0 ? _a : []) {
139
- if (toolCall === null || toolCall === void 0 ? void 0 : toolCall.id) {
140
- toolCallsById.set(toolCall.id, toolCall);
201
+ for (const item of (_a = llmResponse.items) !== null && _a !== void 0 ? _a : []) {
202
+ if ((item === null || item === void 0 ? void 0 : item.type) === 'function_call' && item.call_id) {
203
+ toolCallsById.set(item.call_id, item);
141
204
  }
142
205
  }
143
- for (const choice of (_b = llmResponse.choices) !== null && _b !== void 0 ? _b : []) {
144
- for (const toolCall of (_d = (_c = choice.message) === null || _c === void 0 ? void 0 : _c.tool_calls) !== null && _d !== void 0 ? _d : []) {
145
- if ((toolCall === null || toolCall === void 0 ? void 0 : toolCall.id) && !toolCallsById.has(toolCall.id)) {
146
- toolCallsById.set(toolCall.id, toolCall);
147
- }
206
+ for (const toolCall of (_b = llmResponse.tool_calls) !== null && _b !== void 0 ? _b : []) {
207
+ const id = (toolCall === null || toolCall === void 0 ? void 0 : toolCall.call_id) || (toolCall === null || toolCall === void 0 ? void 0 : toolCall.id);
208
+ if (id) {
209
+ toolCallsById.set(id, toolCall);
148
210
  }
149
211
  }
150
212
  return Array.from(toolCallsById.values());
@@ -152,29 +214,120 @@ class ResponseExecutor {
152
214
  hasExecutableToolCalls(llmResponse) {
153
215
  return this.getToolCalls(llmResponse).some((toolCall) => {
154
216
  var _a;
155
- const toolName = ((_a = toolCall.function) === null || _a === void 0 ? void 0 : _a.name) || '';
217
+ const toolName = toolCall.name || ((_a = toolCall.function) === null || _a === void 0 ? void 0 : _a.name) || '';
156
218
  return !toolName.includes('attempt_completion') &&
157
219
  !toolName.includes('context_compaction') &&
158
220
  !toolName.includes('contextCompaction');
159
221
  });
160
222
  }
161
223
  async runRequiredCompaction(llmResponse) {
162
- var _a;
224
+ var _a, _b;
163
225
  const decision = llmResponse.contextCompaction;
164
226
  if (!(decision === null || decision === void 0 ? void 0 : decision.required) || decision.hasToolCalls === false || !this.hasExecutableToolCalls(llmResponse)) {
165
- return false;
227
+ return { completed: false };
166
228
  }
167
229
  try {
168
- await codeboltjs_1.default.contextCompaction.run({
169
- ...(decision.runRequest || {}),
170
- reason: String(((_a = decision.runRequest) === null || _a === void 0 ? void 0 : _a['reason']) || decision.reason || 'llm_response_tool_calls'),
230
+ const runRequest = decision.runRequest || {};
231
+ const response = await codeboltjs_1.default.contextCompaction.run({
232
+ ...runRequest,
233
+ reason: String(runRequest['reason'] || decision.reason || 'llm_response_tool_calls'),
171
234
  });
172
- return true;
235
+ const responseThreadId = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.threadId;
236
+ const requestThreadId = runRequest['threadId'];
237
+ const threadId = typeof responseThreadId === 'string'
238
+ ? responseThreadId
239
+ : typeof requestThreadId === 'string'
240
+ ? requestThreadId
241
+ : undefined;
242
+ return {
243
+ completed: (response === null || response === void 0 ? void 0 : response.success) !== false,
244
+ ...(threadId ? { threadId } : {}),
245
+ };
173
246
  }
174
247
  catch (error) {
175
248
  console.error('[ResponseExecutor] Context compaction failed:', error);
249
+ return { completed: false };
250
+ }
251
+ }
252
+ buildToolResultMessages(toolExecution) {
253
+ return [
254
+ ...toolExecution.toolResults.map((toolResult) => {
255
+ const content = toolResult.content;
256
+ if (content &&
257
+ typeof content === 'object' &&
258
+ !Array.isArray(content) &&
259
+ content.type === 'tool_search_output') {
260
+ return {
261
+ ...content,
262
+ type: 'tool_search_output',
263
+ call_id: content.call_id || toolResult.tool_call_id,
264
+ status: content.status || 'completed',
265
+ };
266
+ }
267
+ return {
268
+ type: 'function_call_output',
269
+ call_id: toolResult.tool_call_id,
270
+ output: typeof content === 'string'
271
+ ? content
272
+ : JSON.stringify(content),
273
+ status: 'completed',
274
+ };
275
+ }),
276
+ ...toolExecution.followUpMessages,
277
+ ];
278
+ }
279
+ async refreshNextMessageFromCompactedContext(nextMessage, actualMessageSentToLLM, compactionOutcome, toolResultMessages) {
280
+ if (!compactionOutcome.threadId) {
281
+ return null;
282
+ }
283
+ try {
284
+ const response = await codeboltjs_1.default.thread.getThreadContextCompacted({
285
+ threadId: compactionOutcome.threadId,
286
+ });
287
+ const compactedMessages = this.extractCompactedContextMessages(response === null || response === void 0 ? void 0 : response.compactedContext);
288
+ if (compactedMessages.length === 0) {
289
+ return null;
290
+ }
291
+ const currentTurnMessages = this.getMessagesAddedAfterInference(actualMessageSentToLLM, nextMessage);
292
+ return (0, promptContext_1.replaceTranscriptMessages)(nextMessage, [
293
+ ...compactedMessages,
294
+ ...currentTurnMessages,
295
+ ...toolResultMessages,
296
+ ]);
297
+ }
298
+ catch (error) {
299
+ console.error('[ResponseExecutor] Failed to refresh compacted context:', error);
300
+ return null;
301
+ }
302
+ }
303
+ extractCompactedContextMessages(compactedContext) {
304
+ const data = typeof compactedContext === 'object' && compactedContext !== null
305
+ ? compactedContext.data
306
+ : undefined;
307
+ const messages = typeof data === 'object' && data !== null
308
+ ? data.input
309
+ : undefined;
310
+ if (!Array.isArray(messages)) {
311
+ return [];
312
+ }
313
+ return messages
314
+ .filter((message) => this.isMessageObject(message))
315
+ .map((message) => ({ ...message }));
316
+ }
317
+ isMessageObject(value) {
318
+ if (!value || typeof value !== 'object') {
319
+ return false;
320
+ }
321
+ const message = value;
322
+ if (typeof message.role !== 'string') {
176
323
  return false;
177
324
  }
325
+ return message.content !== undefined;
326
+ }
327
+ getMessagesAddedAfterInference(actualMessageSentToLLM, nextMessage) {
328
+ const sentMessages = (0, promptContext_1.getTranscriptMessages)(actualMessageSentToLLM);
329
+ const nextMessages = (0, promptContext_1.getTranscriptMessages)(nextMessage);
330
+ return nextMessages.slice(sentMessages.length);
178
331
  }
179
332
  async executeTools(input) {
180
333
  var _a;
@@ -257,6 +410,21 @@ class ResponseExecutor {
257
410
  console.error('[ResponseExecutor] Failed to send final chat message:', error);
258
411
  }
259
412
  }
413
+ async getPendingAsyncTasks() {
414
+ try {
415
+ const response = await Promise.resolve(codeboltjs_1.default.asyncTask.listTasks({
416
+ scope: 'current_run',
417
+ }));
418
+ const tasks = Array.isArray(response === null || response === void 0 ? void 0 : response.tasks) ? response.tasks : [];
419
+ return tasks.filter((task) => task &&
420
+ task.executionMode !== 'background_detached' &&
421
+ !['completed', 'failed', 'stopped'].includes(task.status));
422
+ }
423
+ catch (error) {
424
+ console.error('[ResponseExecutor] Failed to check async tasks before completion:', error);
425
+ return [];
426
+ }
427
+ }
260
428
  extractCompletionMessage(toolInput) {
261
429
  if ('result' in toolInput) {
262
430
  return this.formatCompletionValue(toolInput['result']);
@@ -364,6 +532,7 @@ class ResponseExecutor {
364
532
  return [false, data];
365
533
  }
366
534
  parseToolResult(tool_call_id, content) {
535
+ let parsedStructuredContent = content;
367
536
  let serializedContent = typeof content === 'string'
368
537
  ? content
369
538
  : JSON.stringify(content);
@@ -372,6 +541,7 @@ class ResponseExecutor {
372
541
  const parsedContent = typeof serializedContent === 'string'
373
542
  ? JSON.parse(serializedContent)
374
543
  : serializedContent;
544
+ parsedStructuredContent = parsedContent;
375
545
  if (parsedContent &&
376
546
  typeof parsedContent === 'object' &&
377
547
  'payload' in parsedContent &&
@@ -386,10 +556,16 @@ class ResponseExecutor {
386
556
  catch {
387
557
  // Preserve the raw tool result when it is not JSON.
388
558
  }
559
+ const contentForModel = (parsedStructuredContent &&
560
+ typeof parsedStructuredContent === 'object' &&
561
+ !Array.isArray(parsedStructuredContent) &&
562
+ parsedStructuredContent.type === 'tool_search_output')
563
+ ? parsedStructuredContent
564
+ : serializedContent;
389
565
  return {
390
566
  role: 'tool',
391
567
  tool_call_id,
392
- content: serializedContent,
568
+ content: contentForModel,
393
569
  userMessage,
394
570
  };
395
571
  }
@@ -414,7 +590,7 @@ class ResponseExecutor {
414
590
  for (const toolCall of toolCalls) {
415
591
  if (!toolCall)
416
592
  continue;
417
- const toolName = ((_b = toolCall.function) === null || _b === void 0 ? void 0 : _b.name) || '';
593
+ const toolName = toolCall.name || ((_b = toolCall.function) === null || _b === void 0 ? void 0 : _b.name) || '';
418
594
  const isToolSearch = toolName === 'tool_search' ||
419
595
  toolName === 'codebolt--tool_search' ||
420
596
  toolName.endsWith('--tool_search') ||
@@ -431,20 +607,8 @@ class ResponseExecutor {
431
607
  const toolResult = toolResults.find(r => r.tool_call_id === toolCallId);
432
608
  if (!(toolResult === null || toolResult === void 0 ? void 0 : toolResult.content))
433
609
  continue;
434
- const content = typeof toolResult.content === 'string'
435
- ? toolResult.content
436
- : JSON.stringify(toolResult.content);
437
- const jsonMatch = content.match(/\[[\s\S]*\]/);
438
- if (!jsonMatch)
439
- continue;
440
- let discoveredSchemas;
441
- try {
442
- discoveredSchemas = JSON.parse(jsonMatch[0]);
443
- }
444
- catch {
445
- continue;
446
- }
447
- if (!Array.isArray(discoveredSchemas))
610
+ const discoveredSchemas = extractDiscoveredToolSchemas(toolResult.content);
611
+ if (!discoveredSchemas.length)
448
612
  continue;
449
613
  const existingToolNames = new Set(nextMessage.message.tools.map((tool) => { var _a; return (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name; }));
450
614
  for (const schema of discoveredSchemas) {
@@ -37,7 +37,7 @@ class CompressionCoordinator {
37
37
  this.conversationCompactor = new processor_pieces_1.ConversationCompactorModifier(conversationCompactorOptions);
38
38
  }
39
39
  shouldCompressBeforeInference(message) {
40
- const estimatedTokens = this.countMessageTokens(message.message.messages);
40
+ const estimatedTokens = this.countMessageTokens(message.message.input);
41
41
  const threshold = this.options.proactiveThreshold * this.options.modelTokenLimit;
42
42
  if (!this.options.enabled) {
43
43
  return {
@@ -92,8 +92,8 @@ class CompressionCoordinator {
92
92
  recoveredMessage: this.withCompressionMetadata(message, {
93
93
  status: 'FAILED_REACTIVE_RETRY_LIMIT',
94
94
  stage: 'reactive_force_compact',
95
- originalTokenCount: this.countMessageTokens(message.message.messages),
96
- newTokenCount: this.countMessageTokens(message.message.messages),
95
+ originalTokenCount: this.countMessageTokens(message.message.input),
96
+ newTokenCount: this.countMessageTokens(message.message.input),
97
97
  timestamp: new Date().toISOString(),
98
98
  strategy: this.options.compactStrategy,
99
99
  reactiveRetryCount: this.reactiveRetryCount,
@@ -104,7 +104,7 @@ class CompressionCoordinator {
104
104
  };
105
105
  }
106
106
  this.reactiveRetryCount++;
107
- const proactiveCompression = await this.chatCompression.tryCompressChat(message.message.messages, true);
107
+ const proactiveCompression = await this.chatCompression.tryCompressChat(message.message.input, true);
108
108
  if (proactiveCompression.compressedMessages &&
109
109
  proactiveCompression.compressionStatus === 1) {
110
110
  return {
@@ -112,7 +112,7 @@ class CompressionCoordinator {
112
112
  ...message,
113
113
  message: {
114
114
  ...message.message,
115
- messages: proactiveCompression.compressedMessages,
115
+ input: proactiveCompression.compressedMessages,
116
116
  },
117
117
  }, {
118
118
  status: 'COMPRESSED',
@@ -128,19 +128,19 @@ class CompressionCoordinator {
128
128
  reason: 'Reactive pre-inference compression applied',
129
129
  };
130
130
  }
131
- const forceCompressed = await this.conversationCompactor.forceCompress(message.message.messages);
131
+ const forceCompressed = await this.conversationCompactor.forceCompress(message.message.input);
132
132
  return {
133
133
  recoveredMessage: this.withCompressionMetadata({
134
134
  ...message,
135
135
  message: {
136
136
  ...message.message,
137
- messages: forceCompressed.messages,
137
+ input: forceCompressed.input,
138
138
  },
139
139
  }, {
140
140
  status: 'COMPRESSED',
141
141
  stage: 'reactive_force_compact',
142
- originalTokenCount: this.countMessageTokens(message.message.messages),
143
- newTokenCount: this.countMessageTokens(forceCompressed.messages),
142
+ originalTokenCount: this.countMessageTokens(message.message.input),
143
+ newTokenCount: this.countMessageTokens(forceCompressed.input),
144
144
  timestamp: new Date().toISOString(),
145
145
  strategy: this.options.compactStrategy,
146
146
  ...(forceCompressed.metadata.messagesCompressed !==
@@ -196,7 +196,7 @@ class AutoCompact {
196
196
  return splitIndex;
197
197
  }
198
198
  async generateSummary(messages) {
199
- var _a, _b, _c, _d, _e;
199
+ var _a, _b;
200
200
  try {
201
201
  // eslint-disable-next-line @typescript-eslint/no-require-imports
202
202
  const codebolt = require('@codebolt/codeboltjs');
@@ -266,11 +266,11 @@ CRITICAL RULES:
266
266
  });
267
267
  // Extract summary from response
268
268
  let summary;
269
- if (typeof ((_a = response === null || response === void 0 ? void 0 : response.completion) === null || _a === void 0 ? void 0 : _a.content) === 'string') {
270
- summary = response.completion.content;
269
+ if (typeof ((_a = response === null || response === void 0 ? void 0 : response.completion) === null || _a === void 0 ? void 0 : _a.output_text) === 'string') {
270
+ summary = response.completion.output_text;
271
271
  }
272
- else if ((_e = (_d = (_c = (_b = response === null || response === void 0 ? void 0 : response.completion) === null || _b === void 0 ? void 0 : _b.choices) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message) === null || _e === void 0 ? void 0 : _e.content) {
273
- summary = response.completion.choices[0].message.content;
272
+ else if (typeof ((_b = response === null || response === void 0 ? void 0 : response.completion) === null || _b === void 0 ? void 0 : _b.content) === 'string') {
273
+ summary = response.completion.content;
274
274
  }
275
275
  if (summary && summary.trim().length > 0) {
276
276
  return summary.trim();
@@ -213,7 +213,7 @@ class ContextCollapse {
213
213
  ];
214
214
  }
215
215
  async generateGranularSummary(messages) {
216
- var _a, _b, _c, _d, _e;
216
+ var _a, _b;
217
217
  const estimator = new types_1.TokenEstimator();
218
218
  // For small ranges, create a structural summary without LLM
219
219
  const tokenCount = estimator.estimateForMessages(messages);
@@ -244,7 +244,7 @@ ${historyText}`;
244
244
  { role: 'user', content: prompt },
245
245
  ],
246
246
  });
247
- const summary = ((_a = response === null || response === void 0 ? void 0 : response.completion) === null || _a === void 0 ? void 0 : _a.content) || ((_e = (_d = (_c = (_b = response === null || response === void 0 ? void 0 : response.completion) === null || _b === void 0 ? void 0 : _b.choices) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message) === null || _e === void 0 ? void 0 : _e.content);
247
+ const summary = ((_a = response === null || response === void 0 ? void 0 : response.completion) === null || _a === void 0 ? void 0 : _a.output_text) || ((_b = response === null || response === void 0 ? void 0 : response.completion) === null || _b === void 0 ? void 0 : _b.content);
248
248
  if (summary && typeof summary === 'string' && summary.trim().length > 0) {
249
249
  return summary.trim();
250
250
  }
@@ -235,7 +235,7 @@ class ReactiveCompact {
235
235
  ];
236
236
  }
237
237
  async forceCompact(messages) {
238
- var _a, _b, _c, _d, _e;
238
+ var _a, _b;
239
239
  try {
240
240
  // eslint-disable-next-line @typescript-eslint/no-require-imports
241
241
  const codebolt = require('@codebolt/codeboltjs');
@@ -276,11 +276,11 @@ ${historyText}`;
276
276
  ],
277
277
  });
278
278
  let summary;
279
- if (typeof ((_a = response === null || response === void 0 ? void 0 : response.completion) === null || _a === void 0 ? void 0 : _a.content) === 'string') {
280
- summary = response.completion.content;
279
+ if (typeof ((_a = response === null || response === void 0 ? void 0 : response.completion) === null || _a === void 0 ? void 0 : _a.output_text) === 'string') {
280
+ summary = response.completion.output_text;
281
281
  }
282
- else if ((_e = (_d = (_c = (_b = response === null || response === void 0 ? void 0 : response.completion) === null || _b === void 0 ? void 0 : _b.choices) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message) === null || _e === void 0 ? void 0 : _e.content) {
283
- summary = response.completion.choices[0].message.content;
282
+ else if (typeof ((_b = response === null || response === void 0 ? void 0 : response.completion) === null || _b === void 0 ? void 0 : _b.content) === 'string') {
283
+ summary = response.completion.content;
284
284
  }
285
285
  if (!summary || summary.trim().length === 0) {
286
286
  return null;
@@ -181,6 +181,12 @@ export interface CodeboltAPI {
181
181
  executeTool(toolName: string, params: unknown): Promise<{
182
182
  data: unknown;
183
183
  }>;
184
+ /** List registered project-local and plugin MCP tools */
185
+ getRegisteredTools(): Promise<{
186
+ data?: {
187
+ tools: OpenAITool[];
188
+ };
189
+ }>;
184
190
  /** List available MCP tools */
185
191
  listTools(): Promise<string[]>;
186
192
  /** Get tool schema */
@@ -30,7 +30,16 @@ function isTool(value) {
30
30
  return false;
31
31
  }
32
32
  const candidate = value;
33
- return candidate.type === 'function' && typeof ((_a = candidate.function) === null || _a === void 0 ? void 0 : _a.name) === 'string';
33
+ return candidate.type === 'function' &&
34
+ typeof ((_a = candidate.function) === null || _a === void 0 ? void 0 : _a.name) === 'string' &&
35
+ candidate.function.name.trim().length > 0;
36
+ }
37
+ function getToolName(tool) {
38
+ var _a, _b;
39
+ return ((_b = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.trim()) || '';
40
+ }
41
+ function compareToolsByName(leftTool, rightTool) {
42
+ return getToolName(leftTool).localeCompare(getToolName(rightTool));
34
43
  }
35
44
  function hashString(value) {
36
45
  let hash = 0;
@@ -86,17 +95,16 @@ function normalizeToolResponse(response) {
86
95
  return tools.filter(isTool).map(normalizeToolForModel);
87
96
  }
88
97
  function mergeTools(...toolGroups) {
89
- var _a;
90
98
  const mergedTools = new Map();
91
99
  for (const tools of toolGroups) {
92
100
  for (const tool of tools) {
93
- const toolName = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name;
101
+ const toolName = getToolName(tool);
94
102
  if (toolName && !mergedTools.has(toolName)) {
95
103
  mergedTools.set(toolName, tool);
96
104
  }
97
105
  }
98
106
  }
99
- return Array.from(mergedTools.values());
107
+ return Array.from(mergedTools.values()).sort(compareToolsByName);
100
108
  }
101
109
  function isAgentLocalTool(value) {
102
110
  if (!value || typeof value !== 'object') {
@@ -151,16 +159,23 @@ function assertNoLocalToolSchemaCollisions(localSchemas, externalSchemas) {
151
159
  }
152
160
  async function listProjectLocalTools() {
153
161
  const mcp = codeboltjs_1.default.mcp;
154
- if (typeof mcp.getLocalMCPServers !== 'function') {
155
- return [];
156
- }
157
- try {
158
- return normalizeToolResponse(await mcp.getLocalMCPServers());
162
+ if (typeof mcp.getRegisteredTools === 'function') {
163
+ try {
164
+ return normalizeToolResponse(await mcp.getRegisteredTools());
165
+ }
166
+ catch (error) {
167
+ console.error('[AgentToolLoader] Failed to load registered MCP tools:', error);
168
+ }
159
169
  }
160
- catch (error) {
161
- console.error('[AgentToolLoader] Failed to load project-local tools:', error);
162
- return [];
170
+ if (typeof mcp.getLocalMCPServers === 'function') {
171
+ try {
172
+ return normalizeToolResponse(await mcp.getLocalMCPServers());
173
+ }
174
+ catch (error) {
175
+ console.error('[AgentToolLoader] Failed to load project-local tools:', error);
176
+ }
163
177
  }
178
+ return [];
164
179
  }
165
180
  async function listAgentAvailableTools(mentionedMCPs = []) {
166
181
  let codeboltTools = [];
@@ -184,16 +199,6 @@ async function listAgentAvailableTools(mentionedMCPs = []) {
184
199
  return mergeTools(codeboltTools, localTools, mentionedTools);
185
200
  }
186
201
  function appendUniqueTools(targetTools, toolsToAppend) {
187
- var _a;
188
- const existingToolNames = new Set(targetTools
189
- .map((tool) => { var _a; return (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name; })
190
- .filter((toolName) => typeof toolName === 'string' && toolName.length > 0));
191
- for (const tool of toolsToAppend) {
192
- const toolName = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name;
193
- if (!toolName || existingToolNames.has(toolName)) {
194
- continue;
195
- }
196
- targetTools.push(tool);
197
- existingToolNames.add(toolName);
198
- }
202
+ const mergedTools = mergeTools(targetTools, toolsToAppend);
203
+ targetTools.splice(0, targetTools.length, ...mergedTools);
199
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebolt/agent",
3
- "version": "6.1.20",
3
+ "version": "6.1.21",
4
4
  "description": "CodeBolt Agent utilities for building and managing AI agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -72,6 +72,10 @@
72
72
  "./unified": {
73
73
  "types": "./dist/unified/index.d.ts",
74
74
  "default": "./dist/unified/index.js"
75
+ },
76
+ "./unified/tools": {
77
+ "types": "./dist/unified/agent/tools.d.ts",
78
+ "default": "./dist/unified/agent/tools.js"
75
79
  }
76
80
  }
77
81
  }