@push.rocks/smartagent 1.7.0 → 1.8.0
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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +6 -1
- package/dist_ts/smartagent.classes.dualagent.d.ts +17 -3
- package/dist_ts/smartagent.classes.dualagent.js +57 -26
- package/dist_ts/smartagent.classes.toolregistry.d.ts +75 -0
- package/dist_ts/smartagent.classes.toolregistry.js +161 -0
- package/dist_ts/smartagent.interfaces.d.ts +52 -0
- package/dist_ts/smartagent.interfaces.js +1 -1
- package/dist_ts/smartagent.tools.expert.d.ts +27 -0
- package/dist_ts/smartagent.tools.expert.js +126 -0
- package/dist_ts/smartagent.tools.search.d.ts +29 -0
- package/dist_ts/smartagent.tools.search.js +215 -0
- package/package.json +1 -1
- package/readme.hints.md +47 -0
- package/readme.md +167 -8
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +7 -0
- package/ts/smartagent.classes.dualagent.ts +63 -28
- package/ts/smartagent.classes.toolregistry.ts +188 -0
- package/ts/smartagent.interfaces.ts +60 -0
- package/ts/smartagent.tools.expert.ts +144 -0
- package/ts/smartagent.tools.search.ts +237 -0
package/readme.md
CHANGED
|
@@ -37,19 +37,19 @@ flowchart TB
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
subgraph Orchestrator["DualAgentOrchestrator"]
|
|
40
|
+
Registry["ToolRegistry<br/><i>Visibility & Lifecycle</i>"]
|
|
40
41
|
Driver["Driver Agent<br/><i>Reason + Plan</i>"]
|
|
41
42
|
Guardian["Guardian Agent<br/><i>Evaluate against policy</i>"]
|
|
42
43
|
|
|
43
44
|
Driver -->|"tool call proposal"| Guardian
|
|
44
45
|
Guardian -->|"approve / reject + feedback"| Driver
|
|
46
|
+
Registry -->|"visible tools"| Driver
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
subgraph Tools["
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Browser["Browser"]
|
|
52
|
-
Deno["Deno"]
|
|
49
|
+
subgraph Tools["Tools"]
|
|
50
|
+
Initial["Initial Tools<br/><i>Always visible</i>"]
|
|
51
|
+
OnDemand["On-Demand Tools<br/><i>Discoverable via search</i>"]
|
|
52
|
+
Experts["Expert SubAgents<br/><i>Specialized agents as tools</i>"]
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
Task --> Orchestrator
|
|
@@ -266,6 +266,157 @@ orchestrator.registerTool(new JsonValidatorTool());
|
|
|
266
266
|
</tool_call>
|
|
267
267
|
```
|
|
268
268
|
|
|
269
|
+
### 🔍 ToolSearchTool
|
|
270
|
+
|
|
271
|
+
Enable the Driver to discover and activate on-demand tools at runtime.
|
|
272
|
+
|
|
273
|
+
**Actions**: `search`, `list`, `activate`, `details`
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// Enable tool search (adds the 'tools' tool)
|
|
277
|
+
orchestrator.enableToolSearch();
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// Search for tools by capability
|
|
282
|
+
<tool_call>
|
|
283
|
+
<tool>tools</tool>
|
|
284
|
+
<action>search</action>
|
|
285
|
+
<params>{"query": "database"}</params>
|
|
286
|
+
</tool_call>
|
|
287
|
+
|
|
288
|
+
// List all available tools
|
|
289
|
+
<tool_call>
|
|
290
|
+
<tool>tools</tool>
|
|
291
|
+
<action>list</action>
|
|
292
|
+
<params>{}</params>
|
|
293
|
+
</tool_call>
|
|
294
|
+
|
|
295
|
+
// Activate an on-demand tool
|
|
296
|
+
<tool_call>
|
|
297
|
+
<tool>tools</tool>
|
|
298
|
+
<action>activate</action>
|
|
299
|
+
<params>{"name": "database_expert"}</params>
|
|
300
|
+
</tool_call>
|
|
301
|
+
|
|
302
|
+
// Get detailed information about a tool
|
|
303
|
+
<tool_call>
|
|
304
|
+
<tool>tools</tool>
|
|
305
|
+
<action>details</action>
|
|
306
|
+
<params>{"name": "filesystem"}</params>
|
|
307
|
+
</tool_call>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### 🧠 ExpertTool (SubAgents)
|
|
311
|
+
|
|
312
|
+
Create specialized sub-agents that can be invoked as tools. Experts are complete `DualAgentOrchestrator` instances wrapped as tools, enabling hierarchical agent architectures.
|
|
313
|
+
|
|
314
|
+
**Actions**: `consult`
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// Register an expert for code review
|
|
318
|
+
orchestrator.registerExpert({
|
|
319
|
+
name: 'code_reviewer',
|
|
320
|
+
description: 'Reviews code for quality, bugs, and best practices',
|
|
321
|
+
systemMessage: `You are an expert code reviewer. Analyze code for:
|
|
322
|
+
- Bugs and potential issues
|
|
323
|
+
- Code style and best practices
|
|
324
|
+
- Performance concerns
|
|
325
|
+
- Security vulnerabilities`,
|
|
326
|
+
guardianPolicy: 'Allow read-only file access within the workspace',
|
|
327
|
+
tools: [new FilesystemTool()],
|
|
328
|
+
visibility: 'on-demand', // Only available via tool search
|
|
329
|
+
tags: ['code', 'review', 'quality'],
|
|
330
|
+
category: 'expert',
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// Consult an expert
|
|
336
|
+
<tool_call>
|
|
337
|
+
<tool>code_reviewer</tool>
|
|
338
|
+
<action>consult</action>
|
|
339
|
+
<params>{
|
|
340
|
+
"task": "Review this function for potential issues",
|
|
341
|
+
"context": "This is a user authentication handler"
|
|
342
|
+
}</params>
|
|
343
|
+
</tool_call>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## 🎯 Tool Visibility System
|
|
347
|
+
|
|
348
|
+
SmartAgent supports **tool visibility modes** for scalable agent architectures:
|
|
349
|
+
|
|
350
|
+
- **`initial`** (default): Tool is visible to the Driver from the start, included in the system prompt
|
|
351
|
+
- **`on-demand`**: Tool is hidden until explicitly activated via `tools.activate()`
|
|
352
|
+
|
|
353
|
+
This enables you to have many specialized tools/experts without overwhelming the Driver's context.
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
// Register a tool with on-demand visibility
|
|
357
|
+
orchestrator.registerTool(new MySpecializedTool(), {
|
|
358
|
+
visibility: 'on-demand',
|
|
359
|
+
tags: ['specialized', 'database'],
|
|
360
|
+
category: 'data',
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// Enable tool search so Driver can discover and activate on-demand tools
|
|
364
|
+
orchestrator.enableToolSearch();
|
|
365
|
+
|
|
366
|
+
// The Driver can now:
|
|
367
|
+
// 1. tools.search({"query": "database"}) -> finds MySpecializedTool
|
|
368
|
+
// 2. tools.activate({"name": "myspecialized"}) -> enables it
|
|
369
|
+
// 3. myspecialized.action({...}) -> use the tool
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Expert SubAgent Example
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
const orchestrator = new DualAgentOrchestrator({
|
|
376
|
+
openaiToken: 'sk-...',
|
|
377
|
+
defaultProvider: 'openai',
|
|
378
|
+
guardianPolicyPrompt: 'Allow safe operations...',
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
orchestrator.registerStandardTools();
|
|
382
|
+
orchestrator.enableToolSearch();
|
|
383
|
+
|
|
384
|
+
// Initial expert (always visible)
|
|
385
|
+
orchestrator.registerExpert({
|
|
386
|
+
name: 'code_assistant',
|
|
387
|
+
description: 'Helps with coding tasks and code generation',
|
|
388
|
+
systemMessage: 'You are a helpful coding assistant...',
|
|
389
|
+
guardianPolicy: 'Allow read-only file access',
|
|
390
|
+
tools: [new FilesystemTool()],
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// On-demand experts (discoverable via search)
|
|
394
|
+
orchestrator.registerExpert({
|
|
395
|
+
name: 'database_expert',
|
|
396
|
+
description: 'Database design, optimization, and query analysis',
|
|
397
|
+
systemMessage: 'You are a database expert...',
|
|
398
|
+
guardianPolicy: 'Allow read-only operations',
|
|
399
|
+
visibility: 'on-demand',
|
|
400
|
+
tags: ['database', 'sql', 'optimization'],
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
orchestrator.registerExpert({
|
|
404
|
+
name: 'security_auditor',
|
|
405
|
+
description: 'Security vulnerability assessment and best practices',
|
|
406
|
+
systemMessage: 'You are a security expert...',
|
|
407
|
+
guardianPolicy: 'Allow read-only file access',
|
|
408
|
+
visibility: 'on-demand',
|
|
409
|
+
tags: ['security', 'audit', 'vulnerabilities'],
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
await orchestrator.start();
|
|
413
|
+
|
|
414
|
+
// Now the Driver can:
|
|
415
|
+
// - Use code_assistant directly
|
|
416
|
+
// - Search for "database" and activate database_expert when needed
|
|
417
|
+
// - Search for "security" and activate security_auditor when needed
|
|
418
|
+
```
|
|
419
|
+
|
|
269
420
|
## 🎥 Streaming Support
|
|
270
421
|
|
|
271
422
|
SmartAgent supports token-by-token streaming for real-time output during LLM generation:
|
|
@@ -608,12 +759,15 @@ const orchestrator = new DualAgentOrchestrator({
|
|
|
608
759
|
| `stop()` | Cleanup all tools and resources |
|
|
609
760
|
| `run(task, options?)` | Execute a task with optional images for vision |
|
|
610
761
|
| `continueTask(input)` | Continue a task with user input |
|
|
611
|
-
| `registerTool(tool)` | Register a custom tool |
|
|
762
|
+
| `registerTool(tool, options?)` | Register a custom tool with optional visibility settings |
|
|
612
763
|
| `registerStandardTools()` | Register all built-in tools (Filesystem, HTTP, Shell, Browser, Deno) |
|
|
613
764
|
| `registerScopedFilesystemTool(basePath, excludePatterns?)` | Register filesystem tool with path restriction |
|
|
765
|
+
| `registerExpert(config)` | Register a specialized sub-agent as a tool |
|
|
766
|
+
| `enableToolSearch()` | Enable tool discovery and activation for the Driver |
|
|
614
767
|
| `setGuardianPolicy(policy)` | Update Guardian policy at runtime |
|
|
615
768
|
| `getHistory()` | Get conversation history |
|
|
616
769
|
| `getToolNames()` | Get list of registered tool names |
|
|
770
|
+
| `getRegistry()` | Get the ToolRegistry for advanced operations |
|
|
617
771
|
| `isActive()` | Check if orchestrator is running |
|
|
618
772
|
|
|
619
773
|
### Exports
|
|
@@ -624,6 +778,9 @@ export { DualAgentOrchestrator } from '@push.rocks/smartagent';
|
|
|
624
778
|
export { DriverAgent } from '@push.rocks/smartagent';
|
|
625
779
|
export { GuardianAgent } from '@push.rocks/smartagent';
|
|
626
780
|
|
|
781
|
+
// Tool Registry
|
|
782
|
+
export { ToolRegistry } from '@push.rocks/smartagent';
|
|
783
|
+
|
|
627
784
|
// Tools
|
|
628
785
|
export { BaseToolWrapper } from '@push.rocks/smartagent';
|
|
629
786
|
export { FilesystemTool, type IFilesystemToolOptions } from '@push.rocks/smartagent';
|
|
@@ -632,9 +789,11 @@ export { ShellTool } from '@push.rocks/smartagent';
|
|
|
632
789
|
export { BrowserTool } from '@push.rocks/smartagent';
|
|
633
790
|
export { DenoTool, type TDenoPermission } from '@push.rocks/smartagent';
|
|
634
791
|
export { JsonValidatorTool } from '@push.rocks/smartagent';
|
|
792
|
+
export { ToolSearchTool } from '@push.rocks/smartagent';
|
|
793
|
+
export { ExpertTool } from '@push.rocks/smartagent';
|
|
635
794
|
|
|
636
795
|
// Types and interfaces
|
|
637
|
-
export * from '@push.rocks/smartagent'; // All interfaces
|
|
796
|
+
export * from '@push.rocks/smartagent'; // All interfaces (IExpertConfig, IToolMetadata, etc.)
|
|
638
797
|
|
|
639
798
|
// Re-exported from @push.rocks/smartai
|
|
640
799
|
export { type ISmartAiOptions, type TProvider, type ChatMessage, type ChatOptions, type ChatResponse };
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/index.ts
CHANGED
|
@@ -7,6 +7,9 @@ export { DualAgentOrchestrator } from './smartagent.classes.dualagent.js';
|
|
|
7
7
|
export { DriverAgent } from './smartagent.classes.driveragent.js';
|
|
8
8
|
export { GuardianAgent } from './smartagent.classes.guardianagent.js';
|
|
9
9
|
|
|
10
|
+
// Export tool registry and related classes
|
|
11
|
+
export { ToolRegistry } from './smartagent.classes.toolregistry.js';
|
|
12
|
+
|
|
10
13
|
// Export base tool class for custom tool creation
|
|
11
14
|
export { BaseToolWrapper } from './smartagent.tools.base.js';
|
|
12
15
|
|
|
@@ -18,6 +21,10 @@ export { BrowserTool } from './smartagent.tools.browser.js';
|
|
|
18
21
|
export { DenoTool, type TDenoPermission } from './smartagent.tools.deno.js';
|
|
19
22
|
export { JsonValidatorTool } from './smartagent.tools.json.js';
|
|
20
23
|
|
|
24
|
+
// Export tool search and expert tools
|
|
25
|
+
export { ToolSearchTool } from './smartagent.tools.search.js';
|
|
26
|
+
export { ExpertTool } from './smartagent.tools.expert.js';
|
|
27
|
+
|
|
21
28
|
// Export all interfaces
|
|
22
29
|
export * from './smartagent.interfaces.js';
|
|
23
30
|
|
|
@@ -8,6 +8,9 @@ import { HttpTool } from './smartagent.tools.http.js';
|
|
|
8
8
|
import { ShellTool } from './smartagent.tools.shell.js';
|
|
9
9
|
import { BrowserTool } from './smartagent.tools.browser.js';
|
|
10
10
|
import { DenoTool } from './smartagent.tools.deno.js';
|
|
11
|
+
import { ToolRegistry } from './smartagent.classes.toolregistry.js';
|
|
12
|
+
import { ToolSearchTool } from './smartagent.tools.search.js';
|
|
13
|
+
import { ExpertTool } from './smartagent.tools.expert.js';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* DualAgentOrchestrator - Coordinates Driver and Guardian agents
|
|
@@ -20,7 +23,7 @@ export class DualAgentOrchestrator {
|
|
|
20
23
|
private guardianProvider: plugins.smartai.MultiModalModel;
|
|
21
24
|
private driver: DriverAgent;
|
|
22
25
|
private guardian: GuardianAgent;
|
|
23
|
-
private
|
|
26
|
+
private registry: ToolRegistry = new ToolRegistry();
|
|
24
27
|
private isRunning = false;
|
|
25
28
|
private conversationHistory: interfaces.IAgentMessage[] = [];
|
|
26
29
|
private ownsSmartAi = true; // true if we created the SmartAi instance, false if it was provided
|
|
@@ -125,19 +128,55 @@ export class DualAgentOrchestrator {
|
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
/**
|
|
128
|
-
* Register a custom tool
|
|
131
|
+
* Register a custom tool with optional visibility settings
|
|
129
132
|
*/
|
|
130
|
-
public registerTool(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
public registerTool(
|
|
134
|
+
tool: BaseToolWrapper,
|
|
135
|
+
options?: interfaces.IToolRegistrationOptions
|
|
136
|
+
): void {
|
|
137
|
+
this.registry.register(tool, options);
|
|
138
|
+
|
|
139
|
+
// If initial visibility and agents exist, register with them
|
|
140
|
+
const visibility = options?.visibility ?? 'initial';
|
|
141
|
+
if (visibility === 'initial') {
|
|
142
|
+
if (this.driver) {
|
|
143
|
+
this.driver.registerTool(tool);
|
|
144
|
+
}
|
|
145
|
+
if (this.guardian) {
|
|
146
|
+
this.guardian.registerTool(tool);
|
|
147
|
+
}
|
|
138
148
|
}
|
|
139
149
|
}
|
|
140
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Register an expert (subagent) as a tool
|
|
153
|
+
*/
|
|
154
|
+
public registerExpert(config: interfaces.IExpertConfig): void {
|
|
155
|
+
const expert = new ExpertTool(config, this.smartai);
|
|
156
|
+
this.registerTool(expert, {
|
|
157
|
+
visibility: config.visibility,
|
|
158
|
+
tags: config.tags,
|
|
159
|
+
category: config.category ?? 'expert',
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Enable tool search functionality
|
|
165
|
+
* This adds a 'tools' tool that allows the Driver to discover and activate on-demand tools
|
|
166
|
+
*/
|
|
167
|
+
public enableToolSearch(): void {
|
|
168
|
+
const searchTool = new ToolSearchTool(this.registry, (tool) => {
|
|
169
|
+
// Callback when an on-demand tool is activated
|
|
170
|
+
if (this.driver) {
|
|
171
|
+
this.driver.registerTool(tool);
|
|
172
|
+
}
|
|
173
|
+
if (this.guardian) {
|
|
174
|
+
this.guardian.registerTool(tool);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
this.registerTool(searchTool); // Always initial visibility
|
|
178
|
+
}
|
|
179
|
+
|
|
141
180
|
/**
|
|
142
181
|
* Register all standard tools
|
|
143
182
|
*/
|
|
@@ -193,19 +232,14 @@ export class DualAgentOrchestrator {
|
|
|
193
232
|
});
|
|
194
233
|
this.guardian = new GuardianAgent(this.guardianProvider, this.options.guardianPolicyPrompt);
|
|
195
234
|
|
|
196
|
-
// Register
|
|
197
|
-
for (const tool of this.
|
|
235
|
+
// Register visible tools with agents
|
|
236
|
+
for (const tool of this.registry.getVisibleTools()) {
|
|
198
237
|
this.driver.registerTool(tool);
|
|
199
238
|
this.guardian.registerTool(tool);
|
|
200
239
|
}
|
|
201
240
|
|
|
202
|
-
// Initialize
|
|
203
|
-
|
|
204
|
-
for (const tool of this.tools.values()) {
|
|
205
|
-
initPromises.push(tool.initialize());
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
await Promise.all(initPromises);
|
|
241
|
+
// Initialize visible tools
|
|
242
|
+
await this.registry.initializeVisibleTools();
|
|
209
243
|
this.isRunning = true;
|
|
210
244
|
}
|
|
211
245
|
|
|
@@ -213,13 +247,7 @@ export class DualAgentOrchestrator {
|
|
|
213
247
|
* Cleanup all tools
|
|
214
248
|
*/
|
|
215
249
|
public async stop(): Promise<void> {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
for (const tool of this.tools.values()) {
|
|
219
|
-
cleanupPromises.push(tool.cleanup());
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
await Promise.all(cleanupPromises);
|
|
250
|
+
await this.registry.cleanup();
|
|
223
251
|
|
|
224
252
|
// Only stop smartai if we created it (don't stop external instances)
|
|
225
253
|
if (this.ownsSmartAi) {
|
|
@@ -432,7 +460,7 @@ Please output the exact XML format above.`
|
|
|
432
460
|
});
|
|
433
461
|
|
|
434
462
|
// Execute the tool
|
|
435
|
-
const tool = this.
|
|
463
|
+
const tool = this.registry.getTool(proposal.toolName);
|
|
436
464
|
if (!tool) {
|
|
437
465
|
const errorMessage = `Tool "${proposal.toolName}" not found.`;
|
|
438
466
|
driverResponse = await this.driver.continueWithMessage(
|
|
@@ -652,6 +680,13 @@ Please output the exact XML format above.`
|
|
|
652
680
|
* Get registered tool names
|
|
653
681
|
*/
|
|
654
682
|
public getToolNames(): string[] {
|
|
655
|
-
return
|
|
683
|
+
return this.registry.getAllMetadata().map((m) => m.name);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Get the tool registry for advanced operations
|
|
688
|
+
*/
|
|
689
|
+
public getRegistry(): ToolRegistry {
|
|
690
|
+
return this.registry;
|
|
656
691
|
}
|
|
657
692
|
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import * as interfaces from './smartagent.interfaces.js';
|
|
2
|
+
import { BaseToolWrapper } from './smartagent.tools.base.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ToolRegistry - Manages tool registration, visibility, and lifecycle
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Track all registered tools with their metadata
|
|
9
|
+
* - Manage visibility (initial vs on-demand)
|
|
10
|
+
* - Handle activation of on-demand tools
|
|
11
|
+
* - Provide search functionality
|
|
12
|
+
*/
|
|
13
|
+
export class ToolRegistry {
|
|
14
|
+
private tools: Map<string, BaseToolWrapper> = new Map();
|
|
15
|
+
private metadata: Map<string, interfaces.IToolMetadata> = new Map();
|
|
16
|
+
private activated: Set<string> = new Set();
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Register a tool with optional visibility settings
|
|
20
|
+
*/
|
|
21
|
+
register(tool: BaseToolWrapper, options: interfaces.IToolRegistrationOptions = {}): void {
|
|
22
|
+
const visibility = options.visibility ?? 'initial';
|
|
23
|
+
|
|
24
|
+
this.tools.set(tool.name, tool);
|
|
25
|
+
this.metadata.set(tool.name, {
|
|
26
|
+
name: tool.name,
|
|
27
|
+
description: tool.description,
|
|
28
|
+
actions: tool.actions,
|
|
29
|
+
visibility,
|
|
30
|
+
isActivated: visibility === 'initial',
|
|
31
|
+
isInitialized: false,
|
|
32
|
+
tags: options.tags,
|
|
33
|
+
category: options.category,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (visibility === 'initial') {
|
|
37
|
+
this.activated.add(tool.name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get tools visible to the Driver (initial + activated on-demand)
|
|
43
|
+
*/
|
|
44
|
+
getVisibleTools(): BaseToolWrapper[] {
|
|
45
|
+
return Array.from(this.tools.entries())
|
|
46
|
+
.filter(([name]) => this.activated.has(name))
|
|
47
|
+
.map(([, tool]) => tool);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get all tools (for search results)
|
|
52
|
+
*/
|
|
53
|
+
getAllTools(): BaseToolWrapper[] {
|
|
54
|
+
return Array.from(this.tools.values());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get a specific tool by name
|
|
59
|
+
*/
|
|
60
|
+
getTool(name: string): BaseToolWrapper | undefined {
|
|
61
|
+
return this.tools.get(name);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get metadata for a tool
|
|
66
|
+
*/
|
|
67
|
+
getMetadata(name: string): interfaces.IToolMetadata | undefined {
|
|
68
|
+
return this.metadata.get(name);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get all metadata
|
|
73
|
+
*/
|
|
74
|
+
getAllMetadata(): interfaces.IToolMetadata[] {
|
|
75
|
+
return Array.from(this.metadata.values());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Search tools by query (matches name, description, tags, action names)
|
|
80
|
+
*/
|
|
81
|
+
search(query: string): interfaces.IToolMetadata[] {
|
|
82
|
+
const q = query.toLowerCase();
|
|
83
|
+
return this.getAllMetadata().filter((meta) => {
|
|
84
|
+
if (meta.name.toLowerCase().includes(q)) return true;
|
|
85
|
+
if (meta.description.toLowerCase().includes(q)) return true;
|
|
86
|
+
if (meta.tags?.some((t) => t.toLowerCase().includes(q))) return true;
|
|
87
|
+
if (meta.category?.toLowerCase().includes(q)) return true;
|
|
88
|
+
if (
|
|
89
|
+
meta.actions.some(
|
|
90
|
+
(a) => a.name.toLowerCase().includes(q) || a.description.toLowerCase().includes(q)
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
return true;
|
|
94
|
+
return false;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Activate an on-demand tool
|
|
100
|
+
*/
|
|
101
|
+
async activate(name: string): Promise<{ success: boolean; error?: string }> {
|
|
102
|
+
const tool = this.tools.get(name);
|
|
103
|
+
const meta = this.metadata.get(name);
|
|
104
|
+
|
|
105
|
+
if (!tool || !meta) {
|
|
106
|
+
return { success: false, error: `Tool "${name}" not found` };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (this.activated.has(name)) {
|
|
110
|
+
return { success: true }; // Already activated
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Initialize if not already initialized
|
|
114
|
+
if (!meta.isInitialized) {
|
|
115
|
+
await tool.initialize();
|
|
116
|
+
meta.isInitialized = true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.activated.add(name);
|
|
120
|
+
meta.isActivated = true;
|
|
121
|
+
|
|
122
|
+
return { success: true };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Check if a tool is activated
|
|
127
|
+
*/
|
|
128
|
+
isActivated(name: string): boolean {
|
|
129
|
+
return this.activated.has(name);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Initialize all initial (visible) tools
|
|
134
|
+
*/
|
|
135
|
+
async initializeVisibleTools(): Promise<void> {
|
|
136
|
+
const promises: Promise<void>[] = [];
|
|
137
|
+
|
|
138
|
+
for (const [name, tool] of this.tools) {
|
|
139
|
+
const meta = this.metadata.get(name);
|
|
140
|
+
if (meta && this.activated.has(name) && !meta.isInitialized) {
|
|
141
|
+
promises.push(
|
|
142
|
+
tool.initialize().then(() => {
|
|
143
|
+
meta.isInitialized = true;
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
await Promise.all(promises);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Cleanup all initialized tools
|
|
154
|
+
*/
|
|
155
|
+
async cleanup(): Promise<void> {
|
|
156
|
+
const promises: Promise<void>[] = [];
|
|
157
|
+
|
|
158
|
+
for (const [name, tool] of this.tools) {
|
|
159
|
+
const meta = this.metadata.get(name);
|
|
160
|
+
if (meta?.isInitialized) {
|
|
161
|
+
promises.push(tool.cleanup());
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
await Promise.all(promises);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Check if a tool exists in the registry
|
|
170
|
+
*/
|
|
171
|
+
has(name: string): boolean {
|
|
172
|
+
return this.tools.has(name);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Get the number of registered tools
|
|
177
|
+
*/
|
|
178
|
+
get size(): number {
|
|
179
|
+
return this.tools.size;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get the number of activated tools
|
|
184
|
+
*/
|
|
185
|
+
get activatedCount(): number {
|
|
186
|
+
return this.activated.size;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
|
|
3
|
+
// ================================
|
|
4
|
+
// Tool Visibility & Registry Types
|
|
5
|
+
// ================================
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Tool visibility mode
|
|
9
|
+
* - 'initial': Conveyed to model in system prompt AND discoverable via search
|
|
10
|
+
* - 'on-demand': Only discoverable via search, must be activated before use
|
|
11
|
+
*/
|
|
12
|
+
export type TToolVisibility = 'initial' | 'on-demand';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Tool metadata for discovery and management
|
|
16
|
+
*/
|
|
17
|
+
export interface IToolMetadata {
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
actions: IToolAction[];
|
|
21
|
+
visibility: TToolVisibility;
|
|
22
|
+
isActivated: boolean;
|
|
23
|
+
isInitialized: boolean;
|
|
24
|
+
tags?: string[];
|
|
25
|
+
category?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Options when registering a tool
|
|
30
|
+
*/
|
|
31
|
+
export interface IToolRegistrationOptions {
|
|
32
|
+
visibility?: TToolVisibility;
|
|
33
|
+
tags?: string[];
|
|
34
|
+
category?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Configuration for creating an Expert (SubAgent)
|
|
39
|
+
*/
|
|
40
|
+
export interface IExpertConfig {
|
|
41
|
+
/** Unique name for the expert */
|
|
42
|
+
name: string;
|
|
43
|
+
/** Description of the expert's capabilities */
|
|
44
|
+
description: string;
|
|
45
|
+
/** System message defining expert behavior */
|
|
46
|
+
systemMessage: string;
|
|
47
|
+
/** Guardian policy for the expert's inner agent */
|
|
48
|
+
guardianPolicy: string;
|
|
49
|
+
/** AI provider (defaults to parent's provider) */
|
|
50
|
+
provider?: plugins.smartai.TProvider;
|
|
51
|
+
/** Tools available to this expert */
|
|
52
|
+
tools?: IAgentToolWrapper[];
|
|
53
|
+
/** Max iterations for expert tasks (default: 10) */
|
|
54
|
+
maxIterations?: number;
|
|
55
|
+
/** Visibility mode (default: 'initial') */
|
|
56
|
+
visibility?: TToolVisibility;
|
|
57
|
+
/** Searchable tags */
|
|
58
|
+
tags?: string[];
|
|
59
|
+
/** Category for grouping */
|
|
60
|
+
category?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
3
63
|
// ================================
|
|
4
64
|
// Task Run Options
|
|
5
65
|
// ================================
|