@codebolt/agent 6.1.19 → 6.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,35 +23,35 @@ Older examples that import from `@codebolt/agent/composable`, `@codebolt/agent/b
23
23
  ## Quick start
24
24
 
25
25
  ```typescript
26
- import { createCodeboltAgent } from '@codebolt/agent/unified';
26
+ import { createAgent } from '@codebolt/agent/unified';
27
27
 
28
- const agent = createCodeboltAgent({
28
+ const agent = createAgent({
29
29
  systemPrompt: 'You are a concise CodeBolt coding assistant.',
30
30
  allowedTools: ['read_file', 'write_file'],
31
31
  maxTurns: 10,
32
32
  });
33
33
 
34
- const result = await agent.processMessage('Inspect the current project and summarize it.');
34
+ const result = await agent.run('Inspect the current project and summarize it.');
35
35
 
36
36
  if (!result.success) {
37
37
  throw new Error(result.error);
38
38
  }
39
39
 
40
- console.log(result.finalMessage ?? result.result);
40
+ console.log(result.finalMessage ?? result.state?.prompt);
41
41
  ```
42
42
 
43
43
  ## Unified agent runtime
44
44
 
45
- Use `CodeboltAgent` or `createCodeboltAgent` for the default CodeBolt-aware runtime. It automatically adds common message modifiers for chat history, environment context, directory context, IDE context, system prompt injection, tool injection, and `@file` processing.
45
+ Use `Agent` or `createAgent` for the default CodeBolt-aware runtime. It automatically adds common message modifiers for chat history, environment context, directory context, IDE context, system prompt injection, tool injection, and `@file` processing. Pass `includeDefaultModifiers: false` and `includeDefaultProcessors: false` when you need a bare runtime.
46
46
 
47
47
  ```typescript
48
48
  import {
49
- CodeboltAgent,
49
+ Agent,
50
50
  ChatCompressionModifier,
51
51
  ToolValidationModifier,
52
52
  } from '@codebolt/agent/unified';
53
53
 
54
- const agent = new CodeboltAgent({
54
+ const agent = new Agent({
55
55
  instructions: 'Help the user safely modify code.',
56
56
  processors: {
57
57
  preInferenceProcessors: [new ChatCompressionModifier()],
@@ -61,10 +61,19 @@ const agent = new CodeboltAgent({
61
61
  maxTurns: 25,
62
62
  });
63
63
 
64
- const response = await agent.processMessage('Fix the lint errors in this package.');
64
+ const response = await agent.run('Fix the lint errors in this package.');
65
65
  ```
66
66
 
67
- For lower-level control, use `Agent`, `InitialPromptGenerator`, `AgentStep`, and `ResponseExecutor` from `@codebolt/agent/unified`.
67
+ For lower-level control, disable defaults or use `InitialPromptGenerator`, `AgentStep`, and `ResponseExecutor` from `@codebolt/agent/unified`.
68
+
69
+ Use `state` to continue a later run without depending on the internal prompt shape:
70
+
71
+ ```typescript
72
+ const first = await agent.run('Inspect the project.');
73
+ const second = await agent.run('Now summarize the risks.', {
74
+ state: first.state ?? undefined,
75
+ });
76
+ ```
68
77
 
69
78
  ## Processor pieces
70
79
 
@@ -148,7 +157,7 @@ The unified framework includes layered compaction utilities:
148
157
  - `PostCompactCleanup`
149
158
  - `TokenEstimator`
150
159
 
151
- These are used by `Agent` and `CodeboltAgent` to reduce transcript size and recover from token-limit errors.
160
+ These are used by `Agent` to reduce transcript size and recover from token-limit errors.
152
161
 
153
162
  ## Development
154
163
 
@@ -1,5 +1,46 @@
1
- import { AgentConfig, AgentInterface } from "@codebolt/types/agent";
1
+ import { AgentConfig, AgentInterface, MessageModifier, PostInferenceProcessor, PostToolCallProcessor, PreInferenceProcessor, PreToolCallProcessor, ProcessedMessage, ToolResult } from "@codebolt/types/agent";
2
2
  import { FlatUserMessage } from "@codebolt/types/sdk";
3
+ import { LoopDetectionService } from "../services/LoopDetectionService";
4
+ import type { CompactionOrchestratorOptions } from "../services/compaction/types";
5
+ export interface AgentOptions extends AgentConfig {
6
+ context?: ProcessedMessage;
7
+ allowedTools?: string[];
8
+ compaction?: CompactionOrchestratorOptions;
9
+ loopDetectionService?: LoopDetectionService;
10
+ maxTurns?: number;
11
+ includeDefaultModifiers?: boolean;
12
+ includeDefaultProcessors?: boolean;
13
+ messageModifiers?: MessageModifier[];
14
+ preInferenceProcessors?: PreInferenceProcessor[];
15
+ postInferenceProcessors?: PostInferenceProcessor[];
16
+ preToolCallProcessors?: PreToolCallProcessor[];
17
+ postToolCallProcessors?: PostToolCallProcessor[];
18
+ }
19
+ export interface AgentRunResult {
20
+ success: boolean;
21
+ state: AgentRunState | null;
22
+ toolResults: ToolResult[];
23
+ finalMessage?: string;
24
+ error?: string;
25
+ /**
26
+ * @deprecated Use `state.prompt` instead.
27
+ */
28
+ result: ProcessedMessage | null;
29
+ /**
30
+ * @deprecated Use `state` instead.
31
+ */
32
+ context: ProcessedMessage | null;
33
+ }
34
+ export interface AgentRunState {
35
+ prompt: ProcessedMessage;
36
+ }
37
+ export interface AgentRunOptions {
38
+ state?: AgentRunState;
39
+ context?: ProcessedMessage;
40
+ }
41
+ export interface CreateAgentOptions extends AgentOptions {
42
+ systemPrompt?: string;
43
+ }
3
44
  export declare class Agent implements AgentInterface {
4
45
  private readonly config;
5
46
  private readonly messageModifiers;
@@ -8,15 +49,30 @@ export declare class Agent implements AgentInterface {
8
49
  private readonly preToolCallProcessors;
9
50
  private readonly postToolCallProcessors;
10
51
  private readonly enableLogging;
52
+ private readonly baseSystemPrompt;
53
+ private readonly context;
54
+ private readonly allowedTools;
11
55
  private readonly compactionOrchestrator;
12
56
  private readonly loopDetectionService;
13
57
  private readonly maxTurns;
14
- constructor(config: AgentConfig);
58
+ private readonly localToolSchemas;
59
+ private readonly localToolsByExecutionName;
60
+ constructor(config: AgentOptions);
61
+ run(message: string | FlatUserMessage, options?: ProcessedMessage | AgentRunOptions): Promise<AgentRunResult>;
62
+ processMessage(message: string | FlatUserMessage, options?: ProcessedMessage | AgentRunOptions): Promise<AgentRunResult>;
15
63
  execute(reqMessage: FlatUserMessage): Promise<{
16
64
  success: boolean;
17
65
  result: any;
18
66
  error?: string;
19
67
  }>;
68
+ getConfig(): AgentOptions;
69
+ getMessageModifiers(): MessageModifier[];
70
+ getPreInferenceProcessors(): PreInferenceProcessor[];
71
+ getPostInferenceProcessors(): PostInferenceProcessor[];
72
+ getPreToolCallProcessors(): PreToolCallProcessor[];
73
+ getPostToolCallProcessors(): PostToolCallProcessor[];
74
+ private resolveRunContext;
75
+ private isProcessedMessage;
20
76
  private applyCompaction;
21
77
  private tryRecoverPrompt;
22
78
  private refreshAvailableTools;
@@ -24,3 +80,4 @@ export declare class Agent implements AgentInterface {
24
80
  private getRecoverableResponseError;
25
81
  private collectResponseMessages;
26
82
  }
83
+ export declare function createAgent(options: CreateAgentOptions): Agent;
@@ -1,45 +1,147 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Agent = void 0;
4
+ exports.createAgent = createAgent;
4
5
  const base_1 = require("../base");
5
6
  const agentStep_1 = require("../base/agentStep");
6
7
  const responseExecutor_1 = require("../base/responseExecutor");
7
8
  const promptContext_1 = require("../base/promptContext");
8
9
  const compactionOrchestrator_1 = require("../services/compaction/compactionOrchestrator");
9
10
  const agentToolLoader_1 = require("../utils/agentToolLoader");
11
+ const processor_pieces_1 = require("../../processor-pieces");
12
+ const DEFAULT_SYSTEM_PROMPT = 'Based on User Message send reply';
13
+ function getProcessorKey(processor) {
14
+ var _a;
15
+ const candidate = processor;
16
+ if (typeof candidate.id === 'string' && candidate.id.length > 0) {
17
+ return candidate.id;
18
+ }
19
+ if (typeof candidate.name === 'string' && candidate.name.length > 0) {
20
+ return candidate.name;
21
+ }
22
+ if ((_a = candidate.constructor) === null || _a === void 0 ? void 0 : _a.name) {
23
+ return candidate.constructor.name;
24
+ }
25
+ return String(processor);
26
+ }
27
+ function mergeProcessors(defaults, custom) {
28
+ const merged = new Map();
29
+ for (const processor of defaults) {
30
+ merged.set(getProcessorKey(processor), processor);
31
+ }
32
+ for (const processor of custom) {
33
+ merged.set(getProcessorKey(processor), processor);
34
+ }
35
+ return Array.from(merged.values());
36
+ }
37
+ function createDefaultMessageModifiers(systemPrompt, allowedTools) {
38
+ return [
39
+ new processor_pieces_1.ChatHistoryMessageModifier({
40
+ enableChatHistory: true,
41
+ includeSystemMessages: false,
42
+ }),
43
+ new processor_pieces_1.EnvironmentContextModifier({ enableFullContext: true }),
44
+ new processor_pieces_1.DirectoryContextModifier(),
45
+ new processor_pieces_1.IdeContextModifier({
46
+ includeActiveFile: true,
47
+ includeOpenFiles: true,
48
+ includeCursorPosition: true,
49
+ includeSelectedText: true
50
+ }),
51
+ new processor_pieces_1.CoreSystemPromptModifier({ customSystemPrompt: systemPrompt }),
52
+ new processor_pieces_1.ToolInjectionModifier({
53
+ includeToolDescriptions: true,
54
+ ...(allowedTools ? { allowedTools } : {})
55
+ }),
56
+ new processor_pieces_1.AtFileProcessorModifier({ enableRecursiveSearch: true })
57
+ ];
58
+ }
59
+ function createDefaultPreInferenceProcessors() {
60
+ return [];
61
+ }
62
+ function createDefaultPostInferenceProcessors() {
63
+ return [];
64
+ }
65
+ function createDefaultPreToolCallProcessors() {
66
+ return [];
67
+ }
68
+ function createDefaultPostToolCallProcessors() {
69
+ return [];
70
+ }
71
+ function createDefaultUserMessage(message) {
72
+ const timestamp = Date.now();
73
+ return {
74
+ userMessage: message,
75
+ selectedAgent: {
76
+ id: 'codebolt-agent',
77
+ name: 'Codebolt Agent'
78
+ },
79
+ mentionedFiles: [],
80
+ mentionedFullPaths: [],
81
+ mentionedFolders: [],
82
+ mentionedMCPs: [],
83
+ uploadedImages: [],
84
+ mentionedAgents: [],
85
+ mentionedEnvironments: [],
86
+ messageId: `msg-${timestamp}`,
87
+ threadId: `thread-${timestamp}`
88
+ };
89
+ }
90
+ function collectProcessors(fromNested, fromTopLevel) {
91
+ return [
92
+ ...(fromNested !== null && fromNested !== void 0 ? fromNested : []),
93
+ ...(fromTopLevel !== null && fromTopLevel !== void 0 ? fromTopLevel : []),
94
+ ];
95
+ }
10
96
  class Agent {
11
97
  constructor(config) {
12
- var _a, _b, _c, _d, _e, _f;
13
- const runtimeConfig = config;
98
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
99
+ const localToolRegistry = (0, agentToolLoader_1.createAgentLocalToolRegistry)(config.tools || []);
100
+ const includeDefaultModifiers = (_b = (_a = config.includeDefaultModifiers) !== null && _a !== void 0 ? _a : config.defaultProcessors) !== null && _b !== void 0 ? _b : true;
101
+ const includeDefaultProcessors = (_d = (_c = config.includeDefaultProcessors) !== null && _c !== void 0 ? _c : config.defaultProcessors) !== null && _d !== void 0 ? _d : true;
102
+ const customMessageModifiers = collectProcessors((_e = config.processors) === null || _e === void 0 ? void 0 : _e.messageModifiers, config.messageModifiers);
103
+ const defaultMessageModifiers = includeDefaultModifiers
104
+ ? createDefaultMessageModifiers(config.instructions || DEFAULT_SYSTEM_PROMPT, config.allowedTools)
105
+ : [];
14
106
  this.config = { ...config };
15
- this.messageModifiers = ((_a = config.processors) === null || _a === void 0 ? void 0 : _a.messageModifiers) || [];
16
- this.preInferenceProcessors = ((_b = config.processors) === null || _b === void 0 ? void 0 : _b.preInferenceProcessors) || [];
17
- this.postInferenceProcessors = ((_c = config.processors) === null || _c === void 0 ? void 0 : _c.postInferenceProcessors) || [];
18
- this.preToolCallProcessors = ((_d = config.processors) === null || _d === void 0 ? void 0 : _d.preToolCallProcessors) || [];
19
- this.postToolCallProcessors = ((_e = config.processors) === null || _e === void 0 ? void 0 : _e.postToolCallProcessors) || [];
20
107
  this.enableLogging = config.enableLogging !== false;
21
- this.compactionOrchestrator = new compactionOrchestrator_1.CompactionOrchestrator(runtimeConfig.compaction || {});
22
- this.loopDetectionService = runtimeConfig.loopDetectionService;
23
- this.maxTurns = (_f = runtimeConfig.maxTurns) !== null && _f !== void 0 ? _f : 25;
108
+ this.baseSystemPrompt = config.instructions || DEFAULT_SYSTEM_PROMPT;
109
+ this.context = config.context;
110
+ this.allowedTools = config.allowedTools;
111
+ this.messageModifiers = mergeProcessors(defaultMessageModifiers, customMessageModifiers);
112
+ this.preInferenceProcessors = mergeProcessors(includeDefaultProcessors ? createDefaultPreInferenceProcessors() : [], collectProcessors((_f = config.processors) === null || _f === void 0 ? void 0 : _f.preInferenceProcessors, config.preInferenceProcessors));
113
+ this.postInferenceProcessors = mergeProcessors(includeDefaultProcessors ? createDefaultPostInferenceProcessors() : [], collectProcessors((_g = config.processors) === null || _g === void 0 ? void 0 : _g.postInferenceProcessors, config.postInferenceProcessors));
114
+ this.preToolCallProcessors = mergeProcessors(includeDefaultProcessors ? createDefaultPreToolCallProcessors() : [], collectProcessors((_h = config.processors) === null || _h === void 0 ? void 0 : _h.preToolCallProcessors, config.preToolCallProcessors));
115
+ this.postToolCallProcessors = mergeProcessors(includeDefaultProcessors ? createDefaultPostToolCallProcessors() : [], collectProcessors((_j = config.processors) === null || _j === void 0 ? void 0 : _j.postToolCallProcessors, config.postToolCallProcessors));
116
+ this.compactionOrchestrator = new compactionOrchestrator_1.CompactionOrchestrator(config.compaction);
117
+ this.loopDetectionService = config.loopDetectionService;
118
+ this.maxTurns = (_l = (_k = config.maxTurns) !== null && _k !== void 0 ? _k : config.maxIterations) !== null && _l !== void 0 ? _l : 25;
119
+ this.localToolSchemas = localToolRegistry.schemas;
120
+ this.localToolsByExecutionName = localToolRegistry.byExecutionName;
24
121
  }
25
- async execute(reqMessage) {
26
- var _a;
27
- if (!reqMessage) {
28
- return {
29
- success: false,
30
- result: null,
31
- error: 'Request message is required'
32
- };
33
- }
122
+ async run(message, options) {
123
+ var _a, _b;
34
124
  try {
35
- const promptGenerator = new base_1.InitialPromptGenerator({
36
- processors: this.messageModifiers,
37
- baseSystemPrompt: this.config.instructions || 'Based on User Message send reply',
38
- enableLogging: this.enableLogging
39
- });
40
- let prompt = await promptGenerator.processMessage(reqMessage);
125
+ const reqMessage = typeof message === 'string'
126
+ ? createDefaultUserMessage(message)
127
+ : message;
128
+ let prompt;
129
+ const contextToUse = this.resolveRunContext(options);
130
+ if (contextToUse) {
131
+ prompt = contextToUse;
132
+ }
133
+ else {
134
+ const promptGenerator = new base_1.InitialPromptGenerator({
135
+ processors: this.messageModifiers,
136
+ baseSystemPrompt: this.baseSystemPrompt,
137
+ enableLogging: this.enableLogging
138
+ });
139
+ prompt = await promptGenerator.processMessage(reqMessage);
140
+ }
41
141
  let completed = false;
42
142
  let turnNumber = 0;
143
+ let finalMessage;
144
+ const toolResults = [];
43
145
  while (!completed) {
44
146
  turnNumber += 1;
45
147
  if (turnNumber > this.maxTurns) {
@@ -82,6 +184,7 @@ class Agent {
82
184
  const responseExecutor = new responseExecutor_1.ResponseExecutor({
83
185
  preToolCallProcessors: this.preToolCallProcessors,
84
186
  postToolCallProcessors: this.postToolCallProcessors,
187
+ localToolsByExecutionName: this.localToolsByExecutionName,
85
188
  ...(this.loopDetectionService
86
189
  ? { loopDetectionService: this.loopDetectionService }
87
190
  : {}),
@@ -94,10 +197,17 @@ class Agent {
94
197
  });
95
198
  completed = executionResult.completed;
96
199
  prompt = executionResult.nextMessage;
200
+ finalMessage = executionResult.finalMessage;
201
+ toolResults.push(...((_b = executionResult.toolResults) !== null && _b !== void 0 ? _b : []));
97
202
  }
203
+ const state = { prompt };
98
204
  return {
99
205
  success: true,
100
- result: prompt
206
+ state,
207
+ toolResults,
208
+ ...(finalMessage !== undefined ? { finalMessage } : {}),
209
+ result: prompt,
210
+ context: prompt,
101
211
  };
102
212
  }
103
213
  catch (error) {
@@ -107,11 +217,51 @@ class Agent {
107
217
  }
108
218
  return {
109
219
  success: false,
220
+ state: null,
221
+ toolResults: [],
110
222
  result: null,
223
+ context: null,
111
224
  error: errorMessage
112
225
  };
113
226
  }
114
227
  }
228
+ async processMessage(message, options) {
229
+ return this.run(message, options);
230
+ }
231
+ async execute(reqMessage) {
232
+ return this.run(reqMessage);
233
+ }
234
+ getConfig() {
235
+ return { ...this.config };
236
+ }
237
+ getMessageModifiers() {
238
+ return [...this.messageModifiers];
239
+ }
240
+ getPreInferenceProcessors() {
241
+ return [...this.preInferenceProcessors];
242
+ }
243
+ getPostInferenceProcessors() {
244
+ return [...this.postInferenceProcessors];
245
+ }
246
+ getPreToolCallProcessors() {
247
+ return [...this.preToolCallProcessors];
248
+ }
249
+ getPostToolCallProcessors() {
250
+ return [...this.postToolCallProcessors];
251
+ }
252
+ resolveRunContext(options) {
253
+ var _a, _b, _c;
254
+ if (!options) {
255
+ return this.context;
256
+ }
257
+ if (this.isProcessedMessage(options)) {
258
+ return options;
259
+ }
260
+ return (_c = (_b = (_a = options.state) === null || _a === void 0 ? void 0 : _a.prompt) !== null && _b !== void 0 ? _b : options.context) !== null && _c !== void 0 ? _c : this.context;
261
+ }
262
+ isProcessedMessage(value) {
263
+ return 'message' in value && 'metadata' in value;
264
+ }
115
265
  async applyCompaction(prompt) {
116
266
  const result = await this.compactionOrchestrator.compact((0, promptContext_1.getTranscriptMessages)(prompt));
117
267
  if (!result.wasCompacted) {
@@ -155,8 +305,9 @@ class Agent {
155
305
  }
156
306
  async refreshAvailableTools(originalRequest, prompt) {
157
307
  var _a, _b, _c;
158
- if (((_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['toolsInjected']) !== true ||
159
- ((_b = prompt.metadata) === null || _b === void 0 ? void 0 : _b['toolsLocation']) !== 'Tool') {
308
+ const shouldRefreshDiscoveredTools = ((_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['toolsInjected']) === true &&
309
+ ((_b = prompt.metadata) === null || _b === void 0 ? void 0 : _b['toolsLocation']) === 'Tool';
310
+ if (!shouldRefreshDiscoveredTools && this.localToolSchemas.length === 0) {
160
311
  return prompt;
161
312
  }
162
313
  const existingTools = Array.isArray(prompt.message.tools)
@@ -166,13 +317,21 @@ class Agent {
166
317
  const mentionedMCPs = Array.isArray(originalRequest.mentionedMCPs)
167
318
  ? originalRequest.mentionedMCPs
168
319
  : [];
169
- let refreshedTools = await (0, agentToolLoader_1.listAgentAvailableTools)(mentionedMCPs);
320
+ let refreshedTools = shouldRefreshDiscoveredTools
321
+ ? await (0, agentToolLoader_1.listAgentAvailableTools)(mentionedMCPs)
322
+ : [];
323
+ (0, agentToolLoader_1.assertNoLocalToolSchemaCollisions)(this.localToolSchemas, refreshedTools);
170
324
  const allowedToolNames = this.getAllowedToolNames(prompt);
171
325
  if (allowedToolNames && allowedToolNames.length > 0) {
172
326
  const allowed = new Set(allowedToolNames);
173
327
  refreshedTools = refreshedTools.filter((tool) => { var _a; return !!((_a = tool.function) === null || _a === void 0 ? void 0 : _a.name) && allowed.has(tool.function.name); });
174
328
  }
175
- const mergedTools = (0, agentToolLoader_1.mergeTools)(refreshedTools, existingTools);
329
+ let localToolSchemas = this.localToolSchemas;
330
+ if (allowedToolNames && allowedToolNames.length > 0) {
331
+ const allowed = new Set(allowedToolNames);
332
+ localToolSchemas = localToolSchemas.filter((tool) => { var _a; return !!((_a = tool.function) === null || _a === void 0 ? void 0 : _a.name) && allowed.has(tool.function.name); });
333
+ }
334
+ const mergedTools = (0, agentToolLoader_1.mergeTools)(localToolSchemas, refreshedTools, existingTools);
176
335
  return {
177
336
  ...prompt,
178
337
  message: {
@@ -190,6 +349,9 @@ class Agent {
190
349
  };
191
350
  }
192
351
  catch (error) {
352
+ if (error instanceof agentToolLoader_1.LocalToolConfigurationError) {
353
+ throw error;
354
+ }
193
355
  if (this.enableLogging) {
194
356
  console.error('[Agent] Failed to refresh tools:', error);
195
357
  }
@@ -199,11 +361,13 @@ class Agent {
199
361
  getAllowedToolNames(prompt) {
200
362
  var _a;
201
363
  const metadataAllowedTools = (_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['allowedTools'];
202
- if (!Array.isArray(metadataAllowedTools)) {
203
- return undefined;
364
+ if (Array.isArray(metadataAllowedTools)) {
365
+ const allowedToolNames = metadataAllowedTools.filter((toolName) => typeof toolName === 'string' && toolName.length > 0);
366
+ if (allowedToolNames.length > 0) {
367
+ return allowedToolNames;
368
+ }
204
369
  }
205
- const allowedToolNames = metadataAllowedTools.filter((toolName) => typeof toolName === 'string' && toolName.length > 0);
206
- return allowedToolNames.length > 0 ? allowedToolNames : undefined;
370
+ return this.allowedTools;
207
371
  }
208
372
  getRecoverableResponseError(response) {
209
373
  var _a, _b, _c, _d;
@@ -241,3 +405,10 @@ class Agent {
241
405
  }
242
406
  }
243
407
  exports.Agent = Agent;
408
+ function createAgent(options) {
409
+ const normalizedOptions = { ...options };
410
+ if (normalizedOptions.instructions === undefined && options.systemPrompt !== undefined) {
411
+ normalizedOptions.instructions = options.systemPrompt;
412
+ }
413
+ return new Agent(normalizedOptions);
414
+ }
@@ -2,14 +2,14 @@
2
2
  * Tool creation utilities for the Unified Agent Framework
3
3
  */
4
4
  import { z, ZodType } from 'zod';
5
- import type { OpenAITool } from '../types/libTypes';
6
- import { ToolConfig, ToolInterface } from '@codebolt/types/agent';
5
+ import type { Tool as OpenAITool } from '@codebolt/types/sdk';
6
+ import { AgentLocalToolExecutionContext, ToolConfig, ToolInterface } from '@codebolt/types/agent';
7
7
  export declare class Tool implements ToolInterface {
8
8
  id: string;
9
9
  description: string;
10
10
  inputSchema: ZodType;
11
11
  outputSchema?: ZodType | undefined;
12
- executionFunction: (context: unknown) => unknown;
12
+ executionFunction: (context: AgentLocalToolExecutionContext) => unknown;
13
13
  constructor(config: ToolConfig);
14
14
  execute(input: unknown, context: unknown): Promise<{
15
15
  success: boolean;
@@ -29,6 +29,61 @@ const formatFlagContext = (flags, mentionedFlags) => {
29
29
  '</flags>',
30
30
  ].join('\n');
31
31
  };
32
+ const createImageUrlBlock = (mediaType, base64Data) => ({
33
+ type: 'image_url',
34
+ image_url: {
35
+ url: `data:${mediaType};base64,${base64Data}`,
36
+ },
37
+ });
38
+ const normalizeImageAttachment = (image) => {
39
+ var _a, _b;
40
+ if (!image)
41
+ return null;
42
+ if (typeof image === 'string') {
43
+ const dataUrlMatch = image.match(/^data:([^;,]+);base64,(.+)$/);
44
+ if (!dataUrlMatch)
45
+ return null;
46
+ const mediaType = dataUrlMatch[1];
47
+ const base64Data = dataUrlMatch[2];
48
+ if (!mediaType || !base64Data)
49
+ return null;
50
+ return createImageUrlBlock(mediaType, base64Data);
51
+ }
52
+ if (typeof image === 'object') {
53
+ const imageBlock = image;
54
+ if (imageBlock.type === 'image_url' &&
55
+ typeof ((_a = imageBlock.image_url) === null || _a === void 0 ? void 0 : _a.url) === 'string') {
56
+ return {
57
+ type: 'image_url',
58
+ image_url: {
59
+ url: imageBlock.image_url.url,
60
+ },
61
+ };
62
+ }
63
+ if (imageBlock.type === 'image' &&
64
+ ((_b = imageBlock.source) === null || _b === void 0 ? void 0 : _b.type) === 'base64' &&
65
+ typeof imageBlock.source.media_type === 'string' &&
66
+ typeof imageBlock.source.data === 'string') {
67
+ return createImageUrlBlock(imageBlock.source.media_type, imageBlock.source.data);
68
+ }
69
+ }
70
+ return null;
71
+ };
72
+ const buildUserMessageContent = (text, uploadedImages) => {
73
+ const imageBlocks = (uploadedImages || [])
74
+ .map(normalizeImageAttachment)
75
+ .filter((image) => image !== null);
76
+ if (imageBlocks.length === 0) {
77
+ return text.trim();
78
+ }
79
+ return [
80
+ {
81
+ type: 'text',
82
+ text: text.trim() || 'Please use the attached image.',
83
+ },
84
+ ...imageBlocks,
85
+ ];
86
+ };
32
87
  /**
33
88
  * Initial prompt generator that combines message modifiers with unified processing
34
89
  */
@@ -68,7 +123,7 @@ class InitialPromptGenerator {
68
123
  }
69
124
  createdMessage = (0, promptContext_1.appendTranscriptMessage)(createdMessage, {
70
125
  role: 'user',
71
- content: input.userMessage.trim(),
126
+ content: buildUserMessageContent(input.userMessage || '', input.uploadedImages),
72
127
  });
73
128
  const flagContext = formatFlagContext(input.flags, input.mentionedFlags);
74
129
  if (flagContext) {
@@ -1,4 +1,4 @@
1
- import { AgentResponseExecutor, PostToolCallProcessor, PreToolCallProcessor, ResponseInput, ResponseOutput } from '@codebolt/types/agent';
1
+ import { AgentResponseExecutor, AgentLocalTool, PostToolCallProcessor, PreToolCallProcessor, ResponseInput, ResponseOutput } from '@codebolt/types/agent';
2
2
  import { LoopDetectionService } from '../services/LoopDetectionService';
3
3
  export declare class ResponseExecutor implements AgentResponseExecutor {
4
4
  private preToolCallProcessors;
@@ -6,10 +6,12 @@ export declare class ResponseExecutor implements AgentResponseExecutor {
6
6
  private completed;
7
7
  private finalMessage;
8
8
  private loopDetectionService;
9
+ private localToolsByExecutionName;
9
10
  constructor(options: {
10
11
  preToolCallProcessors: PreToolCallProcessor[];
11
12
  postToolCallProcessors: PostToolCallProcessor[];
12
13
  loopDetectionService?: LoopDetectionService;
14
+ localToolsByExecutionName?: Map<string, AgentLocalTool>;
13
15
  });
14
16
  executeResponse(input: ResponseInput): Promise<ResponseOutput>;
15
17
  private parseToolCall;
@@ -16,6 +16,7 @@ class ResponseExecutor {
16
16
  this.preToolCallProcessors = options.preToolCallProcessors;
17
17
  this.postToolCallProcessors = options.postToolCallProcessors;
18
18
  this.loopDetectionService = options.loopDetectionService;
19
+ this.localToolsByExecutionName = options.localToolsByExecutionName || new Map();
19
20
  }
20
21
  async executeResponse(input) {
21
22
  var _a, _b, _c;
@@ -40,7 +41,7 @@ class ResponseExecutor {
40
41
  }
41
42
  }
42
43
  const compactionMessagePromise = this.runRequiredCompaction(input.rawLLMOutput);
43
- const toolExecution = await this.executeTools(input.rawLLMOutput);
44
+ const toolExecution = await this.executeTools(input);
44
45
  const compactionCompleted = await compactionMessagePromise;
45
46
  if (compactionCompleted) {
46
47
  await Promise.resolve(codeboltjs_1.default.chat.sendMessage('Conversation Compacted'));
@@ -175,8 +176,9 @@ class ResponseExecutor {
175
176
  return false;
176
177
  }
177
178
  }
178
- async executeTools(llmResponse) {
179
+ async executeTools(input) {
179
180
  var _a;
181
+ const llmResponse = input.rawLLMOutput;
180
182
  const lastMessageContent = this.extractLastMessageContent(llmResponse);
181
183
  const toolCalls = this.getToolCalls(llmResponse);
182
184
  if (toolCalls.length === 0) {
@@ -220,7 +222,7 @@ class ResponseExecutor {
220
222
  toolResults.push(skippedResult);
221
223
  continue;
222
224
  }
223
- const executionResult = await this.executeSingleToolCall(currentToolCall);
225
+ const executionResult = await this.executeSingleToolCall(currentToolCall, input);
224
226
  toolResults.push(executionResult.toolResult);
225
227
  followUpMessages.push(...executionResult.followUpMessages);
226
228
  userRejectedToolUse = executionResult.didUserReject;
@@ -229,7 +231,7 @@ class ResponseExecutor {
229
231
  const completionToolCall = completionToolCalls.at(-1);
230
232
  if (completionToolCall) {
231
233
  const completionArguments = completionToolCall.toolInput;
232
- const [, completionResult] = await this.executeTool(completionToolCall.toolName, completionArguments);
234
+ const [, completionResult] = await this.executeTool(completionToolCall.toolName, completionArguments, input);
233
235
  this.finalMessage = (_a = this.extractCompletionMessage(completionArguments)) !== null && _a !== void 0 ? _a : lastMessageContent;
234
236
  await this.sendFinalMessageToChat(this.finalMessage);
235
237
  const parsedCompletionResult = this.parseToolResult(completionToolCall.toolUseId, completionResult === '' ? 'The user is satisfied with the result.' : completionResult);
@@ -285,7 +287,7 @@ class ResponseExecutor {
285
287
  return String(value);
286
288
  }
287
289
  }
288
- async executeSingleToolCall(toolCall) {
290
+ async executeSingleToolCall(toolCall, input) {
289
291
  try {
290
292
  let resultTuple;
291
293
  if (toolCall.toolName === 'codebolt--thread_management') {
@@ -309,7 +311,7 @@ class ResponseExecutor {
309
311
  resultTuple = [false, 'tool result is successful'];
310
312
  }
311
313
  else {
312
- resultTuple = await this.executeTool(toolCall.toolName, toolCall.toolInput);
314
+ resultTuple = await this.executeTool(toolCall.toolName, toolCall.toolInput, input);
313
315
  }
314
316
  const [didUserReject, result] = resultTuple;
315
317
  const parsedResult = this.parseToolResult(toolCall.toolUseId, result);
@@ -334,12 +336,26 @@ class ResponseExecutor {
334
336
  };
335
337
  }
336
338
  }
337
- async executeTool(toolName, toolInput) {
338
- var _a, _b, _c;
339
+ async executeTool(toolName, toolInput, input) {
340
+ var _a, _b, _c, _d;
339
341
  const executionToolName = (0, agentToolLoader_1.resolveToolExecutionName)(toolName);
342
+ const localTool = this.localToolsByExecutionName.get(executionToolName);
343
+ if (localTool) {
344
+ const localResult = await localTool.execute(toolInput, {
345
+ initialUserMessage: input.initialUserMessage,
346
+ llmMessageSent: input.actualMessageSentToLLM,
347
+ rawLLMResponse: input.rawLLMOutput,
348
+ nextMessage: input.nextMessage,
349
+ toolName: executionToolName,
350
+ });
351
+ if (!localResult.success) {
352
+ return [false, localResult.error || `Local tool "${executionToolName}" failed.`];
353
+ }
354
+ return [false, (_a = localResult.result) !== null && _a !== void 0 ? _a : ''];
355
+ }
340
356
  const parts = executionToolName.split('--');
341
- const toolboxName = parts.length > 1 ? ((_a = parts[0]) !== null && _a !== void 0 ? _a : '') : 'codebolt';
342
- const actualToolName = parts.length > 1 ? ((_b = parts[1]) !== null && _b !== void 0 ? _b : '') : ((_c = parts[0]) !== null && _c !== void 0 ? _c : '');
357
+ const toolboxName = parts.length > 1 ? ((_b = parts[0]) !== null && _b !== void 0 ? _b : '') : 'codebolt';
358
+ const actualToolName = parts.length > 1 ? ((_c = parts[1]) !== null && _c !== void 0 ? _c : '') : ((_d = parts[0]) !== null && _d !== void 0 ? _d : '');
343
359
  const { data } = await codeboltjs_1.default.mcp.executeTool(toolboxName, actualToolName, toolInput);
344
360
  if (Array.isArray(data) && data.length >= 2) {
345
361
  const [didUserReject, content] = data;
@@ -16,8 +16,7 @@ export { AgentStep } from './base/agentStep';
16
16
  export { ResponseExecutor } from './base/responseExecutor';
17
17
  export { LoopDetectionService, LoopType } from './services/LoopDetectionService';
18
18
  export { CompressionCoordinator, type CompressionCoordinatorOptions, type CompressionDecision, type CompressionMetadata, type CompressionRecoveryResult, type CompressionStage, } from './services/CompressionCoordinator';
19
- export { Agent } from './agent/agent';
20
- export { CodeboltAgent, createCodeboltAgent, type CodeboltAgentConfig } from './agent/codeboltAgent';
19
+ export { Agent, createAgent, type AgentOptions, type AgentRunResult, type AgentRunOptions, type AgentRunState, type CreateAgentOptions } from './agent/agent';
21
20
  export { Tool, createTool } from './agent/tools';
22
21
  export { Workflow } from './agent/workflow';
23
22
  export { type OpenAIMessage, type OpenAITool, type ToolResult, type CodeboltAPI, type AgentExecutionResult, type StreamChunk, type StreamCallback } from './types/libTypes';
@@ -10,7 +10,7 @@
10
10
  * The framework is designed to be modular, extensible, and easy to use.
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.TokenEstimator = exports.PostCompactCleanup = exports.ReactiveCompact = exports.AutoCompact = exports.ContextCollapse = exports.MicroCompact = exports.SnipCompact = exports.CompactionOrchestrator = exports.Workflow = exports.createTool = exports.Tool = exports.createCodeboltAgent = exports.CodeboltAgent = exports.Agent = exports.CompressionCoordinator = exports.LoopType = exports.LoopDetectionService = exports.ResponseExecutor = exports.AgentStep = exports.InitialPromptGenerator = exports.createDefaultMessageProcessor = exports.UnifiedToolExecutionError = exports.UnifiedResponseExecutionError = exports.UnifiedStepExecutionError = exports.UnifiedMessageProcessingError = exports.UnifiedAgentError = void 0;
13
+ exports.TokenEstimator = exports.PostCompactCleanup = exports.ReactiveCompact = exports.AutoCompact = exports.ContextCollapse = exports.MicroCompact = exports.SnipCompact = exports.CompactionOrchestrator = exports.Workflow = exports.createTool = exports.Tool = exports.createAgent = exports.Agent = exports.CompressionCoordinator = exports.LoopType = exports.LoopDetectionService = exports.ResponseExecutor = exports.AgentStep = exports.InitialPromptGenerator = exports.createDefaultMessageProcessor = exports.UnifiedToolExecutionError = exports.UnifiedResponseExecutionError = exports.UnifiedStepExecutionError = exports.UnifiedMessageProcessingError = exports.UnifiedAgentError = void 0;
14
14
  // Error types
15
15
  var types_1 = require("./types/types");
16
16
  Object.defineProperty(exports, "UnifiedAgentError", { enumerable: true, get: function () { return types_1.UnifiedAgentError; } });
@@ -35,9 +35,7 @@ Object.defineProperty(exports, "CompressionCoordinator", { enumerable: true, get
35
35
  // Agent framework components
36
36
  var agent_1 = require("./agent/agent");
37
37
  Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return agent_1.Agent; } });
38
- var codeboltAgent_1 = require("./agent/codeboltAgent");
39
- Object.defineProperty(exports, "CodeboltAgent", { enumerable: true, get: function () { return codeboltAgent_1.CodeboltAgent; } });
40
- Object.defineProperty(exports, "createCodeboltAgent", { enumerable: true, get: function () { return codeboltAgent_1.createCodeboltAgent; } });
38
+ Object.defineProperty(exports, "createAgent", { enumerable: true, get: function () { return agent_1.createAgent; } });
41
39
  var tools_1 = require("./agent/tools");
42
40
  Object.defineProperty(exports, "Tool", { enumerable: true, get: function () { return tools_1.Tool; } });
43
41
  Object.defineProperty(exports, "createTool", { enumerable: true, get: function () { return tools_1.createTool; } });
@@ -1,13 +1,23 @@
1
+ import type { AgentLocalTool } from '@codebolt/types/agent';
1
2
  import type { Tool } from '@codebolt/types/sdk';
2
3
  type ToolResponse = {
3
4
  data?: {
4
5
  tools?: unknown;
5
6
  } | unknown;
6
7
  };
8
+ export declare class LocalToolConfigurationError extends Error {
9
+ constructor(message: string);
10
+ }
11
+ export interface AgentLocalToolRegistry {
12
+ schemas: Tool[];
13
+ byExecutionName: Map<string, AgentLocalTool>;
14
+ }
7
15
  export declare function normalizeToolForModel(tool: Tool): Tool;
8
16
  export declare function resolveToolExecutionName(modelToolName: string): string;
9
17
  export declare function normalizeToolResponse(response: ToolResponse | undefined): Tool[];
10
18
  export declare function mergeTools(...toolGroups: Tool[][]): Tool[];
19
+ export declare function createAgentLocalToolRegistry(localTools?: AgentLocalTool[]): AgentLocalToolRegistry;
20
+ export declare function assertNoLocalToolSchemaCollisions(localSchemas: Tool[], externalSchemas: Tool[]): void;
11
21
  export declare function listProjectLocalTools(): Promise<Tool[]>;
12
22
  export declare function listAgentAvailableTools(mentionedMCPs?: unknown[]): Promise<Tool[]>;
13
23
  export declare function appendUniqueTools(targetTools: Tool[], toolsToAppend: Tool[]): void;
@@ -3,10 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LocalToolConfigurationError = void 0;
6
7
  exports.normalizeToolForModel = normalizeToolForModel;
7
8
  exports.resolveToolExecutionName = resolveToolExecutionName;
8
9
  exports.normalizeToolResponse = normalizeToolResponse;
9
10
  exports.mergeTools = mergeTools;
11
+ exports.createAgentLocalToolRegistry = createAgentLocalToolRegistry;
12
+ exports.assertNoLocalToolSchemaCollisions = assertNoLocalToolSchemaCollisions;
10
13
  exports.listProjectLocalTools = listProjectLocalTools;
11
14
  exports.listAgentAvailableTools = listAgentAvailableTools;
12
15
  exports.appendUniqueTools = appendUniqueTools;
@@ -14,6 +17,13 @@ const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
14
17
  const MODEL_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
15
18
  const LOCAL_TOOL_PREFIX = 'local/';
16
19
  const toolExecutionNameByModelName = new Map();
20
+ class LocalToolConfigurationError extends Error {
21
+ constructor(message) {
22
+ super(message);
23
+ this.name = 'LocalToolConfigurationError';
24
+ }
25
+ }
26
+ exports.LocalToolConfigurationError = LocalToolConfigurationError;
17
27
  function isTool(value) {
18
28
  var _a;
19
29
  if (!value || typeof value !== 'object') {
@@ -88,6 +98,57 @@ function mergeTools(...toolGroups) {
88
98
  }
89
99
  return Array.from(mergedTools.values());
90
100
  }
101
+ function isAgentLocalTool(value) {
102
+ if (!value || typeof value !== 'object') {
103
+ return false;
104
+ }
105
+ const candidate = value;
106
+ return typeof candidate.id === 'string' &&
107
+ candidate.id.length > 0 &&
108
+ typeof candidate.execute === 'function' &&
109
+ typeof candidate.toOpenAITool === 'function';
110
+ }
111
+ function createAgentLocalToolRegistry(localTools = []) {
112
+ var _a;
113
+ const schemas = [];
114
+ const byExecutionName = new Map();
115
+ const modelNames = new Set();
116
+ for (const localTool of localTools) {
117
+ if (!isAgentLocalTool(localTool)) {
118
+ throw new LocalToolConfigurationError('Agent local tools must be created with createTool(...) or implement id, execute(...), and toOpenAITool().');
119
+ }
120
+ if (byExecutionName.has(localTool.id)) {
121
+ throw new LocalToolConfigurationError(`Duplicate local agent tool id "${localTool.id}".`);
122
+ }
123
+ const schema = normalizeToolForModel(localTool.toOpenAITool());
124
+ const modelName = (_a = schema.function) === null || _a === void 0 ? void 0 : _a.name;
125
+ if (!modelName) {
126
+ throw new LocalToolConfigurationError(`Local agent tool "${localTool.id}" produced an invalid OpenAI tool schema.`);
127
+ }
128
+ if (modelNames.has(modelName)) {
129
+ throw new LocalToolConfigurationError(`Duplicate local agent tool model name "${modelName}".`);
130
+ }
131
+ schemas.push(schema);
132
+ modelNames.add(modelName);
133
+ byExecutionName.set(localTool.id, localTool);
134
+ }
135
+ return { schemas, byExecutionName };
136
+ }
137
+ function assertNoLocalToolSchemaCollisions(localSchemas, externalSchemas) {
138
+ var _a;
139
+ if (localSchemas.length === 0 || externalSchemas.length === 0) {
140
+ return;
141
+ }
142
+ const localToolNames = new Set(localSchemas
143
+ .map((tool) => { var _a; return (_a = tool.function) === null || _a === void 0 ? void 0 : _a.name; })
144
+ .filter((toolName) => typeof toolName === 'string' && toolName.length > 0));
145
+ for (const externalSchema of externalSchemas) {
146
+ const externalToolName = (_a = externalSchema.function) === null || _a === void 0 ? void 0 : _a.name;
147
+ if (externalToolName && localToolNames.has(externalToolName)) {
148
+ throw new LocalToolConfigurationError(`Local agent tool "${externalToolName}" collides with an existing CodeBolt or MCP tool.`);
149
+ }
150
+ }
151
+ }
91
152
  async function listProjectLocalTools() {
92
153
  const mcp = codeboltjs_1.default.mcp;
93
154
  if (typeof mcp.getLocalMCPServers !== 'function') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebolt/agent",
3
- "version": "6.1.19",
3
+ "version": "6.1.20",
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",
@@ -1,61 +0,0 @@
1
- import { AgentConfig, MessageModifier, PostInferenceProcessor, PostToolCallProcessor, PreInferenceProcessor, PreToolCallProcessor, ProcessedMessage } from "@codebolt/types/agent";
2
- import { FlatUserMessage } from "@codebolt/types/sdk";
3
- import { LoopDetectionService } from "../services/LoopDetectionService";
4
- import type { CompactionOrchestratorOptions } from "../services/compaction/types";
5
- export interface CodeboltAgentConfig extends AgentConfig {
6
- enableLogging?: boolean;
7
- context?: ProcessedMessage;
8
- allowedTools?: string[];
9
- compaction?: CompactionOrchestratorOptions;
10
- loopDetectionService?: LoopDetectionService;
11
- maxTurns?: number;
12
- }
13
- export declare class CodeboltAgent {
14
- private readonly config;
15
- private readonly messageModifiers;
16
- private readonly preInferenceProcessors;
17
- private readonly postInferenceProcessors;
18
- private readonly preToolCallProcessors;
19
- private readonly postToolCallProcessors;
20
- private readonly enableLogging;
21
- private readonly baseSystemPrompt;
22
- private readonly context;
23
- private readonly allowedTools;
24
- private readonly compactionOrchestrator;
25
- private readonly loopDetectionService;
26
- private readonly maxTurns;
27
- constructor(config: CodeboltAgentConfig);
28
- private createDefaultMessageModifiers;
29
- private createDefaultUserMessage;
30
- processMessage(message: string | FlatUserMessage, context?: ProcessedMessage): Promise<{
31
- success: boolean;
32
- result: any;
33
- context: ProcessedMessage | null;
34
- finalMessage?: string;
35
- error?: string;
36
- }>;
37
- getConfig(): CodeboltAgentConfig;
38
- getMessageModifiers(): MessageModifier[];
39
- getPreInferenceProcessors(): PreInferenceProcessor[];
40
- getPostInferenceProcessors(): PostInferenceProcessor[];
41
- getPreToolCallProcessors(): PreToolCallProcessor[];
42
- getPostToolCallProcessors(): PostToolCallProcessor[];
43
- private applyCompaction;
44
- private tryRecoverPrompt;
45
- private refreshAvailableTools;
46
- private getAllowedToolNames;
47
- private getRecoverableResponseError;
48
- private collectResponseMessages;
49
- }
50
- export declare function createCodeboltAgent(options: {
51
- systemPrompt: string;
52
- messageModifiers?: MessageModifier[];
53
- preInferenceProcessors?: PreInferenceProcessor[];
54
- postInferenceProcessors?: PostInferenceProcessor[];
55
- preToolCallProcessors?: PreToolCallProcessor[];
56
- postToolCallProcessors?: PostToolCallProcessor[];
57
- enableLogging?: boolean;
58
- compaction?: CompactionOrchestratorOptions;
59
- loopDetectionService?: LoopDetectionService;
60
- maxTurns?: number;
61
- }): CodeboltAgent;
@@ -1,334 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CodeboltAgent = void 0;
4
- exports.createCodeboltAgent = createCodeboltAgent;
5
- const base_1 = require("../base");
6
- const agentStep_1 = require("../base/agentStep");
7
- const responseExecutor_1 = require("../base/responseExecutor");
8
- const promptContext_1 = require("../base/promptContext");
9
- const compactionOrchestrator_1 = require("../services/compaction/compactionOrchestrator");
10
- const agentToolLoader_1 = require("../utils/agentToolLoader");
11
- const processor_pieces_1 = require("../../processor-pieces");
12
- class CodeboltAgent {
13
- constructor(config) {
14
- var _a, _b, _c, _d, _e, _f, _g;
15
- this.config = { ...config };
16
- this.enableLogging = config.enableLogging !== false;
17
- this.baseSystemPrompt = config.instructions || 'Based on User Message send reply';
18
- this.context = config.context;
19
- this.allowedTools = config.allowedTools;
20
- this.messageModifiers = ((_b = (_a = config.processors) === null || _a === void 0 ? void 0 : _a.messageModifiers) === null || _b === void 0 ? void 0 : _b.length)
21
- ? config.processors.messageModifiers
22
- : this.createDefaultMessageModifiers(this.baseSystemPrompt, this.allowedTools);
23
- this.preInferenceProcessors = ((_c = config.processors) === null || _c === void 0 ? void 0 : _c.preInferenceProcessors) || [];
24
- this.postInferenceProcessors = ((_d = config.processors) === null || _d === void 0 ? void 0 : _d.postInferenceProcessors) || [];
25
- this.preToolCallProcessors = ((_e = config.processors) === null || _e === void 0 ? void 0 : _e.preToolCallProcessors) || [];
26
- this.postToolCallProcessors = ((_f = config.processors) === null || _f === void 0 ? void 0 : _f.postToolCallProcessors) || [];
27
- this.compactionOrchestrator = new compactionOrchestrator_1.CompactionOrchestrator(config.compaction);
28
- this.loopDetectionService = config.loopDetectionService;
29
- this.maxTurns = (_g = config.maxTurns) !== null && _g !== void 0 ? _g : 25;
30
- }
31
- createDefaultMessageModifiers(systemPrompt, allowedTools) {
32
- return [
33
- new processor_pieces_1.ChatHistoryMessageModifier({
34
- enableChatHistory: true,
35
- includeSystemMessages: false,
36
- }),
37
- new processor_pieces_1.EnvironmentContextModifier({ enableFullContext: true }),
38
- new processor_pieces_1.DirectoryContextModifier(),
39
- new processor_pieces_1.IdeContextModifier({
40
- includeActiveFile: true,
41
- includeOpenFiles: true,
42
- includeCursorPosition: true,
43
- includeSelectedText: true
44
- }),
45
- new processor_pieces_1.CoreSystemPromptModifier({ customSystemPrompt: systemPrompt }),
46
- new processor_pieces_1.ToolInjectionModifier({
47
- includeToolDescriptions: true,
48
- ...(allowedTools && { allowedTools })
49
- }),
50
- new processor_pieces_1.AtFileProcessorModifier({ enableRecursiveSearch: true })
51
- ];
52
- }
53
- createDefaultUserMessage(message) {
54
- return {
55
- userMessage: message,
56
- selectedAgent: {
57
- id: 'codebolt-agent',
58
- name: 'Codebolt Agent'
59
- },
60
- mentionedFiles: [],
61
- mentionedFullPaths: [],
62
- mentionedFolders: [],
63
- mentionedMCPs: [],
64
- uploadedImages: [],
65
- mentionedAgents: [],
66
- mentionedEnvironments: [],
67
- messageId: `msg-${Date.now()}`,
68
- threadId: `thread-${Date.now()}`
69
- };
70
- }
71
- async processMessage(message, context) {
72
- var _a;
73
- try {
74
- const reqMessage = typeof message === 'string'
75
- ? this.createDefaultUserMessage(message)
76
- : message;
77
- let prompt;
78
- const contextToUse = context || this.context;
79
- if (contextToUse) {
80
- prompt = contextToUse;
81
- }
82
- else {
83
- const promptGenerator = new base_1.InitialPromptGenerator({
84
- processors: this.messageModifiers,
85
- baseSystemPrompt: this.baseSystemPrompt,
86
- enableLogging: this.enableLogging
87
- });
88
- prompt = await promptGenerator.processMessage(reqMessage);
89
- }
90
- let completed = false;
91
- let turnNumber = 0;
92
- let finalMessage;
93
- while (!completed) {
94
- turnNumber += 1;
95
- if (turnNumber > this.maxTurns) {
96
- throw new Error(`Agent exceeded the maximum turn limit of ${this.maxTurns}.`);
97
- }
98
- this.compactionOrchestrator.resetForTurn();
99
- prompt = await this.applyCompaction(prompt);
100
- prompt = await this.refreshAvailableTools(reqMessage, prompt);
101
- const agentStep = new agentStep_1.AgentStep({
102
- preInferenceProcessors: this.preInferenceProcessors,
103
- postInferenceProcessors: this.postInferenceProcessors
104
- });
105
- let stepResult;
106
- while (!stepResult) {
107
- try {
108
- const nextStepResult = await agentStep.executeStep(reqMessage, prompt);
109
- this.compactionOrchestrator.updateModelTokenLimit((_a = nextStepResult.rawLLMResponse) === null || _a === void 0 ? void 0 : _a.tokenLimit);
110
- const recoverableResponseError = this.getRecoverableResponseError(nextStepResult.rawLLMResponse);
111
- if (!recoverableResponseError) {
112
- stepResult = nextStepResult;
113
- break;
114
- }
115
- const recoveredPrompt = await this.tryRecoverPrompt(prompt, new Error(recoverableResponseError));
116
- if (!recoveredPrompt) {
117
- throw new Error(recoverableResponseError);
118
- }
119
- prompt = recoveredPrompt;
120
- }
121
- catch (error) {
122
- const recoveredPrompt = await this.tryRecoverPrompt(prompt, error);
123
- if (!recoveredPrompt) {
124
- throw error;
125
- }
126
- prompt = recoveredPrompt;
127
- }
128
- }
129
- if (!stepResult) {
130
- throw new Error('Agent step did not produce a response.');
131
- }
132
- const responseExecutor = new responseExecutor_1.ResponseExecutor({
133
- preToolCallProcessors: this.preToolCallProcessors,
134
- postToolCallProcessors: this.postToolCallProcessors,
135
- ...(this.loopDetectionService
136
- ? { loopDetectionService: this.loopDetectionService }
137
- : {}),
138
- });
139
- const executionResult = await responseExecutor.executeResponse({
140
- initialUserMessage: reqMessage,
141
- actualMessageSentToLLM: stepResult.actualMessageSentToLLM,
142
- rawLLMOutput: stepResult.rawLLMResponse,
143
- nextMessage: stepResult.nextMessage
144
- });
145
- completed = executionResult.completed;
146
- prompt = executionResult.nextMessage;
147
- finalMessage = executionResult.finalMessage;
148
- }
149
- return {
150
- success: true,
151
- result: prompt,
152
- context: prompt,
153
- ...(finalMessage !== undefined ? { finalMessage } : {}),
154
- };
155
- }
156
- catch (error) {
157
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
158
- if (this.enableLogging) {
159
- console.error('[CodeboltAgent] Execution failed:', error);
160
- }
161
- return {
162
- success: false,
163
- result: null,
164
- context: null,
165
- error: errorMessage
166
- };
167
- }
168
- }
169
- getConfig() {
170
- return { ...this.config };
171
- }
172
- getMessageModifiers() {
173
- return [...this.messageModifiers];
174
- }
175
- getPreInferenceProcessors() {
176
- return [...this.preInferenceProcessors];
177
- }
178
- getPostInferenceProcessors() {
179
- return [...this.postInferenceProcessors];
180
- }
181
- getPreToolCallProcessors() {
182
- return [...this.preToolCallProcessors];
183
- }
184
- getPostToolCallProcessors() {
185
- return [...this.postToolCallProcessors];
186
- }
187
- async applyCompaction(prompt) {
188
- const result = await this.compactionOrchestrator.compact((0, promptContext_1.getTranscriptMessages)(prompt));
189
- if (!result.wasCompacted) {
190
- return prompt;
191
- }
192
- return {
193
- ...(0, promptContext_1.replaceTranscriptMessages)(prompt, result.messages),
194
- metadata: {
195
- ...prompt.metadata,
196
- compaction: {
197
- totalTokensFreed: result.totalTokensFreed,
198
- layersApplied: result.layersApplied,
199
- boundaries: result.boundaries,
200
- timestamp: new Date().toISOString(),
201
- },
202
- },
203
- };
204
- }
205
- async tryRecoverPrompt(prompt, error) {
206
- const errorMessage = error instanceof Error ? error.message : String(error);
207
- if (!this.compactionOrchestrator.getReactiveLayer().isRecoverableError(errorMessage)) {
208
- return null;
209
- }
210
- const recovery = await this.compactionOrchestrator.recoverFromError((0, promptContext_1.getTranscriptMessages)(prompt), error);
211
- if (!recovery.wasCompacted) {
212
- return null;
213
- }
214
- return {
215
- ...(0, promptContext_1.replaceTranscriptMessages)(prompt, recovery.messages),
216
- metadata: {
217
- ...prompt.metadata,
218
- reactiveCompaction: {
219
- totalTokensFreed: recovery.totalTokensFreed,
220
- layersApplied: recovery.layersApplied,
221
- boundaries: recovery.boundaries,
222
- timestamp: new Date().toISOString(),
223
- error: errorMessage,
224
- },
225
- },
226
- };
227
- }
228
- async refreshAvailableTools(originalRequest, prompt) {
229
- var _a, _b, _c;
230
- if (((_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['toolsInjected']) !== true ||
231
- ((_b = prompt.metadata) === null || _b === void 0 ? void 0 : _b['toolsLocation']) !== 'Tool') {
232
- return prompt;
233
- }
234
- const existingTools = Array.isArray(prompt.message.tools)
235
- ? prompt.message.tools
236
- : [];
237
- try {
238
- const mentionedMCPs = Array.isArray(originalRequest.mentionedMCPs)
239
- ? originalRequest.mentionedMCPs
240
- : [];
241
- let refreshedTools = await (0, agentToolLoader_1.listAgentAvailableTools)(mentionedMCPs);
242
- const allowedToolNames = this.getAllowedToolNames(prompt);
243
- if (allowedToolNames && allowedToolNames.length > 0) {
244
- const allowed = new Set(allowedToolNames);
245
- refreshedTools = refreshedTools.filter((tool) => { var _a; return !!((_a = tool.function) === null || _a === void 0 ? void 0 : _a.name) && allowed.has(tool.function.name); });
246
- }
247
- const mergedTools = (0, agentToolLoader_1.mergeTools)(refreshedTools, existingTools);
248
- return {
249
- ...prompt,
250
- message: {
251
- ...prompt.message,
252
- tools: mergedTools,
253
- ...(mergedTools.length > 0
254
- ? { tool_choice: (_c = prompt.message.tool_choice) !== null && _c !== void 0 ? _c : 'auto' }
255
- : {}),
256
- },
257
- metadata: {
258
- ...prompt.metadata,
259
- toolsCount: mergedTools.length,
260
- toolsRefreshedAt: new Date().toISOString(),
261
- },
262
- };
263
- }
264
- catch (error) {
265
- if (this.enableLogging) {
266
- console.error('[CodeboltAgent] Failed to refresh tools:', error);
267
- }
268
- return prompt;
269
- }
270
- }
271
- getAllowedToolNames(prompt) {
272
- var _a;
273
- const metadataAllowedTools = (_a = prompt.metadata) === null || _a === void 0 ? void 0 : _a['allowedTools'];
274
- if (Array.isArray(metadataAllowedTools)) {
275
- const allowedToolNames = metadataAllowedTools.filter((toolName) => typeof toolName === 'string' && toolName.length > 0);
276
- if (allowedToolNames.length > 0) {
277
- return allowedToolNames;
278
- }
279
- }
280
- return this.allowedTools;
281
- }
282
- getRecoverableResponseError(response) {
283
- var _a, _b, _c, _d;
284
- const reactiveLayer = this.compactionOrchestrator.getReactiveLayer();
285
- const candidateMessages = this.collectResponseMessages(response);
286
- const recoverableMessage = candidateMessages.find((message) => reactiveLayer.isRecoverableError(message));
287
- if (recoverableMessage) {
288
- return recoverableMessage;
289
- }
290
- const finishReasons = [
291
- response.finish_reason,
292
- ...((_a = response.choices) !== null && _a !== void 0 ? _a : []).map((choice) => choice.finish_reason),
293
- ].filter((reason) => typeof reason === 'string');
294
- const hasLengthFinishReason = finishReasons.some((reason) => reason.toLowerCase() === 'length');
295
- const hasToolCalls = ((_c = (_b = response.tool_calls) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) > 0 ||
296
- ((_d = response.choices) !== null && _d !== void 0 ? _d : []).some((choice) => { var _a, _b, _c; return ((_c = (_b = (_a = choice.message) === null || _a === void 0 ? void 0 : _a.tool_calls) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) > 0; });
297
- if (hasLengthFinishReason && candidateMessages.length === 0 && !hasToolCalls) {
298
- return 'Too many tokens or token limit reached before producing usable output.';
299
- }
300
- return null;
301
- }
302
- collectResponseMessages(response) {
303
- var _a, _b;
304
- const messages = [];
305
- if (typeof response.content === 'string' && response.content.trim().length > 0) {
306
- messages.push(response.content.trim());
307
- }
308
- for (const choice of (_a = response.choices) !== null && _a !== void 0 ? _a : []) {
309
- if (typeof ((_b = choice.message) === null || _b === void 0 ? void 0 : _b.content) === 'string' &&
310
- choice.message.content.trim().length > 0) {
311
- messages.push(choice.message.content.trim());
312
- }
313
- }
314
- return messages;
315
- }
316
- }
317
- exports.CodeboltAgent = CodeboltAgent;
318
- function createCodeboltAgent(options) {
319
- var _a;
320
- return new CodeboltAgent({
321
- instructions: options.systemPrompt,
322
- processors: {
323
- messageModifiers: options.messageModifiers || [],
324
- preInferenceProcessors: options.preInferenceProcessors || [],
325
- postInferenceProcessors: options.postInferenceProcessors || [],
326
- preToolCallProcessors: options.preToolCallProcessors || [],
327
- postToolCallProcessors: options.postToolCallProcessors || []
328
- },
329
- enableLogging: (_a = options.enableLogging) !== null && _a !== void 0 ? _a : true,
330
- ...(options.compaction ? { compaction: options.compaction } : {}),
331
- ...(options.loopDetectionService ? { loopDetectionService: options.loopDetectionService } : {}),
332
- ...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}),
333
- });
334
- }