@push.rocks/smartagent 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  2. package/dist_ts/00_commitinfo_data.js +9 -0
  3. package/dist_ts/index.d.ts +10 -0
  4. package/dist_ts/index.js +18 -0
  5. package/dist_ts/plugins.d.ts +6 -0
  6. package/dist_ts/plugins.js +8 -0
  7. package/dist_ts/smartagent.classes.driveragent.d.ts +70 -0
  8. package/dist_ts/smartagent.classes.driveragent.js +274 -0
  9. package/dist_ts/smartagent.classes.dualagent.d.ts +62 -0
  10. package/dist_ts/smartagent.classes.dualagent.js +298 -0
  11. package/dist_ts/smartagent.classes.guardianagent.d.ts +46 -0
  12. package/dist_ts/smartagent.classes.guardianagent.js +201 -0
  13. package/dist_ts/smartagent.classes.smartagent.d.ts +123 -0
  14. package/dist_ts/smartagent.classes.smartagent.js +274 -0
  15. package/dist_ts/smartagent.interfaces.d.ts +165 -0
  16. package/dist_ts/smartagent.interfaces.js +8 -0
  17. package/dist_ts/smartagent.tools.base.d.ts +46 -0
  18. package/dist_ts/smartagent.tools.base.js +45 -0
  19. package/dist_ts/smartagent.tools.browser.d.ts +16 -0
  20. package/dist_ts/smartagent.tools.browser.js +177 -0
  21. package/dist_ts/smartagent.tools.filesystem.d.ts +16 -0
  22. package/dist_ts/smartagent.tools.filesystem.js +352 -0
  23. package/dist_ts/smartagent.tools.http.d.ts +15 -0
  24. package/dist_ts/smartagent.tools.http.js +187 -0
  25. package/dist_ts/smartagent.tools.shell.d.ts +16 -0
  26. package/dist_ts/smartagent.tools.shell.js +155 -0
  27. package/npmextra.json +18 -0
  28. package/package.json +50 -0
  29. package/readme.hints.md +16 -0
  30. package/readme.md +299 -0
  31. package/ts/00_commitinfo_data.ts +8 -0
  32. package/ts/index.ts +29 -0
  33. package/ts/plugins.ts +14 -0
  34. package/ts/smartagent.classes.driveragent.ts +321 -0
  35. package/ts/smartagent.classes.dualagent.ts +350 -0
  36. package/ts/smartagent.classes.guardianagent.ts +241 -0
  37. package/ts/smartagent.interfaces.ts +210 -0
  38. package/ts/smartagent.tools.base.ts +80 -0
  39. package/ts/smartagent.tools.browser.ts +200 -0
  40. package/ts/smartagent.tools.filesystem.ts +379 -0
  41. package/ts/smartagent.tools.http.ts +205 -0
  42. package/ts/smartagent.tools.shell.ts +182 -0
