@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.
- package/dist/processor-pieces/messageModifiers/argumentProcessorModifier.js +11 -15
- package/dist/processor-pieces/messageModifiers/atFileProcessorModifier.d.ts +0 -1
- package/dist/processor-pieces/messageModifiers/atFileProcessorModifier.js +16 -33
- package/dist/processor-pieces/messageModifiers/capabilityContextModifier.js +3 -2
- package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.d.ts +7 -0
- package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.js +135 -27
- package/dist/processor-pieces/messageModifiers/chatRecordingModifier.js +3 -3
- package/dist/processor-pieces/messageModifiers/contextAssemblyModifier.js +18 -12
- package/dist/processor-pieces/messageModifiers/directoryContextModifier.d.ts +1 -0
- package/dist/processor-pieces/messageModifiers/directoryContextModifier.js +15 -15
- package/dist/processor-pieces/messageModifiers/environmentContextModifier.d.ts +1 -0
- package/dist/processor-pieces/messageModifiers/environmentContextModifier.js +48 -2
- package/dist/processor-pieces/messageModifiers/ideContextModifier.js +3 -2
- package/dist/processor-pieces/messageModifiers/memoryImportModifier.js +9 -15
- package/dist/processor-pieces/messageModifiers/toolInjectionModifier.js +17 -20
- package/dist/processor-pieces/postInferenceProcessors/loopDetectionModifier.js +8 -19
- package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.d.ts +1 -1
- package/dist/processor-pieces/postToolCallProcessors/conversationCompactorModifier.js +15 -15
- package/dist/processor-pieces/postToolCallProcessors/shellProcessorModifier.js +3 -3
- package/dist/processor-pieces/preInferenceProcessors/chatCompressionModifier.js +2 -2
- package/dist/processor-pieces/utils/messageModifierHelper.js +3 -3
- package/dist/types/libFunctionTypes.d.ts +5 -0
- package/dist/unified/agent/agent.d.ts +10 -0
- package/dist/unified/agent/agent.js +166 -15
- package/dist/unified/agent/tools.d.ts +14 -0
- package/dist/unified/agent/tools.js +82 -51
- package/dist/unified/base/agentStep.d.ts +1 -0
- package/dist/unified/base/agentStep.js +39 -11
- package/dist/unified/base/initialPromptGenerator.d.ts +2 -0
- package/dist/unified/base/initialPromptGenerator.js +42 -19
- package/dist/unified/base/promptContext.d.ts +3 -0
- package/dist/unified/base/promptContext.js +193 -15
- package/dist/unified/base/responseExecutor.d.ts +6 -0
- package/dist/unified/base/responseExecutor.js +222 -58
- package/dist/unified/services/CompressionCoordinator.js +9 -9
- package/dist/unified/services/compaction/autoCompact.js +5 -5
- package/dist/unified/services/compaction/contextCollapse.js +2 -2
- package/dist/unified/services/compaction/reactiveCompact.js +5 -5
- package/dist/unified/types/libTypes.d.ts +6 -0
- package/dist/unified/utils/agentToolLoader.js +29 -24
- 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
|
|
46
|
-
if (
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
|
199
|
+
var _a, _b;
|
|
137
200
|
const toolCallsById = new Map();
|
|
138
|
-
for (const
|
|
139
|
-
if (
|
|
140
|
-
toolCallsById.set(
|
|
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
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
435
|
-
|
|
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.
|
|
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.
|
|
96
|
-
newTokenCount: this.countMessageTokens(message.message.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
137
|
+
input: forceCompressed.input,
|
|
138
138
|
},
|
|
139
139
|
}, {
|
|
140
140
|
status: 'COMPRESSED',
|
|
141
141
|
stage: 'reactive_force_compact',
|
|
142
|
-
originalTokenCount: this.countMessageTokens(message.message.
|
|
143
|
-
newTokenCount: this.countMessageTokens(forceCompressed.
|
|
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
|
|
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.
|
|
270
|
-
summary = response.completion.
|
|
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 (
|
|
273
|
-
summary = response.completion.
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
280
|
-
summary = response.completion.
|
|
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 (
|
|
283
|
-
summary = response.completion.
|
|
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' &&
|
|
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 = (
|
|
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.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
188
|
-
|
|
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.
|
|
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
|
}
|