@push.rocks/smartagent 1.8.0 → 3.0.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 +3 -3
- package/dist_ts/index.d.ts +8 -14
- package/dist_ts/index.js +8 -24
- package/dist_ts/plugins.d.ts +8 -9
- package/dist_ts/plugins.js +10 -12
- package/dist_ts/smartagent.classes.agent.d.ts +2 -0
- package/dist_ts/smartagent.classes.agent.js +173 -0
- package/dist_ts/smartagent.classes.toolregistry.d.ts +7 -70
- package/dist_ts/smartagent.classes.toolregistry.js +11 -155
- package/dist_ts/smartagent.interfaces.d.ts +47 -283
- package/dist_ts/smartagent.interfaces.js +6 -7
- package/dist_ts/smartagent.utils.truncation.d.ts +10 -0
- package/dist_ts/smartagent.utils.truncation.js +26 -0
- package/dist_ts_compaction/index.d.ts +1 -0
- package/dist_ts_compaction/index.js +2 -0
- package/dist_ts_compaction/plugins.d.ts +4 -0
- package/dist_ts_compaction/plugins.js +3 -0
- package/dist_ts_compaction/smartagent.compaction.d.ts +10 -0
- package/dist_ts_compaction/smartagent.compaction.js +46 -0
- package/dist_ts_tools/index.d.ts +8 -0
- package/dist_ts_tools/index.js +6 -0
- package/dist_ts_tools/plugins.d.ts +15 -0
- package/dist_ts_tools/plugins.js +19 -0
- package/dist_ts_tools/tool.filesystem.d.ts +6 -0
- package/dist_ts_tools/tool.filesystem.js +102 -0
- package/dist_ts_tools/tool.http.d.ts +2 -0
- package/dist_ts_tools/tool.http.js +65 -0
- package/dist_ts_tools/tool.json.d.ts +2 -0
- package/dist_ts_tools/tool.json.js +47 -0
- package/dist_ts_tools/tool.shell.d.ts +8 -0
- package/dist_ts_tools/tool.shell.js +40 -0
- package/npmextra.json +1 -1
- package/package.json +30 -18
- package/readme.hints.md +38 -84
- package/readme.md +254 -682
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/index.ts +10 -37
- package/ts/plugins.ts +22 -21
- package/ts/smartagent.classes.agent.ts +198 -0
- package/ts/smartagent.classes.toolregistry.ts +11 -179
- package/ts/smartagent.interfaces.ts +51 -363
- package/ts/smartagent.utils.truncation.ts +39 -0
- package/ts_compaction/index.ts +1 -0
- package/ts_compaction/plugins.ts +6 -0
- package/ts_compaction/smartagent.compaction.ts +51 -0
- package/ts_tools/index.ts +8 -0
- package/ts_tools/plugins.ts +30 -0
- package/ts_tools/tool.filesystem.ts +131 -0
- package/ts_tools/tool.http.ts +78 -0
- package/ts_tools/tool.json.ts +53 -0
- package/ts_tools/tool.shell.ts +62 -0
- package/dist_ts/smartagent.classes.driveragent.d.ts +0 -134
- package/dist_ts/smartagent.classes.driveragent.js +0 -671
- package/dist_ts/smartagent.classes.dualagent.d.ts +0 -93
- package/dist_ts/smartagent.classes.dualagent.js +0 -614
- package/dist_ts/smartagent.classes.guardianagent.d.ts +0 -46
- package/dist_ts/smartagent.classes.guardianagent.js +0 -201
- package/dist_ts/smartagent.tools.base.d.ts +0 -52
- package/dist_ts/smartagent.tools.base.js +0 -42
- package/dist_ts/smartagent.tools.browser.d.ts +0 -17
- package/dist_ts/smartagent.tools.browser.js +0 -229
- package/dist_ts/smartagent.tools.deno.d.ts +0 -21
- package/dist_ts/smartagent.tools.deno.js +0 -191
- package/dist_ts/smartagent.tools.expert.d.ts +0 -27
- package/dist_ts/smartagent.tools.expert.js +0 -126
- package/dist_ts/smartagent.tools.filesystem.d.ts +0 -40
- package/dist_ts/smartagent.tools.filesystem.js +0 -801
- package/dist_ts/smartagent.tools.http.d.ts +0 -16
- package/dist_ts/smartagent.tools.http.js +0 -264
- package/dist_ts/smartagent.tools.json.d.ts +0 -24
- package/dist_ts/smartagent.tools.json.js +0 -202
- package/dist_ts/smartagent.tools.search.d.ts +0 -29
- package/dist_ts/smartagent.tools.search.js +0 -215
- package/dist_ts/smartagent.tools.shell.d.ts +0 -17
- package/dist_ts/smartagent.tools.shell.js +0 -202
- package/ts/smartagent.classes.driveragent.ts +0 -775
- package/ts/smartagent.classes.dualagent.ts +0 -692
- package/ts/smartagent.classes.guardianagent.ts +0 -241
- package/ts/smartagent.tools.base.ts +0 -83
- package/ts/smartagent.tools.browser.ts +0 -253
- package/ts/smartagent.tools.deno.ts +0 -230
- package/ts/smartagent.tools.expert.ts +0 -144
- package/ts/smartagent.tools.filesystem.ts +0 -885
- package/ts/smartagent.tools.http.ts +0 -283
- package/ts/smartagent.tools.json.ts +0 -224
- package/ts/smartagent.tools.search.ts +0 -237
- package/ts/smartagent.tools.shell.ts +0 -230
package/readme.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# @push.rocks/smartagent
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A lightweight agentic loop built on **Vercel AI SDK v6** via `@push.rocks/smartai`. Register tools, get a model, call `runAgent()` — done. 🚀
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @push.rocks/smartagent
|
|
9
|
-
# or
|
|
10
8
|
pnpm install @push.rocks/smartagent
|
|
11
9
|
```
|
|
12
10
|
|
|
@@ -16,788 +14,362 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
16
14
|
|
|
17
15
|
## Overview
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
`@push.rocks/smartagent` wraps the AI SDK's `streamText` with `stopWhen: stepCountIs(n)` for **parallel multi-step tool execution**. No classes to instantiate, no lifecycle to manage — just one async function:
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
```typescript
|
|
20
|
+
import { runAgent, tool, z } from '@push.rocks/smartagent';
|
|
21
|
+
import { getModel } from '@push.rocks/smartai';
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
const model = getModel({
|
|
24
|
+
provider: 'anthropic',
|
|
25
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
26
|
+
apiKey: process.env.ANTHROPIC_TOKEN,
|
|
27
|
+
});
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
const result = await runAgent({
|
|
30
|
+
model,
|
|
31
|
+
prompt: 'What is 7 + 35?',
|
|
32
|
+
system: 'You are a helpful assistant. Use tools when asked.',
|
|
33
|
+
tools: {
|
|
34
|
+
calculator: tool({
|
|
35
|
+
description: 'Perform arithmetic',
|
|
36
|
+
inputSchema: z.object({
|
|
37
|
+
operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
|
|
38
|
+
a: z.number(),
|
|
39
|
+
b: z.number(),
|
|
40
|
+
}),
|
|
41
|
+
execute: async ({ operation, a, b }) => {
|
|
42
|
+
const ops = { add: a + b, subtract: a - b, multiply: a * b, divide: a / b };
|
|
43
|
+
return String(ops[operation]);
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
maxSteps: 10,
|
|
48
|
+
});
|
|
27
49
|
|
|
28
|
-
|
|
50
|
+
console.log(result.text); // "7 + 35 = 42"
|
|
51
|
+
console.log(result.steps); // number of agentic steps taken
|
|
52
|
+
console.log(result.usage); // { promptTokens, completionTokens, totalTokens }
|
|
53
|
+
```
|
|
29
54
|
|
|
30
55
|
## Architecture
|
|
31
56
|
|
|
32
|
-
```mermaid
|
|
33
|
-
flowchart TB
|
|
34
|
-
subgraph Input
|
|
35
|
-
Task["User Task"]
|
|
36
|
-
Policy["Guardian Policy Prompt"]
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
subgraph Orchestrator["DualAgentOrchestrator"]
|
|
40
|
-
Registry["ToolRegistry<br/><i>Visibility & Lifecycle</i>"]
|
|
41
|
-
Driver["Driver Agent<br/><i>Reason + Plan</i>"]
|
|
42
|
-
Guardian["Guardian Agent<br/><i>Evaluate against policy</i>"]
|
|
43
|
-
|
|
44
|
-
Driver -->|"tool call proposal"| Guardian
|
|
45
|
-
Guardian -->|"approve / reject + feedback"| Driver
|
|
46
|
-
Registry -->|"visible tools"| Driver
|
|
47
|
-
end
|
|
48
|
-
|
|
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
|
-
end
|
|
54
|
-
|
|
55
|
-
Task --> Orchestrator
|
|
56
|
-
Policy --> Guardian
|
|
57
|
-
Driver -->|"execute<br/>(if approved)"| Tools
|
|
58
|
-
Tools -->|"result"| Driver
|
|
59
57
|
```
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- REJECT operations on system directories or sensitive files
|
|
74
|
-
|
|
75
|
-
SHELL POLICY:
|
|
76
|
-
- Allow read-only commands (ls, cat, grep, echo)
|
|
77
|
-
- REJECT destructive commands (rm, mv, chmod) without explicit justification
|
|
78
|
-
|
|
79
|
-
FLAG any attempt to expose secrets or credentials.
|
|
80
|
-
`,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Register standard tools
|
|
84
|
-
orchestrator.registerStandardTools();
|
|
85
|
-
|
|
86
|
-
// Start the orchestrator (initializes all tools)
|
|
87
|
-
await orchestrator.start();
|
|
88
|
-
|
|
89
|
-
// Run a task
|
|
90
|
-
const result = await orchestrator.run('List all TypeScript files in the current directory');
|
|
91
|
-
|
|
92
|
-
console.log('Success:', result.success);
|
|
93
|
-
console.log('Result:', result.result);
|
|
94
|
-
console.log('Iterations:', result.iterations);
|
|
95
|
-
|
|
96
|
-
// Cleanup
|
|
97
|
-
await orchestrator.stop();
|
|
58
|
+
┌─────────────────────────────────────────────────┐
|
|
59
|
+
│ runAgent({ model, prompt, tools, maxSteps }) │
|
|
60
|
+
│ │
|
|
61
|
+
│ ┌───────────┐ ┌──────────┐ ┌───────────┐ │
|
|
62
|
+
│ │ Messages │──▶│ streamText│──▶│ Tools │ │
|
|
63
|
+
│ │ (history) │◀──│ (AI SDK) │◀──│ (ToolSet) │ │
|
|
64
|
+
│ └───────────┘ └──────────┘ └───────────┘ │
|
|
65
|
+
│ │
|
|
66
|
+
│ stopWhen: stepCountIs(maxSteps) │
|
|
67
|
+
│ + retry with backoff on 429/529/503 │
|
|
68
|
+
│ + context overflow detection & recovery │
|
|
69
|
+
│ + tool call repair (case-insensitive matching) │
|
|
70
|
+
└─────────────────────────────────────────────────┘
|
|
98
71
|
```
|
|
99
72
|
|
|
100
|
-
|
|
73
|
+
**Key features:**
|
|
101
74
|
|
|
102
|
-
|
|
75
|
+
- 🔄 **Multi-step agentic loop** — the model calls tools, sees results, and continues reasoning until done
|
|
76
|
+
- ⚡ **Parallel tool execution** — multiple tool calls in a single step are executed concurrently
|
|
77
|
+
- 🔧 **Auto-retry with backoff** — handles 429/529/503 errors with header-aware retry delays
|
|
78
|
+
- 🩹 **Tool call repair** — case-insensitive name matching + invalid tool sink prevents crashes
|
|
79
|
+
- 📊 **Token streaming** — `onToken` and `onToolCall` callbacks for real-time progress
|
|
80
|
+
- 💥 **Context overflow handling** — detects overflow and invokes your `onContextOverflow` callback
|
|
103
81
|
|
|
104
|
-
|
|
82
|
+
## Core API
|
|
105
83
|
|
|
106
|
-
|
|
84
|
+
### `runAgent(options): Promise<IAgentRunResult>`
|
|
107
85
|
|
|
108
|
-
|
|
86
|
+
The single entry point. Options:
|
|
109
87
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
88
|
+
| Option | Type | Default | Description |
|
|
89
|
+
|--------|------|---------|-------------|
|
|
90
|
+
| `model` | `LanguageModelV3` | *required* | Model from `@push.rocks/smartai`'s `getModel()` |
|
|
91
|
+
| `prompt` | `string` | *required* | The user's task/question |
|
|
92
|
+
| `system` | `string` | `undefined` | System prompt |
|
|
93
|
+
| `tools` | `ToolSet` | `{}` | Tools the agent can call |
|
|
94
|
+
| `maxSteps` | `number` | `20` | Max agentic steps before stopping |
|
|
95
|
+
| `messages` | `ModelMessage[]` | `[]` | Conversation history (for multi-turn) |
|
|
96
|
+
| `maxRetries` | `number` | `5` | Max retries on rate-limit/server errors |
|
|
97
|
+
| `onToken` | `(delta: string) => void` | — | Streaming token callback |
|
|
98
|
+
| `onToolCall` | `(name: string) => void` | — | Called when a tool is invoked |
|
|
99
|
+
| `onContextOverflow` | `(messages) => messages` | — | Handle context overflow (e.g., compact messages) |
|
|
119
100
|
|
|
120
|
-
|
|
101
|
+
### `IAgentRunResult`
|
|
121
102
|
|
|
122
103
|
```typescript
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
**Line-range Reading**: Read specific portions of large files:
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
<tool_call>
|
|
138
|
-
<tool>filesystem</tool>
|
|
139
|
-
<action>read</action>
|
|
140
|
-
<params>{"path": "/var/log/app.log", "startLine": 100, "endLine": 150}</params>
|
|
141
|
-
<reasoning>Reading only the relevant log section to avoid token overload</reasoning>
|
|
142
|
-
</tool_call>
|
|
104
|
+
interface IAgentRunResult {
|
|
105
|
+
text: string; // Final response text
|
|
106
|
+
finishReason: string; // 'stop', 'tool-calls', 'length', etc.
|
|
107
|
+
steps: number; // Number of agentic steps taken
|
|
108
|
+
messages: ModelMessage[]; // Full conversation for multi-turn
|
|
109
|
+
usage: {
|
|
110
|
+
promptTokens: number;
|
|
111
|
+
completionTokens: number;
|
|
112
|
+
totalTokens: number;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
143
115
|
```
|
|
144
116
|
|
|
145
|
-
|
|
117
|
+
## Defining Tools 🛠️
|
|
146
118
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
**Actions**: `get`, `post`, `put`, `patch`, `delete`
|
|
119
|
+
Tools use Vercel AI SDK's `tool()` helper with Zod schemas:
|
|
150
120
|
|
|
151
121
|
```typescript
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
122
|
+
import { tool, z } from '@push.rocks/smartagent';
|
|
123
|
+
|
|
124
|
+
const myTool = tool({
|
|
125
|
+
description: 'Describe what this tool does',
|
|
126
|
+
inputSchema: z.object({
|
|
127
|
+
param1: z.string().describe('What this parameter is for'),
|
|
128
|
+
param2: z.number().optional(),
|
|
129
|
+
}),
|
|
130
|
+
execute: async ({ param1, param2 }) => {
|
|
131
|
+
// Do work, return a string
|
|
132
|
+
return `Result: ${param1}`;
|
|
133
|
+
},
|
|
134
|
+
});
|
|
158
135
|
```
|
|
159
136
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
Secure shell command execution using `@push.rocks/smartshell` with `execSpawn` (no shell injection possible).
|
|
163
|
-
|
|
164
|
-
**Actions**: `execute`, `which`
|
|
137
|
+
Pass tools as a flat object to `runAgent()`:
|
|
165
138
|
|
|
166
139
|
```typescript
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
140
|
+
await runAgent({
|
|
141
|
+
model,
|
|
142
|
+
prompt: 'Do the thing',
|
|
143
|
+
tools: { myTool, anotherTool },
|
|
144
|
+
maxSteps: 10,
|
|
145
|
+
});
|
|
173
146
|
```
|
|
174
147
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
### 🌍 BrowserTool
|
|
148
|
+
## ToolRegistry
|
|
178
149
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
**Actions**: `screenshot`, `pdf`, `evaluate`, `getPageContent`
|
|
150
|
+
A lightweight helper for collecting tools:
|
|
182
151
|
|
|
183
152
|
```typescript
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
153
|
+
import { ToolRegistry, tool, z } from '@push.rocks/smartagent';
|
|
154
|
+
|
|
155
|
+
const registry = new ToolRegistry();
|
|
156
|
+
|
|
157
|
+
registry.register('random_number', tool({
|
|
158
|
+
description: 'Generate a random integer between min and max',
|
|
159
|
+
inputSchema: z.object({
|
|
160
|
+
min: z.number(),
|
|
161
|
+
max: z.number(),
|
|
162
|
+
}),
|
|
163
|
+
execute: async ({ min, max }) => {
|
|
164
|
+
return String(Math.floor(Math.random() * (max - min + 1)) + min);
|
|
165
|
+
},
|
|
166
|
+
}));
|
|
167
|
+
|
|
168
|
+
registry.register('is_even', tool({
|
|
169
|
+
description: 'Check if a number is even',
|
|
170
|
+
inputSchema: z.object({ number: z.number() }),
|
|
171
|
+
execute: async ({ number: n }) => n % 2 === 0 ? 'Yes' : 'No',
|
|
172
|
+
}));
|
|
173
|
+
|
|
174
|
+
const result = await runAgent({
|
|
175
|
+
model,
|
|
176
|
+
prompt: 'Generate a random number and tell me if it is even',
|
|
177
|
+
tools: registry.getTools(),
|
|
178
|
+
maxSteps: 10,
|
|
179
|
+
});
|
|
190
180
|
```
|
|
191
181
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
Execute TypeScript/JavaScript code in a **sandboxed Deno environment** with fine-grained permission control.
|
|
182
|
+
## Built-in Tool Factories 🧰
|
|
195
183
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
**Permissions**: `all`, `env`, `ffi`, `hrtime`, `net`, `read`, `run`, `sys`, `write`
|
|
199
|
-
|
|
200
|
-
By default, code runs **fully sandboxed with no permissions**. Permissions must be explicitly requested and are subject to Guardian approval.
|
|
184
|
+
Import from the `@push.rocks/smartagent/tools` subpath:
|
|
201
185
|
|
|
202
186
|
```typescript
|
|
203
|
-
|
|
204
|
-
<tool_call>
|
|
205
|
-
<tool>deno</tool>
|
|
206
|
-
<action>execute</action>
|
|
207
|
-
<params>{"code": "console.log('Hello from Deno!')"}</params>
|
|
208
|
-
<reasoning>Running a simple script to verify the environment</reasoning>
|
|
209
|
-
</tool_call>
|
|
210
|
-
|
|
211
|
-
// Code with network permission
|
|
212
|
-
<tool_call>
|
|
213
|
-
<tool>deno</tool>
|
|
214
|
-
<action>execute</action>
|
|
215
|
-
<params>{
|
|
216
|
-
"code": "const resp = await fetch('https://api.example.com/data'); console.log(await resp.json());",
|
|
217
|
-
"permissions": ["net"]
|
|
218
|
-
}</params>
|
|
219
|
-
<reasoning>Fetching data from API using Deno's fetch</reasoning>
|
|
220
|
-
</tool_call>
|
|
221
|
-
|
|
222
|
-
// Execute and parse JSON result
|
|
223
|
-
<tool_call>
|
|
224
|
-
<tool>deno</tool>
|
|
225
|
-
<action>executeWithResult</action>
|
|
226
|
-
<params>{
|
|
227
|
-
"code": "const result = { sum: 2 + 2, date: new Date().toISOString() }; console.log(JSON.stringify(result));"
|
|
228
|
-
}</params>
|
|
229
|
-
<reasoning>Computing values and returning structured data</reasoning>
|
|
230
|
-
</tool_call>
|
|
187
|
+
import { filesystemTool, shellTool, httpTool, jsonTool } from '@push.rocks/smartagent/tools';
|
|
231
188
|
```
|
|
232
189
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
### 📋 JsonValidatorTool
|
|
236
|
-
|
|
237
|
-
Validate and format JSON data. Perfect for agents to self-check their JSON output before completing tasks.
|
|
190
|
+
### `filesystemTool(options?)`
|
|
238
191
|
|
|
239
|
-
|
|
192
|
+
Returns: `read_file`, `write_file`, `list_directory`, `delete_file`
|
|
240
193
|
|
|
241
194
|
```typescript
|
|
242
|
-
|
|
195
|
+
const tools = filesystemTool({ rootDir: '/home/user/workspace' });
|
|
243
196
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
<tool_call>
|
|
251
|
-
<tool>json</tool>
|
|
252
|
-
<action>validate</action>
|
|
253
|
-
<params>{
|
|
254
|
-
"jsonString": "{\"name\": \"test\", \"version\": \"1.0.0\"}",
|
|
255
|
-
"requiredFields": ["name", "version", "description"]
|
|
256
|
-
}</params>
|
|
257
|
-
<reasoning>Ensuring the config has all required fields before saving</reasoning>
|
|
258
|
-
</tool_call>
|
|
259
|
-
|
|
260
|
-
// Pretty-print JSON
|
|
261
|
-
<tool_call>
|
|
262
|
-
<tool>json</tool>
|
|
263
|
-
<action>format</action>
|
|
264
|
-
<params>{"jsonString": "{\"compact\":true,\"data\":[1,2,3]}"}</params>
|
|
265
|
-
<reasoning>Formatting JSON for readable output</reasoning>
|
|
266
|
-
</tool_call>
|
|
197
|
+
await runAgent({
|
|
198
|
+
model,
|
|
199
|
+
prompt: 'Create a file called hello.txt with "Hello World"',
|
|
200
|
+
tools,
|
|
201
|
+
maxSteps: 5,
|
|
202
|
+
});
|
|
267
203
|
```
|
|
268
204
|
|
|
269
|
-
|
|
205
|
+
Options:
|
|
206
|
+
- `rootDir` — restrict all file operations to this directory. Paths outside it throw `Access denied`.
|
|
270
207
|
|
|
271
|
-
|
|
208
|
+
### `shellTool(options?)`
|
|
272
209
|
|
|
273
|
-
|
|
210
|
+
Returns: `run_command`
|
|
274
211
|
|
|
275
212
|
```typescript
|
|
276
|
-
|
|
277
|
-
orchestrator.enableToolSearch();
|
|
278
|
-
```
|
|
213
|
+
const tools = shellTool({ cwd: '/tmp', allowedCommands: ['ls', 'echo', 'cat'] });
|
|
279
214
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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',
|
|
215
|
+
await runAgent({
|
|
216
|
+
model,
|
|
217
|
+
prompt: 'List all files in /tmp',
|
|
218
|
+
tools,
|
|
219
|
+
maxSteps: 5,
|
|
331
220
|
});
|
|
332
221
|
```
|
|
333
222
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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();
|
|
223
|
+
Options:
|
|
224
|
+
- `cwd` — working directory for commands
|
|
225
|
+
- `allowedCommands` — whitelist of allowed commands (if set, others are rejected)
|
|
365
226
|
|
|
366
|
-
|
|
367
|
-
// 1. tools.search({"query": "database"}) -> finds MySpecializedTool
|
|
368
|
-
// 2. tools.activate({"name": "myspecialized"}) -> enables it
|
|
369
|
-
// 3. myspecialized.action({...}) -> use the tool
|
|
370
|
-
```
|
|
227
|
+
### `httpTool()`
|
|
371
228
|
|
|
372
|
-
|
|
229
|
+
Returns: `http_get`, `http_post`
|
|
373
230
|
|
|
374
231
|
```typescript
|
|
375
|
-
const
|
|
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
|
-
});
|
|
232
|
+
const tools = httpTool();
|
|
402
233
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
visibility: 'on-demand',
|
|
409
|
-
tags: ['security', 'audit', 'vulnerabilities'],
|
|
234
|
+
await runAgent({
|
|
235
|
+
model,
|
|
236
|
+
prompt: 'Fetch the data from https://api.example.com/status',
|
|
237
|
+
tools,
|
|
238
|
+
maxSteps: 5,
|
|
410
239
|
});
|
|
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
240
|
```
|
|
419
241
|
|
|
420
|
-
|
|
242
|
+
### `jsonTool()`
|
|
421
243
|
|
|
422
|
-
|
|
244
|
+
Returns: `json_validate`, `json_transform`
|
|
423
245
|
|
|
424
246
|
```typescript
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
onToken: (token, source) => {
|
|
432
|
-
// source is 'driver' or 'guardian'
|
|
433
|
-
process.stdout.write(token);
|
|
434
|
-
},
|
|
247
|
+
const tools = jsonTool();
|
|
248
|
+
|
|
249
|
+
// Direct usage:
|
|
250
|
+
const result = await tools.json_validate.execute({
|
|
251
|
+
jsonString: '{"name":"test","value":42}',
|
|
252
|
+
requiredFields: ['name', 'value'],
|
|
435
253
|
});
|
|
254
|
+
// → "Valid JSON: object with 2 keys"
|
|
436
255
|
```
|
|
437
256
|
|
|
438
|
-
|
|
257
|
+
## Streaming & Callbacks 🎥
|
|
439
258
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
Pass images to vision-capable models for multimodal tasks:
|
|
259
|
+
Monitor the agent in real-time:
|
|
443
260
|
|
|
444
261
|
```typescript
|
|
445
|
-
|
|
262
|
+
const result = await runAgent({
|
|
263
|
+
model,
|
|
264
|
+
prompt: 'Analyze this data...',
|
|
265
|
+
tools,
|
|
266
|
+
maxSteps: 10,
|
|
446
267
|
|
|
447
|
-
//
|
|
448
|
-
|
|
268
|
+
// Token-by-token streaming
|
|
269
|
+
onToken: (delta) => process.stdout.write(delta),
|
|
449
270
|
|
|
450
|
-
//
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
{ images: [imageBase64] }
|
|
454
|
-
);
|
|
271
|
+
// Tool call notifications
|
|
272
|
+
onToolCall: (toolName) => console.log(`\n🔧 Calling: ${toolName}`),
|
|
273
|
+
});
|
|
455
274
|
```
|
|
456
275
|
|
|
457
|
-
##
|
|
276
|
+
## Context Overflow Handling 💥
|
|
458
277
|
|
|
459
|
-
|
|
278
|
+
For long-running agents that might exceed the model's context window, use the compaction subpath:
|
|
460
279
|
|
|
461
280
|
```typescript
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
console.log(`Proposing: ${event.toolName}.${event.action}`);
|
|
475
|
-
break;
|
|
476
|
-
case 'tool_approved':
|
|
477
|
-
console.log(`✓ Approved`);
|
|
478
|
-
break;
|
|
479
|
-
case 'tool_rejected':
|
|
480
|
-
console.log(`✗ Rejected: ${event.reason}`);
|
|
481
|
-
break;
|
|
482
|
-
case 'task_completed':
|
|
483
|
-
console.log(`Done in ${event.iteration} iterations`);
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
281
|
+
import { runAgent } from '@push.rocks/smartagent';
|
|
282
|
+
import { compactMessages } from '@push.rocks/smartagent/compaction';
|
|
283
|
+
|
|
284
|
+
const result = await runAgent({
|
|
285
|
+
model,
|
|
286
|
+
prompt: 'Process all 500 files...',
|
|
287
|
+
tools,
|
|
288
|
+
maxSteps: 100,
|
|
289
|
+
|
|
290
|
+
onContextOverflow: async (messages) => {
|
|
291
|
+
// Summarize the conversation to free up context space
|
|
292
|
+
return await compactMessages(model, messages);
|
|
486
293
|
},
|
|
487
294
|
});
|
|
488
295
|
```
|
|
489
296
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
## 🔧 Native Tool Calling
|
|
297
|
+
## Output Truncation ✂️
|
|
493
298
|
|
|
494
|
-
|
|
299
|
+
Prevent large tool outputs from consuming too much context:
|
|
495
300
|
|
|
496
301
|
```typescript
|
|
497
|
-
|
|
498
|
-
ollamaToken: 'http://localhost:11434', // Ollama endpoint
|
|
499
|
-
defaultProvider: 'ollama',
|
|
500
|
-
guardianPolicyPrompt: '...',
|
|
302
|
+
import { truncateOutput } from '@push.rocks/smartagent';
|
|
501
303
|
|
|
502
|
-
|
|
503
|
-
|
|
304
|
+
const { content, truncated, notice } = truncateOutput(hugeOutput, {
|
|
305
|
+
maxLines: 2000, // default
|
|
306
|
+
maxBytes: 50_000, // default
|
|
504
307
|
});
|
|
505
308
|
```
|
|
506
309
|
|
|
507
|
-
|
|
508
|
-
- Tools are converted to JSON schema format automatically
|
|
509
|
-
- The provider handles tool call parsing natively
|
|
510
|
-
- Streaming still works with `[THINKING]` and `[OUTPUT]` markers for supported models
|
|
511
|
-
- Tool calls appear as `toolName_actionName` (e.g., `json_validate`)
|
|
512
|
-
|
|
513
|
-
This is more efficient for models that support it and avoids potential XML parsing issues.
|
|
514
|
-
|
|
515
|
-
## Guardian Policy Examples
|
|
516
|
-
|
|
517
|
-
The Guardian's power comes from your policy. Here are battle-tested examples:
|
|
518
|
-
|
|
519
|
-
### 🔐 Strict Security Policy
|
|
520
|
-
|
|
521
|
-
```typescript
|
|
522
|
-
const securityPolicy = `
|
|
523
|
-
SECURITY POLICY:
|
|
524
|
-
1. REJECT any file operations outside /home/user/workspace
|
|
525
|
-
2. REJECT any shell commands that could modify system state
|
|
526
|
-
3. REJECT any HTTP requests to internal/private IP ranges
|
|
527
|
-
4. REJECT any attempts to read environment variables or credentials
|
|
528
|
-
5. FLAG and REJECT obfuscated code execution
|
|
529
|
-
|
|
530
|
-
When rejecting, always explain:
|
|
531
|
-
- What policy was violated
|
|
532
|
-
- What would be a safer alternative
|
|
533
|
-
`;
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
### 🛠️ Development Environment Policy
|
|
537
|
-
|
|
538
|
-
```typescript
|
|
539
|
-
const devPolicy = `
|
|
540
|
-
DEVELOPMENT POLICY:
|
|
541
|
-
- Allow file operations only within the project directory
|
|
542
|
-
- Allow npm/pnpm commands for package management
|
|
543
|
-
- Allow git commands for version control
|
|
544
|
-
- Allow HTTP requests to public APIs only
|
|
545
|
-
- REJECT direct database modifications
|
|
546
|
-
- REJECT commands that could affect other users
|
|
547
|
-
|
|
548
|
-
Always verify:
|
|
549
|
-
- File paths are relative or within project bounds
|
|
550
|
-
- Commands don't have dangerous flags (--force, -rf)
|
|
551
|
-
`;
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
### 🦕 Deno Code Execution Policy
|
|
555
|
-
|
|
556
|
-
```typescript
|
|
557
|
-
const denoPolicy = `
|
|
558
|
-
DENO CODE EXECUTION POLICY:
|
|
559
|
-
- ONLY allow 'read' permission for files within the workspace
|
|
560
|
-
- REJECT 'all' permission unless explicitly justified for the task
|
|
561
|
-
- REJECT 'run' permission (subprocess execution) without specific justification
|
|
562
|
-
- REJECT code that attempts to:
|
|
563
|
-
- Access credentials or environment secrets (even with 'env' permission)
|
|
564
|
-
- Make network requests to internal/private IP ranges
|
|
565
|
-
- Write to system directories
|
|
566
|
-
- FLAG obfuscated or encoded code (base64, eval with dynamic strings)
|
|
567
|
-
- Prefer sandboxed execution (no permissions) when possible
|
|
568
|
-
|
|
569
|
-
When evaluating code:
|
|
570
|
-
- Review the actual code content, not just permissions
|
|
571
|
-
- Consider what data the code could exfiltrate
|
|
572
|
-
- Verify network endpoints are legitimate public APIs
|
|
573
|
-
`;
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
## Configuration Options
|
|
310
|
+
The built-in tool factories use `truncateOutput` internally.
|
|
577
311
|
|
|
578
|
-
|
|
579
|
-
interface IDualAgentOptions {
|
|
580
|
-
// Provider tokens (from @push.rocks/smartai)
|
|
581
|
-
openaiToken?: string;
|
|
582
|
-
anthropicToken?: string;
|
|
583
|
-
perplexityToken?: string;
|
|
584
|
-
groqToken?: string;
|
|
585
|
-
xaiToken?: string;
|
|
586
|
-
ollamaToken?: string; // URL for Ollama endpoint
|
|
587
|
-
|
|
588
|
-
// Use existing SmartAi instance (optional - avoids duplicate providers)
|
|
589
|
-
smartAiInstance?: SmartAi;
|
|
590
|
-
|
|
591
|
-
// Provider selection
|
|
592
|
-
defaultProvider?: TProvider; // For both Driver and Guardian
|
|
593
|
-
guardianProvider?: TProvider; // Optional: separate provider for Guardian
|
|
594
|
-
|
|
595
|
-
// Agent configuration
|
|
596
|
-
driverSystemMessage?: string; // Custom system message for Driver
|
|
597
|
-
guardianPolicyPrompt: string; // REQUIRED: Policy for Guardian to enforce
|
|
598
|
-
name?: string; // Agent system name
|
|
599
|
-
verbose?: boolean; // Enable verbose logging
|
|
600
|
-
|
|
601
|
-
// Native tool calling
|
|
602
|
-
useNativeToolCalling?: boolean; // Use provider's native tool calling API (default: false)
|
|
603
|
-
|
|
604
|
-
// Limits
|
|
605
|
-
maxIterations?: number; // Max task iterations (default: 20)
|
|
606
|
-
maxConsecutiveRejections?: number; // Abort after N rejections (default: 3)
|
|
607
|
-
maxResultChars?: number; // Max chars for tool results before truncation (default: 15000)
|
|
608
|
-
maxHistoryMessages?: number; // Max history messages for API (default: 20)
|
|
609
|
-
|
|
610
|
-
// Callbacks
|
|
611
|
-
onProgress?: (event: IProgressEvent) => void; // Progress event callback
|
|
612
|
-
onToken?: (token: string, source: 'driver' | 'guardian') => void; // Streaming callback
|
|
613
|
-
logPrefix?: string; // Prefix for log messages
|
|
614
|
-
}
|
|
615
|
-
```
|
|
312
|
+
## Multi-Turn Conversations 💬
|
|
616
313
|
|
|
617
|
-
|
|
314
|
+
Pass the returned `messages` back for multi-turn interactions:
|
|
618
315
|
|
|
619
316
|
```typescript
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
toolCallCount?: number; // Number of tool calls made
|
|
628
|
-
rejectionCount?: number; // Number of Guardian rejections
|
|
629
|
-
toolLog?: IToolExecutionLog[]; // Detailed tool execution log
|
|
630
|
-
error?: string; // Error message if status is 'error'
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
type TDualAgentRunStatus =
|
|
634
|
-
| 'completed'
|
|
635
|
-
| 'in_progress'
|
|
636
|
-
| 'max_iterations_reached'
|
|
637
|
-
| 'max_rejections_reached'
|
|
638
|
-
| 'clarification_needed'
|
|
639
|
-
| 'error';
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
## Custom Tools
|
|
643
|
-
|
|
644
|
-
Create custom tools by extending `BaseToolWrapper`:
|
|
645
|
-
|
|
646
|
-
```typescript
|
|
647
|
-
import { BaseToolWrapper, IToolAction, IToolExecutionResult } from '@push.rocks/smartagent';
|
|
648
|
-
|
|
649
|
-
class MyCustomTool extends BaseToolWrapper {
|
|
650
|
-
public name = 'custom';
|
|
651
|
-
public description = 'My custom tool for specific operations';
|
|
652
|
-
|
|
653
|
-
public actions: IToolAction[] = [
|
|
654
|
-
{
|
|
655
|
-
name: 'myAction',
|
|
656
|
-
description: 'Performs a custom action',
|
|
657
|
-
parameters: {
|
|
658
|
-
type: 'object',
|
|
659
|
-
properties: {
|
|
660
|
-
input: { type: 'string', description: 'Input for the action' },
|
|
661
|
-
},
|
|
662
|
-
required: ['input'],
|
|
663
|
-
},
|
|
664
|
-
},
|
|
665
|
-
];
|
|
666
|
-
|
|
667
|
-
public async initialize(): Promise<void> {
|
|
668
|
-
// Setup your tool (called when orchestrator.start() runs)
|
|
669
|
-
this.isInitialized = true;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
public async cleanup(): Promise<void> {
|
|
673
|
-
// Cleanup resources (called when orchestrator.stop() runs)
|
|
674
|
-
this.isInitialized = false;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
public async execute(action: string, params: Record<string, unknown>): Promise<IToolExecutionResult> {
|
|
678
|
-
this.validateAction(action);
|
|
679
|
-
this.ensureInitialized();
|
|
680
|
-
|
|
681
|
-
if (action === 'myAction') {
|
|
682
|
-
return {
|
|
683
|
-
success: true,
|
|
684
|
-
result: { processed: params.input },
|
|
685
|
-
summary: `Processed input: ${params.input}`, // Optional human-readable summary
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
return { success: false, error: 'Unknown action' };
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// Human-readable summary for Guardian evaluation
|
|
693
|
-
public getCallSummary(action: string, params: Record<string, unknown>): string {
|
|
694
|
-
return `Custom action "${action}" with input "${params.input}"`;
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
// Register custom tool
|
|
699
|
-
orchestrator.registerTool(new MyCustomTool());
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
## Reusing SmartAi Instances
|
|
703
|
-
|
|
704
|
-
If you already have a `@push.rocks/smartai` instance, you can share it:
|
|
705
|
-
|
|
706
|
-
```typescript
|
|
707
|
-
import { SmartAi } from '@push.rocks/smartai';
|
|
708
|
-
import { DualAgentOrchestrator } from '@push.rocks/smartagent';
|
|
709
|
-
|
|
710
|
-
const smartai = new SmartAi({ openaiToken: 'sk-...' });
|
|
711
|
-
await smartai.start();
|
|
317
|
+
// First turn
|
|
318
|
+
const turn1 = await runAgent({
|
|
319
|
+
model,
|
|
320
|
+
prompt: 'Create a project structure',
|
|
321
|
+
tools,
|
|
322
|
+
maxSteps: 10,
|
|
323
|
+
});
|
|
712
324
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
325
|
+
// Second turn — continues the conversation
|
|
326
|
+
const turn2 = await runAgent({
|
|
327
|
+
model,
|
|
328
|
+
prompt: 'Now add a README to the project',
|
|
329
|
+
tools,
|
|
330
|
+
maxSteps: 10,
|
|
331
|
+
messages: turn1.messages, // pass history
|
|
716
332
|
});
|
|
333
|
+
```
|
|
717
334
|
|
|
718
|
-
|
|
719
|
-
// ... use orchestrator ...
|
|
720
|
-
await orchestrator.stop();
|
|
335
|
+
## Exports
|
|
721
336
|
|
|
722
|
-
|
|
723
|
-
await smartai.stop();
|
|
724
|
-
```
|
|
337
|
+
### Main (`@push.rocks/smartagent`)
|
|
725
338
|
|
|
726
|
-
|
|
339
|
+
| Export | Type | Description |
|
|
340
|
+
|--------|------|-------------|
|
|
341
|
+
| `runAgent` | function | Core agentic loop |
|
|
342
|
+
| `ToolRegistry` | class | Tool collection helper |
|
|
343
|
+
| `truncateOutput` | function | Output truncation utility |
|
|
344
|
+
| `ContextOverflowError` | class | Error type for context overflow |
|
|
345
|
+
| `tool` | function | Re-exported from `@push.rocks/smartai` |
|
|
346
|
+
| `z` | object | Re-exported Zod for schema definitions |
|
|
347
|
+
| `stepCountIs` | function | Re-exported from AI SDK |
|
|
348
|
+
| `jsonSchema` | function | Re-exported from `@push.rocks/smartai` |
|
|
727
349
|
|
|
728
|
-
|
|
350
|
+
### Tools (`@push.rocks/smartagent/tools`)
|
|
729
351
|
|
|
730
|
-
|
|
|
731
|
-
|
|
732
|
-
|
|
|
733
|
-
|
|
|
734
|
-
|
|
|
735
|
-
|
|
|
736
|
-
| Ollama | ✅ | ✅ |
|
|
737
|
-
| XAI | ✅ | ✅ |
|
|
738
|
-
| Exo | ✅ | ✅ |
|
|
352
|
+
| Export | Type | Description |
|
|
353
|
+
|--------|------|-------------|
|
|
354
|
+
| `filesystemTool` | factory | File operations (read, write, list, delete) |
|
|
355
|
+
| `shellTool` | factory | Shell command execution |
|
|
356
|
+
| `httpTool` | factory | HTTP GET/POST requests |
|
|
357
|
+
| `jsonTool` | factory | JSON validation and transformation |
|
|
739
358
|
|
|
740
|
-
|
|
359
|
+
### Compaction (`@push.rocks/smartagent/compaction`)
|
|
741
360
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
groqToken: 'gsk-...',
|
|
746
|
-
defaultProvider: 'openai', // Driver uses OpenAI
|
|
747
|
-
guardianProvider: 'groq', // Guardian uses Groq (faster, cheaper)
|
|
748
|
-
guardianPolicyPrompt: '...',
|
|
749
|
-
});
|
|
750
|
-
```
|
|
361
|
+
| Export | Type | Description |
|
|
362
|
+
|--------|------|-------------|
|
|
363
|
+
| `compactMessages` | function | Summarize message history to free context |
|
|
751
364
|
|
|
752
|
-
##
|
|
753
|
-
|
|
754
|
-
### DualAgentOrchestrator
|
|
755
|
-
|
|
756
|
-
| Method | Description |
|
|
757
|
-
|--------|-------------|
|
|
758
|
-
| `start()` | Initialize all tools and AI providers |
|
|
759
|
-
| `stop()` | Cleanup all tools and resources |
|
|
760
|
-
| `run(task, options?)` | Execute a task with optional images for vision |
|
|
761
|
-
| `continueTask(input)` | Continue a task with user input |
|
|
762
|
-
| `registerTool(tool, options?)` | Register a custom tool with optional visibility settings |
|
|
763
|
-
| `registerStandardTools()` | Register all built-in tools (Filesystem, HTTP, Shell, Browser, Deno) |
|
|
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 |
|
|
767
|
-
| `setGuardianPolicy(policy)` | Update Guardian policy at runtime |
|
|
768
|
-
| `getHistory()` | Get conversation history |
|
|
769
|
-
| `getToolNames()` | Get list of registered tool names |
|
|
770
|
-
| `getRegistry()` | Get the ToolRegistry for advanced operations |
|
|
771
|
-
| `isActive()` | Check if orchestrator is running |
|
|
772
|
-
|
|
773
|
-
### Exports
|
|
365
|
+
## Dependencies
|
|
774
366
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
// Tool Registry
|
|
782
|
-
export { ToolRegistry } from '@push.rocks/smartagent';
|
|
783
|
-
|
|
784
|
-
// Tools
|
|
785
|
-
export { BaseToolWrapper } from '@push.rocks/smartagent';
|
|
786
|
-
export { FilesystemTool, type IFilesystemToolOptions } from '@push.rocks/smartagent';
|
|
787
|
-
export { HttpTool } from '@push.rocks/smartagent';
|
|
788
|
-
export { ShellTool } from '@push.rocks/smartagent';
|
|
789
|
-
export { BrowserTool } from '@push.rocks/smartagent';
|
|
790
|
-
export { DenoTool, type TDenoPermission } from '@push.rocks/smartagent';
|
|
791
|
-
export { JsonValidatorTool } from '@push.rocks/smartagent';
|
|
792
|
-
export { ToolSearchTool } from '@push.rocks/smartagent';
|
|
793
|
-
export { ExpertTool } from '@push.rocks/smartagent';
|
|
794
|
-
|
|
795
|
-
// Types and interfaces
|
|
796
|
-
export * from '@push.rocks/smartagent'; // All interfaces (IExpertConfig, IToolMetadata, etc.)
|
|
797
|
-
|
|
798
|
-
// Re-exported from @push.rocks/smartai
|
|
799
|
-
export { type ISmartAiOptions, type TProvider, type ChatMessage, type ChatOptions, type ChatResponse };
|
|
800
|
-
```
|
|
367
|
+
- **[`@push.rocks/smartai`](https://code.foss.global/push.rocks/smartai)** — Provider registry, `getModel()`, re-exports `tool`/`jsonSchema`
|
|
368
|
+
- **[`ai`](https://www.npmjs.com/package/ai)** v6 — Vercel AI SDK (`streamText`, `stepCountIs`, `ModelMessage`)
|
|
369
|
+
- **[`zod`](https://www.npmjs.com/package/zod)** — Tool input schema definitions
|
|
370
|
+
- **[`@push.rocks/smartfs`](https://code.foss.global/push.rocks/smartfs)** — Filesystem tool implementation
|
|
371
|
+
- **[`@push.rocks/smartshell`](https://code.foss.global/push.rocks/smartshell)** — Shell tool implementation
|
|
372
|
+
- **[`@push.rocks/smartrequest`](https://code.foss.global/push.rocks/smartrequest)** — HTTP tool implementation
|
|
801
373
|
|
|
802
374
|
## License and Legal Information
|
|
803
375
|
|