package/readme.md ADDED
@@ -0,0 +1,299 @@
1
+ # @push.rocks/smartagent
2
+ A dual-agent agentic framework with Driver and Guardian agents for safe, policy-controlled AI task execution.
3
+
4
+ ## Install
5
+ ```bash
6
+ npm install @push.rocks/smartagent
7
+ # or
8
+ pnpm install @push.rocks/smartagent
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ SmartAgent implements a dual-agent architecture:
14
+
15
+ - **Driver Agent**: Executes tasks, reasons about goals, and proposes tool calls
16
+ - **Guardian Agent**: Evaluates tool call proposals against a policy prompt, approving or rejecting with feedback
17
+
18
+ This design ensures safe tool use through AI-based policy evaluation rather than rigid programmatic rules.
19
+
20
+ ## Architecture
21
+
22
+ ```
23
+ User Task + Guardian Policy Prompt
24
+ |
25
+ +---------------------------------------+
26
+ | DualAgentOrchestrator |
27
+ | |
28
+ | +--------+ +------------+ |
29
+ | | Driver |-------> | Guardian | |
30
+ | | Agent | tool | Agent | |
31
+ | | | call | | |
32
+ | | Reason |<--------| Evaluate | |
33
+ | | + Plan | approve | against | |
34
+ | +--------+ /reject | policy | |
35
+ | | +feedback+-----------+ |
36
+ | v (if approved) |
37
+ | +-----------------------------------+|
38
+ | | Standard Tools ||
39
+ | | Filesystem | HTTP | Shell | Browser|
40
+ | +-----------------------------------+|
41
+ +---------------------------------------+
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ ```typescript
47
+ import { DualAgentOrchestrator } from '@push.rocks/smartagent';
48
+
49
+ // Create orchestrator with Guardian policy
50
+ const orchestrator = new DualAgentOrchestrator({
51
+ openaiToken: 'sk-...',
52
+ defaultProvider: 'openai',
53
+ guardianPolicyPrompt: `
54
+ FILE SYSTEM POLICY:
55
+ - ONLY allow reading/writing within /tmp or the current working directory
56
+ - REJECT operations on system directories or sensitive files
57
+
58
+ SHELL POLICY:
59
+ - Allow read-only commands (ls, cat, grep, echo)
60
+ - REJECT destructive commands (rm, mv, chmod) without explicit justification
61
+
62
+ FLAG any attempt to expose secrets or credentials.
63
+ `,
64
+ });
65
+
66
+ // Register standard tools
67
+ orchestrator.registerStandardTools();
68
+
69
+ // Start the orchestrator (initializes all tools)
70
+ await orchestrator.start();
71
+
72
+ // Run a task
73
+ const result = await orchestrator.run('List all TypeScript files in the current directory');
74
+
75
+ console.log('Success:', result.success);
76
+ console.log('Result:', result.result);
77
+ console.log('Iterations:', result.iterations);
78
+
79
+ // Cleanup
80
+ await orchestrator.stop();
81
+ ```
82
+
83
+ ## Standard Tools
84
+
85
+ ### FilesystemTool
86
+ File and directory operations using `@push.rocks/smartfs`.
87
+
88
+ **Actions**: `read`, `write`, `append`, `list`, `delete`, `exists`, `stat`, `copy`, `move`, `mkdir`
89
+
90
+ ```typescript
91
+ // Example tool call by Driver
92
+ <tool_call>
93
+ <tool>filesystem</tool>
94
+ <action>read</action>
95
+ <params>{"path": "/tmp/config.json"}</params>
96
+ <reasoning>Need to read the configuration file to understand the settings</reasoning>
97
+ </tool_call>
98
+ ```
99
+
100
+ ### HttpTool
101
+ HTTP requests using `@push.rocks/smartrequest`.
102
+
103
+ **Actions**: `get`, `post`, `put`, `patch`, `delete`
104
+
105
+ ```typescript
106
+ <tool_call>
107
+ <tool>http</tool>
108
+ <action>get</action>
109
+ <params>{"url": "https://api.example.com/data"}</params>
110
+ <reasoning>Fetching data from the API endpoint</reasoning>
111
+ </tool_call>
112
+ ```
113
+
114
+ ### ShellTool
115
+ Secure shell command execution using `@push.rocks/smartshell` with `execSpawn` (no shell injection).
116
+
117
+ **Actions**: `execute`, `which`
118
+
119
+ ```typescript
120
+ <tool_call>
121
+ <tool>shell</tool>
122
+ <action>execute</action>
123
+ <params>{"command": "ls", "args": ["-la", "/tmp"]}</params>
124
+ <reasoning>Listing directory contents to find relevant files</reasoning>
125
+ </tool_call>
126
+ ```
127
+
128
+ ### BrowserTool
129
+ Web page interaction using `@push.rocks/smartbrowser` (Puppeteer-based).
130
+
131
+ **Actions**: `screenshot`, `pdf`, `evaluate`, `getPageContent`
132
+
133
+ ```typescript
134
+ <tool_call>
135
+ <tool>browser</tool>
136
+ <action>getPageContent</action>
137
+ <params>{"url": "https://example.com"}</params>
138
+ <reasoning>Extracting text content from the webpage</reasoning>
139
+ </tool_call>
140
+ ```
141
+
142
+ ## Guardian Policy Examples
143
+
144
+ ### Strict Security Policy
145
+ ```typescript
146
+ const securityPolicy = `
147
+ SECURITY POLICY:
148
+ 1. REJECT any file operations outside /home/user/workspace
149
+ 2. REJECT any shell commands that could modify system state
150
+ 3. REJECT any HTTP requests to internal/private IP ranges
151
+ 4. REJECT any attempts to read environment variables or credentials
152
+ 5. FLAG and REJECT obfuscated code execution
153
+
154
+ When rejecting, always explain:
155
+ - What policy was violated
156
+ - What would be a safer alternative
157
+ `;
158
+ ```
159
+
160
+ ### Development Environment Policy
161
+ ```typescript
162
+ const devPolicy = `
163
+ DEVELOPMENT POLICY:
164
+ - Allow file operations only within the project directory
165
+ - Allow npm/pnpm commands for package management
166
+ - Allow git commands for version control
167
+ - Allow HTTP requests to public APIs only
168
+ - REJECT direct database modifications
169
+ - REJECT commands that could affect other users
170
+
171
+ Always verify:
172
+ - File paths are relative or within project bounds
173
+ - Commands don't have dangerous flags (--force, -rf)
174
+ `;
175
+ ```
176
+
177
+ ## Configuration Options
178
+
179
+ ```typescript
180
+ interface IDualAgentOptions {
181
+ // Provider tokens (from @push.rocks/smartai)
182
+ openaiToken?: string;
183
+ anthropicToken?: string;
184
+ perplexityToken?: string;
185
+ groqToken?: string;
186
+ xaiToken?: string;
187
+
188
+ // Provider selection
189
+ defaultProvider?: TProvider; // For both Driver and Guardian
190
+ guardianProvider?: TProvider; // Optional: separate provider for Guardian
191
+
192
+ // Agent configuration
193
+ driverSystemMessage?: string; // Custom system message for Driver
194
+ guardianPolicyPrompt: string; // REQUIRED: Policy for Guardian to enforce
195
+
196
+ // Limits
197
+ maxIterations?: number; // Max task iterations (default: 20)
198
+ maxConsecutiveRejections?: number; // Abort after N rejections (default: 3)
199
+ }
200
+ ```
201
+
202
+ ## Result Interface
203
+
204
+ ```typescript
205
+ interface IDualAgentRunResult {
206
+ success: boolean; // Whether task completed successfully
207
+ completed: boolean; // Task completion status
208
+ result: string; // Final result or response
209
+ iterations: number; // Number of iterations taken
210
+ history: IAgentMessage[]; // Full conversation history
211
+ status: TDualAgentRunStatus; // 'completed' | 'max_iterations_reached' | etc.
212
+ }
213
+ ```
214
+
215
+ ## Custom Tools
216
+
217
+ Create custom tools by extending `BaseToolWrapper`:
218
+
219
+ ```typescript
220
+ import { BaseToolWrapper, IToolAction, IToolExecutionResult } from '@push.rocks/smartagent';
221
+
222
+ class MyCustomTool extends BaseToolWrapper {
223
+ public name = 'custom';
224
+ public description = 'My custom tool for specific operations';
225
+
226
+ public actions: IToolAction[] = [
227
+ {
228
+ name: 'myAction',
229
+ description: 'Performs a custom action',
230
+ parameters: {
231
+ type: 'object',
232
+ properties: {
233
+ input: { type: 'string', description: 'Input for the action' },
234
+ },
235
+ required: ['input'],
236
+ },
237
+ },
238
+ ];
239
+
240
+ public async initialize(): Promise<void> {
241
+ this.isInitialized = true;
242
+ }
243
+
244
+ public async cleanup(): Promise<void> {
245
+ this.isInitialized = false;
246
+ }
247
+
248
+ public async execute(action: string, params: Record<string, unknown>): Promise<IToolExecutionResult> {
249
+ this.validateAction(action);
250
+ this.ensureInitialized();
251
+
252
+ if (action === 'myAction') {
253
+ return {
254
+ success: true,
255
+ result: { processed: params.input },
256
+ };
257
+ }
258
+
259
+ return { success: false, error: 'Unknown action' };
260
+ }
261
+
262
+ public getCallSummary(action: string, params: Record<string, unknown>): string {
263
+ return `Custom action "${action}" with input "${params.input}"`;
264
+ }
265
+ }
266
+
267
+ // Register custom tool
268
+ orchestrator.registerTool(new MyCustomTool());
269
+ ```
270
+
271
+ ## Supported Providers
272
+
273
+ | Provider | Driver | Guardian |
274
+ |----------|:------:|:--------:|
275
+ | OpenAI | Yes | Yes |
276
+ | Anthropic | Yes | Yes |
277
+ | Perplexity | Yes | Yes |
278
+ | Groq | Yes | Yes |
279
+ | Ollama | Yes | Yes |
280
+ | XAI | Yes | Yes |
281
+
282
+ ## License and Legal Information
283
+
284
+ This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
285
+
286
+ **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
287
+
288
+ ### Trademarks
289
+
290
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
291
+
292
+ ### Company Information
293
+
294
+ Task Venture Capital GmbH
295
+ Registered at District court Bremen HRB 35230 HB, Germany
296
+
297
+ For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
298
+
299
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export const commitinfo = {
5
+ name: '@push.rocks/smartagent',
6
+ version: '1.0.2',
7
+ description: 'an agentic framework built on top of @push.rocks/smartai'
8
+ }
package/ts/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ import * as plugins from './plugins.js';
2
+
3
+ // Export the dual-agent orchestrator (main entry point)
4
+ export { DualAgentOrchestrator } from './smartagent.classes.dualagent.js';
5
+
6
+ // Export individual agents
7
+ export { DriverAgent } from './smartagent.classes.driveragent.js';
8
+ export { GuardianAgent } from './smartagent.classes.guardianagent.js';
9
+
10
+ // Export base tool class for custom tool creation
11
+ export { BaseToolWrapper } from './smartagent.tools.base.js';
12
+
13
+ // Export standard tools
14
+ export { FilesystemTool } from './smartagent.tools.filesystem.js';
15
+ export { HttpTool } from './smartagent.tools.http.js';
16
+ export { ShellTool } from './smartagent.tools.shell.js';
17
+ export { BrowserTool } from './smartagent.tools.browser.js';
18
+
19
+ // Export all interfaces
20
+ export * from './smartagent.interfaces.js';
21
+
22
+ // Re-export useful types from smartai
23
+ export {
24
+ type ISmartAiOptions,
25
+ type TProvider,
26
+ type ChatMessage,
27
+ type ChatOptions,
28
+ type ChatResponse,
29
+ } from '@push.rocks/smartai';
package/ts/plugins.ts ADDED
@@ -0,0 +1,14 @@
1
+ // @push.rocks scope
2
+ import * as smartai from '@push.rocks/smartai';
3
+ import * as smartfs from '@push.rocks/smartfs';
4
+ import * as smartrequest from '@push.rocks/smartrequest';
5
+ import * as smartbrowser from '@push.rocks/smartbrowser';
6
+ import * as smartshell from '@push.rocks/smartshell';
7
+
8
+ export {
9
+ smartai,
10
+ smartfs,
11
+ smartrequest,
12
+ smartbrowser,
13
+ smartshell,
14
+ };
@@ -0,0 +1,321 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as interfaces from './smartagent.interfaces.js';
3
+ import type { BaseToolWrapper } from './smartagent.tools.base.js';
4
+
5
+ /**
6
+ * DriverAgent - Executes tasks by reasoning and proposing tool calls
7
+ * Works in conjunction with GuardianAgent for approval
8
+ */
9
+ export class DriverAgent {
10
+ private provider: plugins.smartai.MultiModalModel;
11
+ private systemMessage: string;
12
+ private messageHistory: plugins.smartai.ChatMessage[] = [];
13
+ private tools: Map<string, BaseToolWrapper> = new Map();
14
+
15
+ constructor(
16
+ provider: plugins.smartai.MultiModalModel,
17
+ systemMessage?: string
18
+ ) {
19
+ this.provider = provider;
20
+ this.systemMessage = systemMessage || this.getDefaultSystemMessage();
21
+ }
22
+
23
+ /**
24
+ * Register a tool for use by the driver
25
+ */
26
+ public registerTool(tool: BaseToolWrapper): void {
27
+ this.tools.set(tool.name, tool);
28
+ }
29
+
30
+ /**
31
+ * Get all registered tools
32
+ */
33
+ public getTools(): Map<string, BaseToolWrapper> {
34
+ return this.tools;
35
+ }
36
+
37
+ /**
38
+ * Initialize a new conversation for a task
39
+ */
40
+ public async startTask(task: string): Promise<interfaces.IAgentMessage> {
41
+ // Reset message history
42
+ this.messageHistory = [];
43
+
44
+ // Build the user message
45
+ const userMessage = `TASK: ${task}\n\nAnalyze this task and determine what actions are needed. If you need to use a tool, provide a tool call proposal.`;
46
+
47
+ // Add to history
48
+ this.messageHistory.push({
49
+ role: 'user',
50
+ content: userMessage,
51
+ });
52
+
53
+ // Build tool descriptions for the system message
54
+ const toolDescriptions = this.buildToolDescriptions();
55
+ const fullSystemMessage = `${this.systemMessage}\n\n## Available Tools\n${toolDescriptions}`;
56
+
57
+ // Get response from provider
58
+ const response = await this.provider.chat({
59
+ systemMessage: fullSystemMessage,
60
+ userMessage: userMessage,
61
+ messageHistory: [],
62
+ });
63
+
64
+ // Add assistant response to history
65
+ this.messageHistory.push({
66
+ role: 'assistant',
67
+ content: response.message,
68
+ });
69
+
70
+ return {
71
+ role: 'assistant',
72
+ content: response.message,
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Continue the conversation with feedback or results
78
+ */
79
+ public async continueWithMessage(message: string): Promise<interfaces.IAgentMessage> {
80
+ // Add the new message to history
81
+ this.messageHistory.push({
82
+ role: 'user',
83
+ content: message,
84
+ });
85
+
86
+ // Build tool descriptions for the system message
87
+ const toolDescriptions = this.buildToolDescriptions();
88
+ const fullSystemMessage = `${this.systemMessage}\n\n## Available Tools\n${toolDescriptions}`;
89
+
90
+ // Get response from provider (pass all but last user message as history)
91
+ const historyForChat = this.messageHistory.slice(0, -1);
92
+
93
+ const response = await this.provider.chat({
94
+ systemMessage: fullSystemMessage,
95
+ userMessage: message,
96
+ messageHistory: historyForChat,
97
+ });
98
+
99
+ // Add assistant response to history
100
+ this.messageHistory.push({
101
+ role: 'assistant',
102
+ content: response.message,
103
+ });
104
+
105
+ return {
106
+ role: 'assistant',
107
+ content: response.message,
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Parse tool call proposals from assistant response
113
+ */
114
+ public parseToolCallProposals(response: string): interfaces.IToolCallProposal[] {
115
+ const proposals: interfaces.IToolCallProposal[] = [];
116
+
117
+ // Match <tool_call>...</tool_call> blocks
118
+ const toolCallRegex = /<tool_call>([\s\S]*?)<\/tool_call>/g;
119
+ let match;
120
+
121
+ while ((match = toolCallRegex.exec(response)) !== null) {
122
+ const content = match[1];
123
+
124
+ try {
125
+ const proposal = this.parseToolCallContent(content);
126
+ if (proposal) {
127
+ proposals.push(proposal);
128
+ }
129
+ } catch (error) {
130
+ // Skip malformed tool calls
131
+ console.warn('Failed to parse tool call:', error);
132
+ }
133
+ }
134
+
135
+ return proposals;
136
+ }
137
+
138
+ /**
139
+ * Parse the content inside a tool_call block
140
+ */
141
+ private parseToolCallContent(content: string): interfaces.IToolCallProposal | null {
142
+ // Extract tool name
143
+ const toolMatch = content.match(/<tool>(.*?)<\/tool>/s);
144
+ if (!toolMatch) return null;
145
+ const toolName = toolMatch[1].trim();
146
+
147
+ // Extract action
148
+ const actionMatch = content.match(/<action>(.*?)<\/action>/s);
149
+ if (!actionMatch) return null;
150
+ const action = actionMatch[1].trim();
151
+
152
+ // Extract params (JSON)
153
+ const paramsMatch = content.match(/<params>([\s\S]*?)<\/params>/);
154
+ let params: Record<string, unknown> = {};
155
+ if (paramsMatch) {
156
+ try {
157
+ params = JSON.parse(paramsMatch[1].trim());
158
+ } catch {
159
+ // Try to extract individual parameters if JSON fails
160
+ params = this.extractParamsFromXml(paramsMatch[1]);
161
+ }
162
+ }
163
+
164
+ // Extract reasoning (optional)
165
+ const reasoningMatch = content.match(/<reasoning>([\s\S]*?)<\/reasoning>/);
166
+ const reasoning = reasoningMatch ? reasoningMatch[1].trim() : undefined;
167
+
168
+ return {
169
+ proposalId: this.generateProposalId(),
170
+ toolName,
171
+ action,
172
+ params,
173
+ reasoning,
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Extract parameters from XML-like format when JSON parsing fails
179
+ */
180
+ private extractParamsFromXml(content: string): Record<string, unknown> {
181
+ const params: Record<string, unknown> = {};
182
+ const paramRegex = /<(\w+)>([\s\S]*?)<\/\1>/g;
183
+ let match;
184
+
185
+ while ((match = paramRegex.exec(content)) !== null) {
186
+ const key = match[1];
187
+ let value: unknown = match[2].trim();
188
+
189
+ // Try to parse as JSON for arrays/objects
190
+ try {
191
+ value = JSON.parse(value as string);
192
+ } catch {
193
+ // Keep as string if not valid JSON
194
+ }
195
+
196
+ params[key] = value;
197
+ }
198
+
199
+ return params;
200
+ }
201
+
202
+ /**
203
+ * Check if the response indicates task completion
204
+ */
205
+ public isTaskComplete(response: string): boolean {
206
+ // Check for explicit completion markers
207
+ const completionMarkers = [
208
+ '<task_complete>',
209
+ '<task_completed>',
210
+ 'TASK COMPLETE',
211
+ 'Task completed successfully',
212
+ ];
213
+
214
+ const lowerResponse = response.toLowerCase();
215
+ return completionMarkers.some(marker =>
216
+ lowerResponse.includes(marker.toLowerCase())
217
+ );
218
+ }
219
+
220
+ /**
221
+ * Check if the response needs clarification or user input
222
+ */
223
+ public needsClarification(response: string): boolean {
224
+ const clarificationMarkers = [
225
+ '<needs_clarification>',
226
+ '<question>',
227
+ 'please clarify',
228
+ 'could you specify',
229
+ 'what do you mean by',
230
+ ];
231
+
232
+ const lowerResponse = response.toLowerCase();
233
+ return clarificationMarkers.some(marker =>
234
+ lowerResponse.includes(marker.toLowerCase())
235
+ );
236
+ }
237
+
238
+ /**
239
+ * Extract the final result from a completed task
240
+ */
241
+ public extractTaskResult(response: string): string | null {
242
+ // Try to extract from result tags
243
+ const resultMatch = response.match(/<task_result>([\s\S]*?)<\/task_result>/);
244
+ if (resultMatch) {
245
+ return resultMatch[1].trim();
246
+ }
247
+
248
+ const completeMatch = response.match(/<task_complete>([\s\S]*?)<\/task_complete>/);
249
+ if (completeMatch) {
250
+ return completeMatch[1].trim();
251
+ }
252
+
253
+ return null;
254
+ }
255
+
256
+ /**
257
+ * Build tool descriptions for the system message
258
+ */
259
+ private buildToolDescriptions(): string {
260
+ const descriptions: string[] = [];
261
+
262
+ for (const tool of this.tools.values()) {
263
+ descriptions.push(tool.getFullDescription());
264
+ }
265
+
266
+ return descriptions.join('\n\n');
267
+ }
268
+
269
+ /**
270
+ * Generate a unique proposal ID
271
+ */
272
+ private generateProposalId(): string {
273
+ return `prop_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
274
+ }
275
+
276
+ /**
277
+ * Get the default system message for the driver
278
+ */
279
+ private getDefaultSystemMessage(): string {
280
+ return `You are an AI assistant that executes tasks by using available tools.
281
+
282
+ ## Your Role
283
+ You analyze tasks, break them down into steps, and use tools to accomplish goals.
284
+
285
+ ## Tool Usage Format
286
+ When you need to use a tool, output a tool call proposal in this format:
287
+
288
+ <tool_call>
289
+ <tool>tool_name</tool>
290
+ <action>action_name</action>
291
+ <params>
292
+ {"param1": "value1", "param2": "value2"}
293
+ </params>
294
+ <reasoning>Brief explanation of why this action is needed</reasoning>
295
+ </tool_call>
296
+
297
+ ## Guidelines
298
+ 1. Think step by step about what needs to be done
299
+ 2. Use only the tools that are available to you
300
+ 3. Provide clear reasoning for each tool call
301
+ 4. If a tool call is rejected, adapt your approach based on the feedback
302
+ 5. When the task is complete, indicate this clearly:
303
+
304
+ <task_complete>
305
+ Brief summary of what was accomplished
306
+ </task_complete>
307
+
308
+ ## Important
309
+ - Only propose ONE tool call at a time
310
+ - Wait for the result before proposing the next action
311
+ - If you encounter an error, analyze it and try an alternative approach
312
+ - If you need clarification, ask using <needs_clarification>your question</needs_clarification>`;
313
+ }
314
+
315
+ /**
316
+ * Reset the conversation state
317
+ */
318
+ public reset(): void {
319
+ this.messageHistory = [];
320
+ }
321
+ }