@codebolt/agent 6.1.15 → 6.1.17
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/environmentContextModifier.d.ts +3 -1
- package/dist/processor-pieces/messageModifiers/environmentContextModifier.js +58 -5
- package/dist/processor-pieces/messageModifiers/toolInjectionModifier.js +6 -9
- package/dist/types/InternalTypes.d.ts +2 -0
- package/dist/types/commonTypes.d.ts +12 -0
- package/dist/types/libFunctionTypes.d.ts +37 -0
- package/dist/types/socketMessageTypes.d.ts +12 -0
- package/dist/unified/agent/agent.d.ts +0 -1
- package/dist/unified/agent/agent.js +5 -30
- package/dist/unified/agent/codeboltAgent.d.ts +0 -1
- package/dist/unified/agent/codeboltAgent.js +6 -30
- package/dist/unified/base/agentStep.js +13 -1
- package/dist/unified/base/initialPromptGenerator.js +28 -0
- package/dist/unified/base/responseExecutor.d.ts +4 -0
- package/dist/unified/base/responseExecutor.js +79 -6
- package/dist/unified/types/libTypes.d.ts +12 -0
- package/dist/unified/utils/agentToolLoader.d.ts +14 -0
- package/dist/unified/utils/agentToolLoader.js +138 -0
- package/package.json +1 -1
|
@@ -12,8 +12,10 @@ export declare class EnvironmentContextModifier extends BaseMessageModifier {
|
|
|
12
12
|
private readonly options;
|
|
13
13
|
private readonly defaultExcludePatterns;
|
|
14
14
|
constructor(options?: EnvironmentContextOptions);
|
|
15
|
-
modify(
|
|
15
|
+
modify(originalRequest: FlatUserMessage, createdMessage: ProcessedMessage): Promise<ProcessedMessage>;
|
|
16
|
+
private formatMentionedEnvironments;
|
|
16
17
|
private readProjectAgentMd;
|
|
18
|
+
private readAgentInstructionFile;
|
|
17
19
|
private generateFullContext;
|
|
18
20
|
private findRelevantFiles;
|
|
19
21
|
private walkDirectory;
|
|
@@ -67,7 +67,7 @@ class EnvironmentContextModifier extends base_1.BaseMessageModifier {
|
|
|
67
67
|
excludePatterns: [...this.defaultExcludePatterns, ...(options.excludePatterns || [])]
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
async modify(
|
|
70
|
+
async modify(originalRequest, createdMessage) {
|
|
71
71
|
try {
|
|
72
72
|
// Get current date formatted to user's locale
|
|
73
73
|
const today = new Date().toLocaleDateString(undefined, {
|
|
@@ -115,6 +115,10 @@ ${directoryListing}
|
|
|
115
115
|
contextParts.push(baseAgentMdContext);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
const mentionedEnvironmentContext = this.formatMentionedEnvironments(originalRequest.mentionedEnvironments);
|
|
119
|
+
if (mentionedEnvironmentContext) {
|
|
120
|
+
contextParts.push(mentionedEnvironmentContext);
|
|
121
|
+
}
|
|
118
122
|
// Add full file context if enabled (just like gemini-cli does)
|
|
119
123
|
if (this.options.enableFullContext) {
|
|
120
124
|
try {
|
|
@@ -155,18 +159,67 @@ ${directoryListing}
|
|
|
155
159
|
return createdMessage;
|
|
156
160
|
}
|
|
157
161
|
}
|
|
162
|
+
formatMentionedEnvironments(mentionedEnvironments) {
|
|
163
|
+
if (!(mentionedEnvironments === null || mentionedEnvironments === void 0 ? void 0 : mentionedEnvironments.length)) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const environments = mentionedEnvironments
|
|
167
|
+
.map((mention) => {
|
|
168
|
+
const environment = (mention === null || mention === void 0 ? void 0 : mention.environmentData) || mention;
|
|
169
|
+
const provider = (environment === null || environment === void 0 ? void 0 : environment.provider) || (environment === null || environment === void 0 ? void 0 : environment.remoteProvider) || {};
|
|
170
|
+
const config = (environment === null || environment === void 0 ? void 0 : environment.config) || {};
|
|
171
|
+
return {
|
|
172
|
+
id: (mention === null || mention === void 0 ? void 0 : mention.id) || (environment === null || environment === void 0 ? void 0 : environment.id) || (environment === null || environment === void 0 ? void 0 : environment.environmentId) || (environment === null || environment === void 0 ? void 0 : environment.environment_id),
|
|
173
|
+
name: (mention === null || mention === void 0 ? void 0 : mention.title) || (environment === null || environment === void 0 ? void 0 : environment.name) || (environment === null || environment === void 0 ? void 0 : environment.title),
|
|
174
|
+
description: (mention === null || mention === void 0 ? void 0 : mention.description) || (environment === null || environment === void 0 ? void 0 : environment.description),
|
|
175
|
+
state: (environment === null || environment === void 0 ? void 0 : environment.state) || (environment === null || environment === void 0 ? void 0 : environment.status),
|
|
176
|
+
provider: (provider === null || provider === void 0 ? void 0 : provider.name) || (provider === null || provider === void 0 ? void 0 : provider.title) || (provider === null || provider === void 0 ? void 0 : provider.id) || (provider === null || provider === void 0 ? void 0 : provider.providerId),
|
|
177
|
+
executionMode: (config === null || config === void 0 ? void 0 : config.executionMode) || (environment === null || environment === void 0 ? void 0 : environment.executionMode) || (environment === null || environment === void 0 ? void 0 : environment.type),
|
|
178
|
+
environment,
|
|
179
|
+
};
|
|
180
|
+
})
|
|
181
|
+
.filter((environment) => environment.id || environment.name);
|
|
182
|
+
if (!environments.length) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
return [
|
|
186
|
+
'<mentioned-environments>',
|
|
187
|
+
'The user explicitly mentioned these environments with #. Treat them as routing context, not as an automatic active-environment selection.',
|
|
188
|
+
'If the user asks to run, start, delegate, create, or continue work in one of these environments, first inspect this mentioned environment list and choose the matching environment.',
|
|
189
|
+
'Use the thread tool `thread_create_background` to create a background thread in the selected remote environment. Pass the selected environment object in `environment`, set `isRemoteTask: true`, and put the requested work in `userMessage` or `task`.',
|
|
190
|
+
'If `thread_create_background` is not available in the current tool list, first use the tool search capability, such as `tool_search`, to find the thread/background-thread creation tool and then use the matching tool.',
|
|
191
|
+
'If multiple mentioned environments could match and the user did not specify which one, ask a brief clarification before creating the background thread.',
|
|
192
|
+
'Do not call environment management tools or change the active environment just because an environment was mentioned.',
|
|
193
|
+
JSON.stringify(environments, null, 2),
|
|
194
|
+
'</mentioned-environments>',
|
|
195
|
+
].join('\n');
|
|
196
|
+
}
|
|
158
197
|
async readProjectAgentMd(basePath, title = 'Project Agent Instructions') {
|
|
159
|
-
const
|
|
160
|
-
|
|
198
|
+
const instructionFiles = [
|
|
199
|
+
path.join(basePath, '.codebolt', 'agent.md'),
|
|
200
|
+
path.join(basePath, 'agent.md'),
|
|
201
|
+
path.join(basePath, 'AGENTS.md'),
|
|
202
|
+
];
|
|
203
|
+
const sections = [];
|
|
204
|
+
for (const instructionFile of instructionFiles) {
|
|
205
|
+
const section = await this.readAgentInstructionFile(basePath, instructionFile, title);
|
|
206
|
+
if (section) {
|
|
207
|
+
sections.push(section);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return sections.join('\n\n');
|
|
211
|
+
}
|
|
212
|
+
async readAgentInstructionFile(basePath, filePath, title) {
|
|
213
|
+
const relativePath = path.relative(basePath, filePath);
|
|
161
214
|
try {
|
|
162
|
-
const stats = await fs.promises.stat(
|
|
215
|
+
const stats = await fs.promises.stat(filePath);
|
|
163
216
|
if (!stats.isFile()) {
|
|
164
217
|
return '';
|
|
165
218
|
}
|
|
166
219
|
if (stats.size > this.options.maxFileSize) {
|
|
167
220
|
return `--- ${title} (${relativePath}) ---\n[File too large: ${stats.size} bytes]`;
|
|
168
221
|
}
|
|
169
|
-
const content = await fs.promises.readFile(
|
|
222
|
+
const content = await fs.promises.readFile(filePath, 'utf-8');
|
|
170
223
|
if (!content.trim()) {
|
|
171
224
|
return '';
|
|
172
225
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.ToolInjectionModifier = void 0;
|
|
7
4
|
const base_1 = require("../base");
|
|
8
|
-
const
|
|
5
|
+
const agentToolLoader_1 = require("../../unified/utils/agentToolLoader");
|
|
9
6
|
class ToolInjectionModifier extends base_1.BaseMessageModifier {
|
|
10
7
|
constructor(options = {}) {
|
|
11
8
|
super();
|
|
@@ -14,16 +11,16 @@ class ToolInjectionModifier extends base_1.BaseMessageModifier {
|
|
|
14
11
|
includeToolDescriptions: options.includeToolDescriptions !== false,
|
|
15
12
|
maxToolsInMessage: options.maxToolsInMessage || 30,
|
|
16
13
|
giveToolExamples: options.giveToolExamples || false,
|
|
17
|
-
maxToolExamples: options.maxToolExamples || 2
|
|
14
|
+
maxToolExamples: options.maxToolExamples || 2,
|
|
18
15
|
};
|
|
16
|
+
if (options.allowedTools) {
|
|
17
|
+
this.options.allowedTools = options.allowedTools;
|
|
18
|
+
}
|
|
19
19
|
}
|
|
20
20
|
async modify(originalRequest, createdMessage) {
|
|
21
21
|
try {
|
|
22
|
-
const toolsResponse = await codeboltjs_1.default.mcp.listMcpFromServers(['codebolt']);
|
|
23
|
-
let tools = (toolsResponse === null || toolsResponse === void 0 ? void 0 : toolsResponse.data.tools) || (toolsResponse === null || toolsResponse === void 0 ? void 0 : toolsResponse.data) || [];
|
|
24
22
|
let mentionedMCPs = originalRequest.mentionedMCPs || [];
|
|
25
|
-
|
|
26
|
-
tools = [...tools, ...(mentionedTools || [])];
|
|
23
|
+
let tools = await (0, agentToolLoader_1.listAgentAvailableTools)(Array.isArray(mentionedMCPs) ? mentionedMCPs : []);
|
|
27
24
|
// Filter tools if allowedTools is specified
|
|
28
25
|
if (this.options.allowedTools && this.options.allowedTools.length > 0) {
|
|
29
26
|
tools = tools.filter((tool) => this.options.allowedTools.includes(tool.function.name));
|
|
@@ -332,6 +332,12 @@ export interface Agent {
|
|
|
332
332
|
/** Detailed description of the agent and its capabilities */
|
|
333
333
|
longDescription?: string;
|
|
334
334
|
}
|
|
335
|
+
export interface FlagContext {
|
|
336
|
+
user: string[];
|
|
337
|
+
project: string[];
|
|
338
|
+
thread: string[];
|
|
339
|
+
effective: string[];
|
|
340
|
+
}
|
|
335
341
|
/**
|
|
336
342
|
* Interface for initial user message structure
|
|
337
343
|
*/
|
|
@@ -346,6 +352,12 @@ export interface InitialUserMessage {
|
|
|
346
352
|
mentionedMCPs?: MCPTool[];
|
|
347
353
|
/** List of mentioned agents */
|
|
348
354
|
mentionedAgents?: Agent[];
|
|
355
|
+
/** List of mentioned environments */
|
|
356
|
+
mentionedEnvironments?: any[];
|
|
357
|
+
/** Flags mentioned in the initial message context */
|
|
358
|
+
mentionedFlags?: string[];
|
|
359
|
+
/** Flags enabled for the initial message context */
|
|
360
|
+
flags?: FlagContext;
|
|
349
361
|
}
|
|
350
362
|
/**
|
|
351
363
|
* Type definition for an AST node.
|
|
@@ -160,6 +160,12 @@ export interface UserMessageContent {
|
|
|
160
160
|
/** The text content */
|
|
161
161
|
text: string;
|
|
162
162
|
}
|
|
163
|
+
export interface FlagContext {
|
|
164
|
+
user: string[];
|
|
165
|
+
project: string[];
|
|
166
|
+
thread: string[];
|
|
167
|
+
effective: string[];
|
|
168
|
+
}
|
|
163
169
|
/**
|
|
164
170
|
* User message received from the Codebolt platform
|
|
165
171
|
* This is a simplified, user-friendly version of the internal message format
|
|
@@ -193,6 +199,30 @@ export interface UserMessage {
|
|
|
193
199
|
selection?: any;
|
|
194
200
|
remixPrompt?: string;
|
|
195
201
|
mentionedAgents?: [];
|
|
202
|
+
mentionedEnvironments?: any[];
|
|
203
|
+
mentionedFlags?: string[];
|
|
204
|
+
flags?: FlagContext;
|
|
205
|
+
}
|
|
206
|
+
export interface DynamicAgentEvent {
|
|
207
|
+
id: string;
|
|
208
|
+
type: 'agent:dynamic:event';
|
|
209
|
+
timestamp: string;
|
|
210
|
+
source: Record<string, any>;
|
|
211
|
+
payload: {
|
|
212
|
+
name: string;
|
|
213
|
+
data?: Record<string, any>;
|
|
214
|
+
emittedAt: string;
|
|
215
|
+
};
|
|
216
|
+
metadata?: Record<string, any>;
|
|
217
|
+
}
|
|
218
|
+
export interface EmitAgentEventResponse {
|
|
219
|
+
success: boolean;
|
|
220
|
+
type: string;
|
|
221
|
+
requestId?: string;
|
|
222
|
+
data?: {
|
|
223
|
+
event: DynamicAgentEvent;
|
|
224
|
+
};
|
|
225
|
+
error?: string;
|
|
196
226
|
}
|
|
197
227
|
/**
|
|
198
228
|
* Interface for codebolt API functionality
|
|
@@ -224,6 +254,11 @@ export interface CodeboltAPI {
|
|
|
224
254
|
chat: {
|
|
225
255
|
sendMessage: (message: string, metadata: any) => Promise<void>;
|
|
226
256
|
};
|
|
257
|
+
agentEvents: {
|
|
258
|
+
emit: (name: string, data?: Record<string, any>, options?: {
|
|
259
|
+
metadata?: Record<string, any>;
|
|
260
|
+
}) => Promise<EmitAgentEventResponse>;
|
|
261
|
+
};
|
|
227
262
|
}
|
|
228
263
|
export interface ReadFileOptions {
|
|
229
264
|
/** File path to read */
|
|
@@ -565,6 +600,8 @@ export interface ChatSendOptions {
|
|
|
565
600
|
mentionedFiles?: string[];
|
|
566
601
|
/** Mentioned agents */
|
|
567
602
|
mentionedAgents?: string[];
|
|
603
|
+
/** Mentioned environments */
|
|
604
|
+
mentionedEnvironments?: any[];
|
|
568
605
|
}
|
|
569
606
|
export interface ChatHistoryOptions {
|
|
570
607
|
/** Conversation ID */
|
|
@@ -22,6 +22,12 @@ export interface BaseExecuteToolResponse extends BaseWebSocketResponse {
|
|
|
22
22
|
result?: any;
|
|
23
23
|
status?: 'pending' | 'executing' | 'success' | 'error' | 'rejected';
|
|
24
24
|
}
|
|
25
|
+
export interface FlagContext {
|
|
26
|
+
user: string[];
|
|
27
|
+
project: string[];
|
|
28
|
+
thread: string[];
|
|
29
|
+
effective: string[];
|
|
30
|
+
}
|
|
25
31
|
export interface UserMessage {
|
|
26
32
|
type: "messageResponse";
|
|
27
33
|
message: {
|
|
@@ -42,6 +48,7 @@ export interface UserMessage {
|
|
|
42
48
|
actions: any[];
|
|
43
49
|
mentionedAgents: any[];
|
|
44
50
|
mentionedDocs: any[];
|
|
51
|
+
mentionedEnvironments?: any[];
|
|
45
52
|
links: any[];
|
|
46
53
|
universalAgentLastMessage: string;
|
|
47
54
|
selection: any | null;
|
|
@@ -53,6 +60,8 @@ export interface UserMessage {
|
|
|
53
60
|
templateType: string;
|
|
54
61
|
processId: string;
|
|
55
62
|
shadowGitHash: string;
|
|
63
|
+
mentionedFlags?: string[];
|
|
64
|
+
flags?: FlagContext;
|
|
56
65
|
};
|
|
57
66
|
sender: {
|
|
58
67
|
senderType: string;
|
|
@@ -84,6 +93,7 @@ export interface ChatMessageFromUser {
|
|
|
84
93
|
actions: any[];
|
|
85
94
|
mentionedAgents: any[];
|
|
86
95
|
mentionedDocs: any[];
|
|
96
|
+
mentionedEnvironments?: any[];
|
|
87
97
|
links: any[];
|
|
88
98
|
universalAgentLastMessage: string;
|
|
89
99
|
selection: any | null;
|
|
@@ -95,6 +105,8 @@ export interface ChatMessageFromUser {
|
|
|
95
105
|
templateType: string;
|
|
96
106
|
processId: string;
|
|
97
107
|
shadowGitHash: string;
|
|
108
|
+
mentionedFlags?: string[];
|
|
109
|
+
flags?: FlagContext;
|
|
98
110
|
}
|
|
99
111
|
export interface ChatMessage extends BaseWebSocketResponse {
|
|
100
112
|
id: string;
|
|
@@ -20,7 +20,6 @@ export declare class Agent implements AgentInterface {
|
|
|
20
20
|
private applyCompaction;
|
|
21
21
|
private tryRecoverPrompt;
|
|
22
22
|
private refreshAvailableTools;
|
|
23
|
-
private mergeTools;
|
|
24
23
|
private getAllowedToolNames;
|
|
25
24
|
private getRecoverableResponseError;
|
|
26
25
|
private collectResponseMessages;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.Agent = void 0;
|
|
7
|
-
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
8
4
|
const base_1 = require("../base");
|
|
9
5
|
const agentStep_1 = require("../base/agentStep");
|
|
10
6
|
const responseExecutor_1 = require("../base/responseExecutor");
|
|
11
7
|
const promptContext_1 = require("../base/promptContext");
|
|
12
8
|
const compactionOrchestrator_1 = require("../services/compaction/compactionOrchestrator");
|
|
9
|
+
const agentToolLoader_1 = require("../utils/agentToolLoader");
|
|
13
10
|
class Agent {
|
|
14
11
|
constructor(config) {
|
|
15
12
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -157,7 +154,7 @@ class Agent {
|
|
|
157
154
|
};
|
|
158
155
|
}
|
|
159
156
|
async refreshAvailableTools(originalRequest, prompt) {
|
|
160
|
-
var _a, _b, _c
|
|
157
|
+
var _a, _b, _c;
|
|
161
158
|
if (((_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['toolsInjected']) !== true ||
|
|
162
159
|
((_b = prompt.metadata) === null || _b === void 0 ? void 0 : _b['toolsLocation']) !== 'Tool') {
|
|
163
160
|
return prompt;
|
|
@@ -166,28 +163,23 @@ class Agent {
|
|
|
166
163
|
? prompt.message.tools
|
|
167
164
|
: [];
|
|
168
165
|
try {
|
|
169
|
-
const toolsResponse = await codeboltjs_1.default.mcp.listMcpFromServers(['codebolt']);
|
|
170
|
-
let refreshedTools = ((_c = toolsResponse === null || toolsResponse === void 0 ? void 0 : toolsResponse.data) === null || _c === void 0 ? void 0 : _c.tools) || (toolsResponse === null || toolsResponse === void 0 ? void 0 : toolsResponse.data) || [];
|
|
171
166
|
const mentionedMCPs = Array.isArray(originalRequest.mentionedMCPs)
|
|
172
167
|
? originalRequest.mentionedMCPs
|
|
173
168
|
: [];
|
|
174
|
-
|
|
175
|
-
const { data: mentionedTools } = await codeboltjs_1.default.mcp.getTools(mentionedMCPs);
|
|
176
|
-
refreshedTools = [...refreshedTools, ...(mentionedTools || [])];
|
|
177
|
-
}
|
|
169
|
+
let refreshedTools = await (0, agentToolLoader_1.listAgentAvailableTools)(mentionedMCPs);
|
|
178
170
|
const allowedToolNames = this.getAllowedToolNames(prompt);
|
|
179
171
|
if (allowedToolNames && allowedToolNames.length > 0) {
|
|
180
172
|
const allowed = new Set(allowedToolNames);
|
|
181
173
|
refreshedTools = refreshedTools.filter((tool) => { var _a; return !!((_a = tool.function) === null || _a === void 0 ? void 0 : _a.name) && allowed.has(tool.function.name); });
|
|
182
174
|
}
|
|
183
|
-
const mergedTools =
|
|
175
|
+
const mergedTools = (0, agentToolLoader_1.mergeTools)(refreshedTools, existingTools);
|
|
184
176
|
return {
|
|
185
177
|
...prompt,
|
|
186
178
|
message: {
|
|
187
179
|
...prompt.message,
|
|
188
180
|
tools: mergedTools,
|
|
189
181
|
...(mergedTools.length > 0
|
|
190
|
-
? { tool_choice: (
|
|
182
|
+
? { tool_choice: (_c = prompt.message.tool_choice) !== null && _c !== void 0 ? _c : 'auto' }
|
|
191
183
|
: {}),
|
|
192
184
|
},
|
|
193
185
|
metadata: {
|
|
@@ -204,23 +196,6 @@ class Agent {
|
|
|
204
196
|
return prompt;
|
|
205
197
|
}
|
|
206
198
|
}
|
|
207
|
-
mergeTools(existingTools, refreshedTools) {
|
|
208
|
-
var _a, _b;
|
|
209
|
-
const mergedTools = new Map();
|
|
210
|
-
for (const tool of refreshedTools) {
|
|
211
|
-
const toolName = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name;
|
|
212
|
-
if (toolName) {
|
|
213
|
-
mergedTools.set(toolName, tool);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
for (const tool of existingTools) {
|
|
217
|
-
const toolName = (_b = tool.function) === null || _b === void 0 ? void 0 : _b.name;
|
|
218
|
-
if (toolName && !mergedTools.has(toolName)) {
|
|
219
|
-
mergedTools.set(toolName, tool);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return Array.from(mergedTools.values());
|
|
223
|
-
}
|
|
224
199
|
getAllowedToolNames(prompt) {
|
|
225
200
|
var _a;
|
|
226
201
|
const metadataAllowedTools = (_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['allowedTools'];
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.CodeboltAgent = void 0;
|
|
7
4
|
exports.createCodeboltAgent = createCodeboltAgent;
|
|
8
|
-
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
9
5
|
const base_1 = require("../base");
|
|
10
6
|
const agentStep_1 = require("../base/agentStep");
|
|
11
7
|
const responseExecutor_1 = require("../base/responseExecutor");
|
|
12
8
|
const promptContext_1 = require("../base/promptContext");
|
|
13
9
|
const compactionOrchestrator_1 = require("../services/compaction/compactionOrchestrator");
|
|
10
|
+
const agentToolLoader_1 = require("../utils/agentToolLoader");
|
|
14
11
|
const processor_pieces_1 = require("../../processor-pieces");
|
|
15
12
|
class CodeboltAgent {
|
|
16
13
|
constructor(config) {
|
|
@@ -66,6 +63,7 @@ class CodeboltAgent {
|
|
|
66
63
|
mentionedMCPs: [],
|
|
67
64
|
uploadedImages: [],
|
|
68
65
|
mentionedAgents: [],
|
|
66
|
+
mentionedEnvironments: [],
|
|
69
67
|
messageId: `msg-${Date.now()}`,
|
|
70
68
|
threadId: `thread-${Date.now()}`
|
|
71
69
|
};
|
|
@@ -228,7 +226,7 @@ class CodeboltAgent {
|
|
|
228
226
|
};
|
|
229
227
|
}
|
|
230
228
|
async refreshAvailableTools(originalRequest, prompt) {
|
|
231
|
-
var _a, _b, _c
|
|
229
|
+
var _a, _b, _c;
|
|
232
230
|
if (((_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['toolsInjected']) !== true ||
|
|
233
231
|
((_b = prompt.metadata) === null || _b === void 0 ? void 0 : _b['toolsLocation']) !== 'Tool') {
|
|
234
232
|
return prompt;
|
|
@@ -237,28 +235,23 @@ class CodeboltAgent {
|
|
|
237
235
|
? prompt.message.tools
|
|
238
236
|
: [];
|
|
239
237
|
try {
|
|
240
|
-
const toolsResponse = await codeboltjs_1.default.mcp.listMcpFromServers(['codebolt']);
|
|
241
|
-
let refreshedTools = ((_c = toolsResponse === null || toolsResponse === void 0 ? void 0 : toolsResponse.data) === null || _c === void 0 ? void 0 : _c.tools) || (toolsResponse === null || toolsResponse === void 0 ? void 0 : toolsResponse.data) || [];
|
|
242
238
|
const mentionedMCPs = Array.isArray(originalRequest.mentionedMCPs)
|
|
243
239
|
? originalRequest.mentionedMCPs
|
|
244
240
|
: [];
|
|
245
|
-
|
|
246
|
-
const { data: mentionedTools } = await codeboltjs_1.default.mcp.getTools(mentionedMCPs);
|
|
247
|
-
refreshedTools = [...refreshedTools, ...(mentionedTools || [])];
|
|
248
|
-
}
|
|
241
|
+
let refreshedTools = await (0, agentToolLoader_1.listAgentAvailableTools)(mentionedMCPs);
|
|
249
242
|
const allowedToolNames = this.getAllowedToolNames(prompt);
|
|
250
243
|
if (allowedToolNames && allowedToolNames.length > 0) {
|
|
251
244
|
const allowed = new Set(allowedToolNames);
|
|
252
245
|
refreshedTools = refreshedTools.filter((tool) => { var _a; return !!((_a = tool.function) === null || _a === void 0 ? void 0 : _a.name) && allowed.has(tool.function.name); });
|
|
253
246
|
}
|
|
254
|
-
const mergedTools =
|
|
247
|
+
const mergedTools = (0, agentToolLoader_1.mergeTools)(refreshedTools, existingTools);
|
|
255
248
|
return {
|
|
256
249
|
...prompt,
|
|
257
250
|
message: {
|
|
258
251
|
...prompt.message,
|
|
259
252
|
tools: mergedTools,
|
|
260
253
|
...(mergedTools.length > 0
|
|
261
|
-
? { tool_choice: (
|
|
254
|
+
? { tool_choice: (_c = prompt.message.tool_choice) !== null && _c !== void 0 ? _c : 'auto' }
|
|
262
255
|
: {}),
|
|
263
256
|
},
|
|
264
257
|
metadata: {
|
|
@@ -275,23 +268,6 @@ class CodeboltAgent {
|
|
|
275
268
|
return prompt;
|
|
276
269
|
}
|
|
277
270
|
}
|
|
278
|
-
mergeTools(existingTools, refreshedTools) {
|
|
279
|
-
var _a, _b;
|
|
280
|
-
const mergedTools = new Map();
|
|
281
|
-
for (const tool of refreshedTools) {
|
|
282
|
-
const toolName = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name;
|
|
283
|
-
if (toolName) {
|
|
284
|
-
mergedTools.set(toolName, tool);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
for (const tool of existingTools) {
|
|
288
|
-
const toolName = (_b = tool.function) === null || _b === void 0 ? void 0 : _b.name;
|
|
289
|
-
if (toolName && !mergedTools.has(toolName)) {
|
|
290
|
-
mergedTools.set(toolName, tool);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return Array.from(mergedTools.values());
|
|
294
|
-
}
|
|
295
271
|
getAllowedToolNames(prompt) {
|
|
296
272
|
var _a;
|
|
297
273
|
const metadataAllowedTools = (_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['allowedTools'];
|
|
@@ -63,7 +63,7 @@ class AgentStep {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
async generateResponse(messageForLLM) {
|
|
66
|
-
var _a, _b;
|
|
66
|
+
var _a, _b, _c, _d;
|
|
67
67
|
const response = await codeboltjs_1.default.llm.inference(messageForLLM);
|
|
68
68
|
const completion = response.completion;
|
|
69
69
|
// Add tokenLimit and maxOutputTokens to completion object if available in response
|
|
@@ -75,6 +75,12 @@ class AgentStep {
|
|
|
75
75
|
if (response.maxOutputTokens !== undefined) {
|
|
76
76
|
completion.maxOutputTokens = response.maxOutputTokens;
|
|
77
77
|
}
|
|
78
|
+
if (response.contextCompaction !== undefined) {
|
|
79
|
+
completion.contextCompaction = response.contextCompaction;
|
|
80
|
+
}
|
|
81
|
+
if (response.compactionRequired !== undefined) {
|
|
82
|
+
completion.compactionRequired = response.compactionRequired;
|
|
83
|
+
}
|
|
78
84
|
// Also check inside completion object itself (from LLM provider response)
|
|
79
85
|
if (((_a = completion.completion) === null || _a === void 0 ? void 0 : _a.tokenLimit) !== undefined) {
|
|
80
86
|
completion.tokenLimit = completion.completion.tokenLimit;
|
|
@@ -82,6 +88,12 @@ class AgentStep {
|
|
|
82
88
|
if (((_b = completion.completion) === null || _b === void 0 ? void 0 : _b.maxOutputTokens) !== undefined) {
|
|
83
89
|
completion.maxOutputTokens = completion.completion.maxOutputTokens;
|
|
84
90
|
}
|
|
91
|
+
if (((_c = completion.completion) === null || _c === void 0 ? void 0 : _c.contextCompaction) !== undefined) {
|
|
92
|
+
completion.contextCompaction = completion.completion.contextCompaction;
|
|
93
|
+
}
|
|
94
|
+
if (((_d = completion.completion) === null || _d === void 0 ? void 0 : _d.compactionRequired) !== undefined) {
|
|
95
|
+
completion.compactionRequired = completion.completion.compactionRequired;
|
|
96
|
+
}
|
|
85
97
|
}
|
|
86
98
|
return completion;
|
|
87
99
|
}
|
|
@@ -8,6 +8,27 @@ exports.createUnifiedMessageProcessor = createUnifiedMessageProcessor;
|
|
|
8
8
|
const types_1 = require("../types/types");
|
|
9
9
|
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
10
10
|
const promptContext_1 = require("./promptContext");
|
|
11
|
+
const formatFlagList = (flags) => flags && flags.length > 0 ? flags.join(', ') : 'none';
|
|
12
|
+
const normalizeFlagList = (flags) => Array.from(new Set((flags || [])
|
|
13
|
+
.map(flag => String(flag || '').trim().toLowerCase().replace(/\s+/g, '-').replace(/^-+|-+$/g, ''))
|
|
14
|
+
.filter(Boolean))).sort();
|
|
15
|
+
const mergeFlagLists = (existing, mentioned) => {
|
|
16
|
+
const merged = [...(existing || []), ...normalizeFlagList(mentioned)];
|
|
17
|
+
return Array.from(new Set(merged.filter(Boolean)));
|
|
18
|
+
};
|
|
19
|
+
const formatFlagContext = (flags, mentionedFlags) => {
|
|
20
|
+
const normalizedMentionedFlags = normalizeFlagList(mentionedFlags);
|
|
21
|
+
if (!flags && normalizedMentionedFlags.length === 0)
|
|
22
|
+
return null;
|
|
23
|
+
return [
|
|
24
|
+
'<flags>',
|
|
25
|
+
`user: ${formatFlagList(flags === null || flags === void 0 ? void 0 : flags.user)}`,
|
|
26
|
+
`project: ${formatFlagList(flags === null || flags === void 0 ? void 0 : flags.project)}`,
|
|
27
|
+
`thread: ${formatFlagList(mergeFlagLists(flags === null || flags === void 0 ? void 0 : flags.thread, normalizedMentionedFlags))}`,
|
|
28
|
+
`effective: ${formatFlagList(mergeFlagLists(flags === null || flags === void 0 ? void 0 : flags.effective, normalizedMentionedFlags))}`,
|
|
29
|
+
'</flags>',
|
|
30
|
+
].join('\n');
|
|
31
|
+
};
|
|
11
32
|
/**
|
|
12
33
|
* Initial prompt generator that combines message modifiers with unified processing
|
|
13
34
|
*/
|
|
@@ -49,6 +70,13 @@ class InitialPromptGenerator {
|
|
|
49
70
|
role: 'user',
|
|
50
71
|
content: input.userMessage.trim(),
|
|
51
72
|
});
|
|
73
|
+
const flagContext = formatFlagContext(input.flags, input.mentionedFlags);
|
|
74
|
+
if (flagContext) {
|
|
75
|
+
createdMessage = (0, promptContext_1.appendUserContextMessage)(createdMessage, {
|
|
76
|
+
role: 'user',
|
|
77
|
+
content: flagContext,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
52
80
|
for (const messageModifier of this.processors) {
|
|
53
81
|
try {
|
|
54
82
|
createdMessage = await messageModifier.modify(input, createdMessage);
|
|
@@ -15,8 +15,12 @@ export declare class ResponseExecutor implements AgentResponseExecutor {
|
|
|
15
15
|
private parseToolCall;
|
|
16
16
|
private extractLastMessageContent;
|
|
17
17
|
private getToolCalls;
|
|
18
|
+
private hasExecutableToolCalls;
|
|
19
|
+
private runRequiredCompaction;
|
|
18
20
|
private executeTools;
|
|
19
21
|
private sendFinalMessageToChat;
|
|
22
|
+
private extractCompletionMessage;
|
|
23
|
+
private formatCompletionValue;
|
|
20
24
|
private executeSingleToolCall;
|
|
21
25
|
private executeTool;
|
|
22
26
|
private parseToolResult;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ResponseExecutor = void 0;
|
|
7
7
|
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
8
8
|
const promptContext_1 = require("./promptContext");
|
|
9
|
+
const agentToolLoader_1 = require("../utils/agentToolLoader");
|
|
9
10
|
class ResponseExecutor {
|
|
10
11
|
constructor(options) {
|
|
11
12
|
this.preToolCallProcessors = [];
|
|
@@ -38,10 +39,15 @@ class ResponseExecutor {
|
|
|
38
39
|
console.error(`[ResponseExecutor] Error in pre tool call processor:`, error);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
const compactionMessagePromise = this.runRequiredCompaction(input.rawLLMOutput);
|
|
41
43
|
const toolExecution = await this.executeTools(input.rawLLMOutput);
|
|
44
|
+
const compactionCompleted = await compactionMessagePromise;
|
|
45
|
+
if (compactionCompleted) {
|
|
46
|
+
await Promise.resolve(codeboltjs_1.default.chat.sendMessage('Conversation Compacted'));
|
|
47
|
+
}
|
|
42
48
|
this.completed = this.completed || toolExecution.completed;
|
|
43
49
|
this.finalMessage = (_a = toolExecution.finalMessage) !== null && _a !== void 0 ? _a : this.finalMessage;
|
|
44
|
-
this.injectDiscoveredTools(input.rawLLMOutput, toolExecution.toolResults, nextMessage);
|
|
50
|
+
await this.injectDiscoveredTools(input.rawLLMOutput, toolExecution.toolResults, nextMessage);
|
|
45
51
|
if (toolExecution.toolResults.length > 0 || toolExecution.followUpMessages.length > 0) {
|
|
46
52
|
nextMessage = (0, promptContext_1.appendTranscriptMessages)(nextMessage, [
|
|
47
53
|
...toolExecution.toolResults.map((toolResult) => ({
|
|
@@ -142,7 +148,35 @@ class ResponseExecutor {
|
|
|
142
148
|
}
|
|
143
149
|
return Array.from(toolCallsById.values());
|
|
144
150
|
}
|
|
151
|
+
hasExecutableToolCalls(llmResponse) {
|
|
152
|
+
return this.getToolCalls(llmResponse).some((toolCall) => {
|
|
153
|
+
var _a;
|
|
154
|
+
const toolName = ((_a = toolCall.function) === null || _a === void 0 ? void 0 : _a.name) || '';
|
|
155
|
+
return !toolName.includes('attempt_completion') &&
|
|
156
|
+
!toolName.includes('context_compaction') &&
|
|
157
|
+
!toolName.includes('contextCompaction');
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async runRequiredCompaction(llmResponse) {
|
|
161
|
+
var _a;
|
|
162
|
+
const decision = llmResponse.contextCompaction;
|
|
163
|
+
if (!(decision === null || decision === void 0 ? void 0 : decision.required) || decision.hasToolCalls === false || !this.hasExecutableToolCalls(llmResponse)) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
await codeboltjs_1.default.contextCompaction.run({
|
|
168
|
+
...(decision.runRequest || {}),
|
|
169
|
+
reason: String(((_a = decision.runRequest) === null || _a === void 0 ? void 0 : _a['reason']) || decision.reason || 'llm_response_tool_calls'),
|
|
170
|
+
});
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.error('[ResponseExecutor] Context compaction failed:', error);
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
145
178
|
async executeTools(llmResponse) {
|
|
179
|
+
var _a;
|
|
146
180
|
const lastMessageContent = this.extractLastMessageContent(llmResponse);
|
|
147
181
|
const toolCalls = this.getToolCalls(llmResponse);
|
|
148
182
|
if (toolCalls.length === 0) {
|
|
@@ -195,8 +229,9 @@ class ResponseExecutor {
|
|
|
195
229
|
const completionToolCall = completionToolCalls.at(-1);
|
|
196
230
|
if (completionToolCall) {
|
|
197
231
|
const completionArguments = completionToolCall.toolInput;
|
|
198
|
-
this.finalMessage = JSON.stringify(completionArguments);
|
|
199
232
|
const [, completionResult] = await this.executeTool(completionToolCall.toolName, completionArguments);
|
|
233
|
+
this.finalMessage = (_a = this.extractCompletionMessage(completionArguments)) !== null && _a !== void 0 ? _a : lastMessageContent;
|
|
234
|
+
await this.sendFinalMessageToChat(this.finalMessage);
|
|
200
235
|
const parsedCompletionResult = this.parseToolResult(completionToolCall.toolUseId, completionResult === '' ? 'The user is satisfied with the result.' : completionResult);
|
|
201
236
|
toolResults.push(parsedCompletionResult);
|
|
202
237
|
}
|
|
@@ -220,6 +255,36 @@ class ResponseExecutor {
|
|
|
220
255
|
console.error('[ResponseExecutor] Failed to send final chat message:', error);
|
|
221
256
|
}
|
|
222
257
|
}
|
|
258
|
+
extractCompletionMessage(toolInput) {
|
|
259
|
+
if ('result' in toolInput) {
|
|
260
|
+
return this.formatCompletionValue(toolInput['result']);
|
|
261
|
+
}
|
|
262
|
+
return this.formatCompletionValue(toolInput);
|
|
263
|
+
}
|
|
264
|
+
formatCompletionValue(value) {
|
|
265
|
+
if (typeof value === 'string') {
|
|
266
|
+
return value;
|
|
267
|
+
}
|
|
268
|
+
if (value === undefined || value === null) {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
if (typeof value !== 'object') {
|
|
272
|
+
return String(value);
|
|
273
|
+
}
|
|
274
|
+
const valueRecord = value;
|
|
275
|
+
for (const key of ['answer', 'message', 'content', 'text', 'output', 'result']) {
|
|
276
|
+
const nestedValue = valueRecord[key];
|
|
277
|
+
if (typeof nestedValue === 'string' && nestedValue.trim().length > 0) {
|
|
278
|
+
return nestedValue;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
return JSON.stringify(value, null, 2);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return String(value);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
223
288
|
async executeSingleToolCall(toolCall) {
|
|
224
289
|
try {
|
|
225
290
|
let resultTuple;
|
|
@@ -271,7 +336,8 @@ class ResponseExecutor {
|
|
|
271
336
|
}
|
|
272
337
|
async executeTool(toolName, toolInput) {
|
|
273
338
|
var _a, _b, _c;
|
|
274
|
-
const
|
|
339
|
+
const executionToolName = (0, agentToolLoader_1.resolveToolExecutionName)(toolName);
|
|
340
|
+
const parts = executionToolName.split('--');
|
|
275
341
|
const toolboxName = parts.length > 1 ? ((_a = parts[0]) !== null && _a !== void 0 ? _a : '') : 'codebolt';
|
|
276
342
|
const actualToolName = parts.length > 1 ? ((_b = parts[1]) !== null && _b !== void 0 ? _b : '') : ((_c = parts[0]) !== null && _c !== void 0 ? _c : '');
|
|
277
343
|
const { data } = await codeboltjs_1.default.mcp.executeTool(toolboxName, actualToolName, toolInput);
|
|
@@ -323,7 +389,7 @@ class ResponseExecutor {
|
|
|
323
389
|
getPostToolCallProcessors() {
|
|
324
390
|
return this.postToolCallProcessors;
|
|
325
391
|
}
|
|
326
|
-
injectDiscoveredTools(llmResponse, toolResults, nextMessage) {
|
|
392
|
+
async injectDiscoveredTools(llmResponse, toolResults, nextMessage) {
|
|
327
393
|
var _a, _b;
|
|
328
394
|
try {
|
|
329
395
|
const toolCalls = this.getToolCalls(llmResponse);
|
|
@@ -335,9 +401,16 @@ class ResponseExecutor {
|
|
|
335
401
|
const toolName = ((_b = toolCall.function) === null || _b === void 0 ? void 0 : _b.name) || '';
|
|
336
402
|
const isToolSearch = toolName === 'tool_search' ||
|
|
337
403
|
toolName === 'codebolt--tool_search' ||
|
|
338
|
-
toolName.endsWith('--tool_search')
|
|
404
|
+
toolName.endsWith('--tool_search') ||
|
|
405
|
+
toolName === 'search_mcp_tool' ||
|
|
406
|
+
toolName === 'codebolt--search_mcp_tool' ||
|
|
407
|
+
toolName.endsWith('--search_mcp_tool') ||
|
|
408
|
+
toolName === 'codebase_search_mcp_tool' ||
|
|
409
|
+
toolName === 'codebolt--codebase_search_mcp_tool' ||
|
|
410
|
+
toolName.endsWith('--codebase_search_mcp_tool');
|
|
339
411
|
if (!isToolSearch)
|
|
340
412
|
continue;
|
|
413
|
+
(0, agentToolLoader_1.appendUniqueTools)(nextMessage.message.tools, await (0, agentToolLoader_1.listProjectLocalTools)());
|
|
341
414
|
const toolCallId = toolCall.id;
|
|
342
415
|
const toolResult = toolResults.find(r => r.tool_call_id === toolCallId);
|
|
343
416
|
if (!(toolResult === null || toolResult === void 0 ? void 0 : toolResult.content))
|
|
@@ -363,7 +436,7 @@ class ResponseExecutor {
|
|
|
363
436
|
const rawName = schemaFunction === null || schemaFunction === void 0 ? void 0 : schemaFunction.name;
|
|
364
437
|
if (!rawName)
|
|
365
438
|
continue;
|
|
366
|
-
const prefixedName = rawName.
|
|
439
|
+
const prefixedName = rawName.includes('--') ? rawName : `codebolt--${rawName}`;
|
|
367
440
|
if (existingToolNames.has(prefixedName))
|
|
368
441
|
continue;
|
|
369
442
|
const prefixedSchema = {
|
|
@@ -206,6 +206,18 @@ export interface CodeboltAPI {
|
|
|
206
206
|
/** List available agents */
|
|
207
207
|
listAgents(): Promise<string[]>;
|
|
208
208
|
};
|
|
209
|
+
/** Dynamic agent events */
|
|
210
|
+
agentEvents?: {
|
|
211
|
+
emit(name: string, data?: Record<string, unknown>, options?: {
|
|
212
|
+
metadata?: Record<string, unknown>;
|
|
213
|
+
}): Promise<{
|
|
214
|
+
success: boolean;
|
|
215
|
+
type: string;
|
|
216
|
+
requestId?: string;
|
|
217
|
+
data?: unknown;
|
|
218
|
+
error?: string;
|
|
219
|
+
}>;
|
|
220
|
+
};
|
|
209
221
|
}
|
|
210
222
|
/**
|
|
211
223
|
* LLM configuration
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Tool } from '@codebolt/types/sdk';
|
|
2
|
+
type ToolResponse = {
|
|
3
|
+
data?: {
|
|
4
|
+
tools?: unknown;
|
|
5
|
+
} | unknown;
|
|
6
|
+
};
|
|
7
|
+
export declare function normalizeToolForModel(tool: Tool): Tool;
|
|
8
|
+
export declare function resolveToolExecutionName(modelToolName: string): string;
|
|
9
|
+
export declare function normalizeToolResponse(response: ToolResponse | undefined): Tool[];
|
|
10
|
+
export declare function mergeTools(...toolGroups: Tool[][]): Tool[];
|
|
11
|
+
export declare function listProjectLocalTools(): Promise<Tool[]>;
|
|
12
|
+
export declare function listAgentAvailableTools(mentionedMCPs?: unknown[]): Promise<Tool[]>;
|
|
13
|
+
export declare function appendUniqueTools(targetTools: Tool[], toolsToAppend: Tool[]): void;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.normalizeToolForModel = normalizeToolForModel;
|
|
7
|
+
exports.resolveToolExecutionName = resolveToolExecutionName;
|
|
8
|
+
exports.normalizeToolResponse = normalizeToolResponse;
|
|
9
|
+
exports.mergeTools = mergeTools;
|
|
10
|
+
exports.listProjectLocalTools = listProjectLocalTools;
|
|
11
|
+
exports.listAgentAvailableTools = listAgentAvailableTools;
|
|
12
|
+
exports.appendUniqueTools = appendUniqueTools;
|
|
13
|
+
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
14
|
+
const MODEL_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
15
|
+
const LOCAL_TOOL_PREFIX = 'local/';
|
|
16
|
+
const toolExecutionNameByModelName = new Map();
|
|
17
|
+
function isTool(value) {
|
|
18
|
+
var _a;
|
|
19
|
+
if (!value || typeof value !== 'object') {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const candidate = value;
|
|
23
|
+
return candidate.type === 'function' && typeof ((_a = candidate.function) === null || _a === void 0 ? void 0 : _a.name) === 'string';
|
|
24
|
+
}
|
|
25
|
+
function hashString(value) {
|
|
26
|
+
let hash = 0;
|
|
27
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
28
|
+
hash = ((hash << 5) - hash + value.charCodeAt(index)) | 0;
|
|
29
|
+
}
|
|
30
|
+
return Math.abs(hash).toString(36);
|
|
31
|
+
}
|
|
32
|
+
function sanitizeToolNamePart(value) {
|
|
33
|
+
const sanitized = value.replace(/[^a-zA-Z0-9_-]/g, '_').replace(/_+/g, '_');
|
|
34
|
+
return sanitized.replace(/^_+|_+$/g, '') || 'tool';
|
|
35
|
+
}
|
|
36
|
+
function normalizeToolForModel(tool) {
|
|
37
|
+
const originalName = tool.function.name;
|
|
38
|
+
let modelName = originalName;
|
|
39
|
+
if (!MODEL_TOOL_NAME_PATTERN.test(originalName)) {
|
|
40
|
+
const separatorIndex = originalName.indexOf('--');
|
|
41
|
+
if (originalName.startsWith(LOCAL_TOOL_PREFIX) && separatorIndex > LOCAL_TOOL_PREFIX.length) {
|
|
42
|
+
const toolboxName = originalName.slice(LOCAL_TOOL_PREFIX.length, separatorIndex);
|
|
43
|
+
const actualToolName = originalName.slice(separatorIndex + 2);
|
|
44
|
+
modelName = `local_${sanitizeToolNamePart(toolboxName)}--${sanitizeToolNamePart(actualToolName)}`;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
modelName = sanitizeToolNamePart(originalName);
|
|
48
|
+
}
|
|
49
|
+
const mappedName = toolExecutionNameByModelName.get(modelName);
|
|
50
|
+
if (mappedName && mappedName !== originalName) {
|
|
51
|
+
modelName = `${modelName}_${hashString(originalName)}`;
|
|
52
|
+
}
|
|
53
|
+
toolExecutionNameByModelName.set(modelName, originalName);
|
|
54
|
+
}
|
|
55
|
+
if (modelName === originalName) {
|
|
56
|
+
return tool;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...tool,
|
|
60
|
+
function: {
|
|
61
|
+
...tool.function,
|
|
62
|
+
name: modelName,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function resolveToolExecutionName(modelToolName) {
|
|
67
|
+
return toolExecutionNameByModelName.get(modelToolName) || modelToolName;
|
|
68
|
+
}
|
|
69
|
+
function normalizeToolResponse(response) {
|
|
70
|
+
const data = response === null || response === void 0 ? void 0 : response.data;
|
|
71
|
+
const tools = Array.isArray(data === null || data === void 0 ? void 0 : data.tools)
|
|
72
|
+
? data.tools
|
|
73
|
+
: Array.isArray(data)
|
|
74
|
+
? data
|
|
75
|
+
: [];
|
|
76
|
+
return tools.filter(isTool).map(normalizeToolForModel);
|
|
77
|
+
}
|
|
78
|
+
function mergeTools(...toolGroups) {
|
|
79
|
+
var _a;
|
|
80
|
+
const mergedTools = new Map();
|
|
81
|
+
for (const tools of toolGroups) {
|
|
82
|
+
for (const tool of tools) {
|
|
83
|
+
const toolName = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name;
|
|
84
|
+
if (toolName && !mergedTools.has(toolName)) {
|
|
85
|
+
mergedTools.set(toolName, tool);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return Array.from(mergedTools.values());
|
|
90
|
+
}
|
|
91
|
+
async function listProjectLocalTools() {
|
|
92
|
+
const mcp = codeboltjs_1.default.mcp;
|
|
93
|
+
if (typeof mcp.getLocalMCPServers !== 'function') {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
return normalizeToolResponse(await mcp.getLocalMCPServers());
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error('[AgentToolLoader] Failed to load project-local tools:', error);
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function listAgentAvailableTools(mentionedMCPs = []) {
|
|
105
|
+
let codeboltTools = [];
|
|
106
|
+
let mentionedTools = [];
|
|
107
|
+
try {
|
|
108
|
+
codeboltTools = normalizeToolResponse(await codeboltjs_1.default.mcp.listMcpFromServers(['codebolt']));
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.error('[AgentToolLoader] Failed to load CodeBolt tools:', error);
|
|
112
|
+
}
|
|
113
|
+
const localTools = await listProjectLocalTools();
|
|
114
|
+
if (mentionedMCPs.length > 0) {
|
|
115
|
+
try {
|
|
116
|
+
const response = await codeboltjs_1.default.mcp.getTools(mentionedMCPs);
|
|
117
|
+
mentionedTools = normalizeToolResponse(response);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error('[AgentToolLoader] Failed to load mentioned MCP tools:', error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return mergeTools(codeboltTools, localTools, mentionedTools);
|
|
124
|
+
}
|
|
125
|
+
function appendUniqueTools(targetTools, toolsToAppend) {
|
|
126
|
+
var _a;
|
|
127
|
+
const existingToolNames = new Set(targetTools
|
|
128
|
+
.map((tool) => { var _a; return (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name; })
|
|
129
|
+
.filter((toolName) => typeof toolName === 'string' && toolName.length > 0));
|
|
130
|
+
for (const tool of toolsToAppend) {
|
|
131
|
+
const toolName = (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name;
|
|
132
|
+
if (!toolName || existingToolNames.has(toolName)) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
targetTools.push(tool);
|
|
136
|
+
existingToolNames.add(toolName);
|
|
137
|
+
}
|
|
138
|
+
}
|