@agent-smith/core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +378 -0
- package/dist/actions/cmd.d.ts +5 -0
- package/dist/actions/cmd.js +135 -0
- package/dist/actions/read.d.ts +3 -0
- package/dist/actions/read.js +17 -0
- package/dist/adaptaters/cmd.d.ts +2 -0
- package/dist/adaptaters/cmd.js +39 -0
- package/dist/agents/cmd.d.ts +3 -0
- package/dist/agents/cmd.js +10 -0
- package/dist/agents/conf.d.ts +3 -0
- package/dist/agents/conf.js +9 -0
- package/dist/agents/files.d.ts +3 -0
- package/dist/agents/files.js +40 -0
- package/dist/agents/read.d.ts +11 -0
- package/dist/agents/read.js +241 -0
- package/dist/agents/useagent.d.ts +13 -0
- package/dist/agents/useagent.js +395 -0
- package/dist/conf.d.ts +14 -0
- package/dist/conf.js +160 -0
- package/dist/const.d.ts +3 -0
- package/dist/const.js +10 -0
- package/dist/db/db.d.ts +3 -0
- package/dist/db/db.js +24 -0
- package/dist/db/read.d.ts +45 -0
- package/dist/db/read.js +280 -0
- package/dist/db/schemas.d.ts +2 -0
- package/dist/db/schemas.js +141 -0
- package/dist/db/write.d.ts +23 -0
- package/dist/db/write.js +570 -0
- package/dist/features/actions/load-skill.d.ts +2 -0
- package/dist/features/actions/load-skill.js +37 -0
- package/dist/features/actions/notify-user.d.ts +2 -0
- package/dist/features/actions/notify-user.js +25 -0
- package/dist/features/actions/read-feature.d.ts +2 -0
- package/dist/features/actions/read-feature.js +25 -0
- package/dist/features/actions/run-agent.d.ts +2 -0
- package/dist/features/actions/run-agent.js +34 -0
- package/dist/features/actions/run-collaborator.d.ts +1 -0
- package/dist/features/actions/run-collaborator.js +42 -0
- package/dist/features/actions/run-worker.d.ts +2 -0
- package/dist/features/actions/run-worker.js +34 -0
- package/dist/features/adaptaters/agent-smith-db-getschema.d.ts +4 -0
- package/dist/features/adaptaters/agent-smith-db-getschema.js +62 -0
- package/dist/features/adaptaters/imgs2base64.d.ts +1 -0
- package/dist/features/adaptaters/imgs2base64.js +13 -0
- package/dist/features/adaptaters/prequery.d.ts +4 -0
- package/dist/features/adaptaters/prequery.js +5 -0
- package/dist/features/agents/agent-smith-colab.yml +37 -0
- package/dist/features/agents/agent-smith-doc.yml +50 -0
- package/dist/features/agents/agent-smith-help.yml +35 -0
- package/dist/features/agents/agent-smith-search.yml +41 -0
- package/dist/features/agents/agent-smith-sql.yml +31 -0
- package/dist/features/agents/agent-smith.yml +37 -0
- package/dist/features/agents/collaborator.yml +15 -0
- package/dist/features/agents/infer.yml +12 -0
- package/dist/features/fragments/ctx-helper-files.md +4 -0
- package/dist/features/fragments/workspace.txt +6 -0
- package/dist/features/skills/create-package-readme/SKILL.md +66 -0
- package/dist/features/skills/document-package/SKILL.md +83 -0
- package/dist/features/skills/t/SKILL.md +26 -0
- package/dist/features/skills/update-codebase-summary/SKILL.md +45 -0
- package/dist/features/skills/update-doc-map/SKILL.md +8 -0
- package/dist/features/skills/update-doc-map/scripts/generate-doc-map.mjs +196 -0
- package/dist/features/workflows/agent-smith-db.yml +9 -0
- package/dist/features/workflows/q.yml +3 -0
- package/dist/features/workflows/vision.yml +3 -0
- package/dist/main.d.ts +127 -0
- package/dist/main.js +80 -0
- package/dist/mcp.d.ts +16 -0
- package/dist/mcp.js +110 -0
- package/dist/state/backends.d.ts +7 -0
- package/dist/state/backends.js +96 -0
- package/dist/state/features.d.ts +10 -0
- package/dist/state/features.js +42 -0
- package/dist/state/plugins.d.ts +6 -0
- package/dist/state/plugins.js +27 -0
- package/dist/state/state.d.ts +18 -0
- package/dist/state/state.js +79 -0
- package/dist/state/tasks.d.ts +6 -0
- package/dist/state/tasks.js +33 -0
- package/dist/tools.d.ts +15 -0
- package/dist/tools.js +149 -0
- package/dist/updateconf.d.ts +5 -0
- package/dist/updateconf.js +124 -0
- package/dist/utils/io.d.ts +10 -0
- package/dist/utils/io.js +98 -0
- package/dist/utils/perf.d.ts +9 -0
- package/dist/utils/perf.js +63 -0
- package/dist/utils/sys/clipboard.d.ts +3 -0
- package/dist/utils/sys/clipboard.js +33 -0
- package/dist/utils/sys/delete_file.d.ts +2 -0
- package/dist/utils/sys/delete_file.js +10 -0
- package/dist/utils/sys/dirs.d.ts +2 -0
- package/dist/utils/sys/dirs.js +9 -0
- package/dist/utils/sys/execute.d.ts +13 -0
- package/dist/utils/sys/execute.js +48 -0
- package/dist/utils/sys/read.d.ts +3 -0
- package/dist/utils/sys/read.js +21 -0
- package/dist/utils/sys/read_agent.d.ts +6 -0
- package/dist/utils/sys/read_agent.js +23 -0
- package/dist/utils/sys/read_cmds.d.ts +7 -0
- package/dist/utils/sys/read_cmds.js +37 -0
- package/dist/utils/sys/read_conf.d.ts +6 -0
- package/dist/utils/sys/read_conf.js +12 -0
- package/dist/utils/sys/read_features.d.ts +3 -0
- package/dist/utils/sys/read_features.js +134 -0
- package/dist/utils/sys/read_yml_file.d.ts +5 -0
- package/dist/utils/sys/read_yml_file.js +11 -0
- package/dist/utils/sys/run_python.d.ts +6 -0
- package/dist/utils/sys/run_python.js +39 -0
- package/dist/utils/text.d.ts +2 -0
- package/dist/utils/text.js +28 -0
- package/dist/utils/user_msgs.d.ts +5 -0
- package/dist/utils/user_msgs.js +19 -0
- package/dist/workflows/cmd.d.ts +3 -0
- package/dist/workflows/cmd.js +189 -0
- package/dist/workflows/read.d.ts +6 -0
- package/dist/workflows/read.js +61 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
[](https://www.npmjs.com/package/@agent-smith/core)
|
|
2
|
+
|
|
3
|
+
# @agent-smith/core — Runtime Engine
|
|
4
|
+
|
|
5
|
+
The central runtime engine for the [Agent Smith toolkit](https://github.com/lynxai-team/agent-smith). Provides SQLite-backed configuration management, filesystem-based feature discovery, a unified tool execution engine, and Model Context Protocol (MCP) client integration.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🗄️ **SQLite Configuration** — 17-table database for features, backends, plugins, settings, and workspaces
|
|
10
|
+
- 🔍 **Feature Discovery** — Scans directories for agents, actions, workflows, commands, adaptaters, and skills
|
|
11
|
+
- ⚡ **Unified Tool Execution** — Execute actions (JS/Python/YAML), agents, workflows, and commands through a common interface
|
|
12
|
+
- 🌐 **MCP Client** — Connect to external MCP servers and expose their tools as `ToolSpec` objects
|
|
13
|
+
- 🔧 **Multi-Language Support** — JavaScript (ESM), Python (`python-shell`), and YAML/shell actions
|
|
14
|
+
- 📡 **Reactive State** — Vue `ref`/`reactive` for cross-module state management
|
|
15
|
+
- 🔄 **Backend Agnostic** — Multiple inference backends (OpenAI-compatible, local llamacpp) with per-agent selection
|
|
16
|
+
|
|
17
|
+
## Documentation
|
|
18
|
+
|
|
19
|
+
### For AI Agents
|
|
20
|
+
- [Codebase Summary](.agents/documentation/codebase-summary.md) — Architecture, key files, and patterns for the core package
|
|
21
|
+
- [Configuration](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/libraries/core/2.configuration.md) — Configuration file format, loading, and management
|
|
22
|
+
- [Feature Discovery](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/libraries/core/3.feature-discovery.md) — Directory structure, discovery process, and SQLite registration
|
|
23
|
+
- [Tool Execution](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/libraries/core/4.tool-execution.md) — Execution functions, multi-language support, and error handling
|
|
24
|
+
- [MCP Client](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/libraries/core/5.mcp.md) — MCP server connection, tool extraction, and agent integration
|
|
25
|
+
|
|
26
|
+
### For Humans
|
|
27
|
+
- [Get Started](https://lynxai-team.github.io/agent-smith/libraries/core/get_started) — Installation and basic usage
|
|
28
|
+
- [Configuration](https://lynxai-team.github.io/agent-smith/libraries/core/configuration) — Configuration file format, loading, and management
|
|
29
|
+
- [Feature Discovery](https://lynxai-team.github.io/agent-smith/libraries/core/feature-discovery) — Directory structure, discovery process, and SQLite registration
|
|
30
|
+
- [Tool Execution](https://lynxai-team.github.io/agent-smith/libraries/core/tool-execution) — Execution functions, multi-language support, and error handling
|
|
31
|
+
- [MCP Client](https://lynxai-team.github.io/agent-smith/libraries/core/mcp) — MCP server connection, tool extraction, and agent integration
|
|
32
|
+
|
|
33
|
+
## 📦 Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @agent-smith/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Dependencies:** `@agent-smith/types`, `better-sqlite3`, `@vue/reactivity`, `yaml`, `@modelcontextprotocol/sdk`, `python-shell`
|
|
40
|
+
|
|
41
|
+
## 🚀 Quick Start
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { conf, db, executeAction, executeWorkflow, McpClient } from "@agent-smith/core";
|
|
45
|
+
|
|
46
|
+
// Initialize the database and process configuration
|
|
47
|
+
await conf.updateConfCmd(["conf"]);
|
|
48
|
+
|
|
49
|
+
// Discover and register features from configured paths
|
|
50
|
+
await conf.updateFeaturesCmd({});
|
|
51
|
+
|
|
52
|
+
// Execute an action by name
|
|
53
|
+
const result = await executeAction("read", ["./file.txt"], {});
|
|
54
|
+
|
|
55
|
+
// Or run a workflow that chains multiple steps
|
|
56
|
+
const workflowResult = await executeWorkflow("my-workflow", ["arg1"], {});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 📖 Usage
|
|
60
|
+
|
|
61
|
+
### Configuration Management
|
|
62
|
+
|
|
63
|
+
Load and manage configuration from YAML files:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { conf } from "@agent-smith/core";
|
|
67
|
+
|
|
68
|
+
// Process an existing config file
|
|
69
|
+
const { paths, pf, dd } = await conf.processConfPath("~/.config/agent-smith/config.yml");
|
|
70
|
+
// paths: Array<string> — all feature search paths
|
|
71
|
+
// pf: string — prompt file path
|
|
72
|
+
// dd: string — data directory path
|
|
73
|
+
|
|
74
|
+
// Create a default config if none exists
|
|
75
|
+
const fp = conf.createConfigFileIfNotExists();
|
|
76
|
+
|
|
77
|
+
// Get platform-specific config paths
|
|
78
|
+
const { confDir, dbPath } = conf.getConfigPath("agent-smith", "config.db");
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Feature Discovery
|
|
82
|
+
|
|
83
|
+
Discover and register features from filesystem directories:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { getFeatureSpec, conf } from "@agent-smith/core";
|
|
87
|
+
|
|
88
|
+
// Re-scan all registered feature paths
|
|
89
|
+
await conf.updateFeaturesCmd({});
|
|
90
|
+
|
|
91
|
+
// Look up a feature by name and type
|
|
92
|
+
const spec = getFeatureSpec("writer", "agent");
|
|
93
|
+
if (spec.found) {
|
|
94
|
+
console.log(spec.path); // Full file path
|
|
95
|
+
console.log(spec.ext); // File extension
|
|
96
|
+
console.log(spec.variables); // Variable definitions
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Tool Execution
|
|
101
|
+
|
|
102
|
+
Execute actions, workflows, and agents:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { executeAction, executeWorkflow, executeAgent } from "@agent-smith/core";
|
|
106
|
+
|
|
107
|
+
// Execute a JavaScript action
|
|
108
|
+
const result = await executeAction("read", ["./file.txt"], {});
|
|
109
|
+
|
|
110
|
+
// Execute a YAML action (shell command)
|
|
111
|
+
const grepResult = await executeAction("grep", ["error"], {});
|
|
112
|
+
|
|
113
|
+
// Execute a Python action
|
|
114
|
+
const pythonResult = await executeAction("analyze", ["data.csv"], {});
|
|
115
|
+
|
|
116
|
+
// Run a workflow chaining multiple steps
|
|
117
|
+
const pipelineResult = await executeWorkflow("data-pipeline", ["input.csv"], {
|
|
118
|
+
verbose: true,
|
|
119
|
+
debug: false
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Execute an agent with inference
|
|
123
|
+
const agentResult = await executeAgent("writer", ["AI trends"], {
|
|
124
|
+
model: "llama3",
|
|
125
|
+
temperature: 0.7
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Agent Executor
|
|
130
|
+
|
|
131
|
+
Create a full agent execution context:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import { useAgentExecutor } from "@agent-smith/core";
|
|
135
|
+
|
|
136
|
+
const executor = await useAgentExecutor("researcher", { prompt: "Analyze the data" }, {});
|
|
137
|
+
const result = await executor.execute();
|
|
138
|
+
// Returns: InferenceResult
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The executor handles backend resolution, MCP server initialization, grammar compilation, and streaming.
|
|
142
|
+
|
|
143
|
+
### Reactive State
|
|
144
|
+
|
|
145
|
+
Access and manage reactive state:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { state } from "@agent-smith/core";
|
|
149
|
+
|
|
150
|
+
// List all inference backends
|
|
151
|
+
const backends = state.listBackends();
|
|
152
|
+
|
|
153
|
+
// Set the default backend
|
|
154
|
+
await state.setBackend("openai");
|
|
155
|
+
|
|
156
|
+
// Get per-agent inference settings
|
|
157
|
+
const settings = state.getAgentSettings();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### MCP Client
|
|
161
|
+
|
|
162
|
+
Connect to external MCP servers:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { McpClient } from "@agent-smith/core";
|
|
166
|
+
|
|
167
|
+
const client = new McpClient(
|
|
168
|
+
"filesystem", // server name
|
|
169
|
+
"npx", // command
|
|
170
|
+
["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], // args
|
|
171
|
+
null, // authorizedTools (null = all allowed)
|
|
172
|
+
null // askUserTools (null = no confirmation needed)
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// Start the server connection
|
|
176
|
+
await client.start();
|
|
177
|
+
|
|
178
|
+
// Extract tools as ToolSpec objects
|
|
179
|
+
const tools = await client.extractTools({ confirmToolUsage });
|
|
180
|
+
|
|
181
|
+
// Stop the connection
|
|
182
|
+
await client.stop();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## 🔧 Complete Example
|
|
186
|
+
|
|
187
|
+
A full working example demonstrating configuration, feature discovery, and execution:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import {
|
|
191
|
+
conf,
|
|
192
|
+
db,
|
|
193
|
+
state,
|
|
194
|
+
executeAction,
|
|
195
|
+
executeWorkflow,
|
|
196
|
+
useAgentExecutor,
|
|
197
|
+
getFeatureSpec,
|
|
198
|
+
McpClient
|
|
199
|
+
} from "@agent-smith/core";
|
|
200
|
+
|
|
201
|
+
async function main() {
|
|
202
|
+
// Step 1: Initialize database and configuration
|
|
203
|
+
console.log("Initializing...");
|
|
204
|
+
await conf.updateConfCmd(["conf"]);
|
|
205
|
+
|
|
206
|
+
// Verify state readiness
|
|
207
|
+
if (!state.isStateReady()) {
|
|
208
|
+
throw new Error("Configuration not loaded");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Step 2: Discover features from all registered paths
|
|
212
|
+
console.log("Discovering features...");
|
|
213
|
+
await conf.updateFeaturesCmd({});
|
|
214
|
+
|
|
215
|
+
// Step 3: Look up a feature
|
|
216
|
+
const agentSpec = getFeatureSpec("writer", "agent");
|
|
217
|
+
if (!agentSpec.found) {
|
|
218
|
+
throw new Error("Writer agent not found");
|
|
219
|
+
}
|
|
220
|
+
console.log(`Found agent at: ${agentSpec.path}`);
|
|
221
|
+
|
|
222
|
+
// Step 4: Execute an action
|
|
223
|
+
console.log("Executing read action...");
|
|
224
|
+
const fileContent = await executeAction("read", ["./README.md"], {});
|
|
225
|
+
console.log(`File content length: ${fileContent.length}`);
|
|
226
|
+
|
|
227
|
+
// Step 5: Run a workflow
|
|
228
|
+
console.log("Running workflow...");
|
|
229
|
+
try {
|
|
230
|
+
const result = await executeWorkflow("my-pipeline", ["input.txt"], {
|
|
231
|
+
verbose: true
|
|
232
|
+
});
|
|
233
|
+
console.log("Workflow completed:", result);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
console.error("Workflow failed:", e.message);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Step 6: Execute an agent
|
|
239
|
+
console.log("Running agent...");
|
|
240
|
+
try {
|
|
241
|
+
const executor = await useAgentExecutor("writer", { prompt: "Write about AI" }, {});
|
|
242
|
+
const inferenceResult = await executor.execute();
|
|
243
|
+
console.log("Agent response:", inferenceResult.content);
|
|
244
|
+
} catch (e) {
|
|
245
|
+
console.error("Agent execution failed:", e.message);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Step 7: Use MCP client for external tools
|
|
249
|
+
console.log("Setting up MCP client...");
|
|
250
|
+
const mcpClient = new McpClient(
|
|
251
|
+
"filesystem",
|
|
252
|
+
"npx",
|
|
253
|
+
["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
await mcpClient.start();
|
|
258
|
+
const tools = await mcpClient.extractTools({ confirmToolUsage: async () => true });
|
|
259
|
+
console.log(`Loaded ${tools.length} MCP tools`);
|
|
260
|
+
} finally {
|
|
261
|
+
await mcpClient.stop();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log("Done!");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
main().catch(console.error);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## 📋 API Reference
|
|
271
|
+
|
|
272
|
+
### Named Exports
|
|
273
|
+
|
|
274
|
+
| Export | Type | Description |
|
|
275
|
+
|--------|------|-------------|
|
|
276
|
+
| `db` | `object` | Database operations: `init`, `...readOps`, `...writeOps`, `db` (raw better-sqlite3) |
|
|
277
|
+
| `fs` | `object` | Filesystem helpers: `openAgentSpec`, `readWorkflow` |
|
|
278
|
+
| `conf` | `object` | Configuration management: `getConfigPath`, `processConfPath`, `updateConfigFile`, etc. |
|
|
279
|
+
| `utils` | `object` | Utilities: `execute`, `runShellCmd`, `deleteFileIfExists`, `readAgent`, etc. |
|
|
280
|
+
| `state` | `object` | Reactive state: `init`, `initState`, `setBackend`, `listBackends`, `agentSettings`, etc. |
|
|
281
|
+
| `executeAction` | `function` | Execute an action by name |
|
|
282
|
+
| `executeWorkflow` | `function` | Execute a workflow by name |
|
|
283
|
+
| `executeAgent` | `function` | Execute an agent by name |
|
|
284
|
+
| `useAgentExecutor` | `function` | Create an agent execution context |
|
|
285
|
+
| `getFeatureSpec` | `function` | Look up a feature by name and type |
|
|
286
|
+
| `extractToolDoc` | `function` | Extract tool specification from a feature file |
|
|
287
|
+
| `McpClient` | `class` | MCP server client for external tool integration |
|
|
288
|
+
|
|
289
|
+
### `executeAction(name, payload, options)`
|
|
290
|
+
|
|
291
|
+
Executes an action by name, resolving it from the SQLite database.
|
|
292
|
+
|
|
293
|
+
| Parameter | Type | Description |
|
|
294
|
+
|-----------|------|-------------|
|
|
295
|
+
| `name` | `string` | Action name (matches registered feature) |
|
|
296
|
+
| `payload` | `Array<string>` | Arguments passed to the action |
|
|
297
|
+
| `options` | `object` | Execution options (`debug`, `verbose`) |
|
|
298
|
+
|
|
299
|
+
**Returns:** `Promise<any>` — Action result
|
|
300
|
+
|
|
301
|
+
**Dispatch by extension:**
|
|
302
|
+
- `.js`: Dynamically imports and calls exported `action(args, options)`
|
|
303
|
+
- `.yml`: Executes YAML-defined shell command with args
|
|
304
|
+
- `.py`: Runs via `python-shell` package
|
|
305
|
+
|
|
306
|
+
### `executeWorkflow(name, args, options)`
|
|
307
|
+
|
|
308
|
+
Executes a workflow as a sequence of steps (agent/action/adaptater/cmd).
|
|
309
|
+
|
|
310
|
+
| Parameter | Type | Description |
|
|
311
|
+
|-----------|------|-------------|
|
|
312
|
+
| `name` | `string` | Workflow name |
|
|
313
|
+
| `args` | `Array<string>` | Initial arguments for the first step |
|
|
314
|
+
| `options` | `object` | Execution options (`verbose`, `debug`) |
|
|
315
|
+
|
|
316
|
+
**Returns:** `Promise<any>` — Result of the final step
|
|
317
|
+
|
|
318
|
+
### `executeAgent(name, args, options)`
|
|
319
|
+
|
|
320
|
+
Executes an agent by resolving its prompt and running inference.
|
|
321
|
+
|
|
322
|
+
| Parameter | Type | Description |
|
|
323
|
+
|-----------|------|-------------|
|
|
324
|
+
| `name` | `string` | Agent name |
|
|
325
|
+
| `args` | `Array<string>` | Arguments for prompt generation |
|
|
326
|
+
| `options` | `object` | Inference options (`model`, `temperature`, etc.) |
|
|
327
|
+
|
|
328
|
+
**Returns:** `Promise<InferenceResult>` — Agent inference result
|
|
329
|
+
|
|
330
|
+
### `useAgentExecutor(name, payload, options)`
|
|
331
|
+
|
|
332
|
+
Creates an agent execution context with full setup.
|
|
333
|
+
|
|
334
|
+
| Parameter | Type | Description |
|
|
335
|
+
|-----------|------|-------------|
|
|
336
|
+
| `name` | `string` | Agent name |
|
|
337
|
+
| `payload` | `object` | Payload including `prompt` and optional context |
|
|
338
|
+
| `options` | `object` | Execution options |
|
|
339
|
+
|
|
340
|
+
**Returns:** `Promise<{ execute: () => Promise<InferenceResult> }>`
|
|
341
|
+
|
|
342
|
+
### `getFeatureSpec(name, type)`
|
|
343
|
+
|
|
344
|
+
Looks up a feature in the SQLite database.
|
|
345
|
+
|
|
346
|
+
| Parameter | Type | Description |
|
|
347
|
+
|-----------|------|-------------|
|
|
348
|
+
| `name` | `string` | Feature name |
|
|
349
|
+
| `type` | `"agent" \| "action" \| "workflow" \| "adaptater" \| "cmd" \| "skill"` | Feature type |
|
|
350
|
+
|
|
351
|
+
**Returns:** `{ found: boolean; path?: string; ext?: string; variables?: Record<string, any> }`
|
|
352
|
+
|
|
353
|
+
### `McpClient` Class
|
|
354
|
+
|
|
355
|
+
| Constructor | `(servername: string, command: string, args: Array<string>, authorizedTools?: Array<string> \| null, askUserTools?: Array<string> \| null)` |
|
|
356
|
+
|-------------|--------------------------------------------------------------------------------------------------------------------------|
|
|
357
|
+
| `start()` | `async () => Promise<void>` — Connect to the MCP server via stdio transport |
|
|
358
|
+
| `stop()` | `async () => Promise<void>` — Close the connection |
|
|
359
|
+
| `extractTools(options)` | `async (options: { confirmToolUsage?: Function }) => Promise<Array<ToolSpec>>` — Extract tools as ToolSpec objects |
|
|
360
|
+
|
|
361
|
+
## ⚠️ Important Notes
|
|
362
|
+
|
|
363
|
+
- **Node.js Environment**: This package is designed for Node.js environments. It depends on `better-sqlite3` which requires native compilation.
|
|
364
|
+
- **SQLite First Run**: The database is initialized automatically on first use with 17 tables. No manual migration needed.
|
|
365
|
+
- **Feature Discovery Required**: Before executing features, you must call `conf.updateConfCmd()` and `conf.updateFeaturesCmd()` to discover and register them.
|
|
366
|
+
- **Python Actions**: Require `python-shell` package and a working Python installation.
|
|
367
|
+
- **MCP Servers**: External MCP servers are spawned as child processes. Ensure required binaries (e.g., `npx`) are available.
|
|
368
|
+
- **Related Packages**: See `@agent-smith/types` for shared interfaces, `@agent-smith/agent` for the Agent class, `@agent-smith/cli` for CLI usage.
|
|
369
|
+
|
|
370
|
+
## 📖 Documentation Links
|
|
371
|
+
|
|
372
|
+
- [Full docsite](https://lynxai-team.github.io/agent-smith/) — Complete project documentation
|
|
373
|
+
- [Architecture Overview](https://lynxai-team.github.io/agent-smith/architecture/overview) — System architecture and design principles
|
|
374
|
+
- [Tool Abstraction](https://lynxai-team.github.io/agent-smith/architecture/tool-abstraction) — Unified `ToolSpec` interface
|
|
375
|
+
|
|
376
|
+
## 📄 License
|
|
377
|
+
|
|
378
|
+
MIT
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FeatureExecutor } from "@agent-smith/types";
|
|
2
|
+
declare function executeAction(name: string, payload: any, options: Record<string, any>, quiet?: boolean): Promise<any>;
|
|
3
|
+
declare function systemAction(path: string): FeatureExecutor<Array<string>, any>;
|
|
4
|
+
declare function pythonAction(path: string, options: Record<string, any>): FeatureExecutor<Array<string>>;
|
|
5
|
+
export { executeAction, pythonAction, systemAction };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { pathToFileURL } from 'url';
|
|
2
|
+
import { getFeatureSpec } from '../state/features.js';
|
|
3
|
+
import { pyShell } from "../state/state.js";
|
|
4
|
+
import { getInputFromOptions, processOutput } from "../utils/io.js";
|
|
5
|
+
import { execute } from "../utils/sys/execute.js";
|
|
6
|
+
import { readYmlFile } from "../utils/sys/read_yml_file.js";
|
|
7
|
+
import { runPyScript } from "../utils/sys/run_python.js";
|
|
8
|
+
import { runtimeError } from "../utils/user_msgs.js";
|
|
9
|
+
import { createJsAction } from "./read.js";
|
|
10
|
+
async function executeAction(name, payload, options, quiet = false) {
|
|
11
|
+
let run;
|
|
12
|
+
//console.log("GET ACTION", name, payload);
|
|
13
|
+
const inputData = await getInputFromOptions(options);
|
|
14
|
+
if (inputData) {
|
|
15
|
+
if (Array.isArray(payload)) {
|
|
16
|
+
payload.push(inputData);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const { found, path, ext } = getFeatureSpec(name, "action");
|
|
20
|
+
if (!found) {
|
|
21
|
+
throw new Error(`Action ${name} not found at ${path}`);
|
|
22
|
+
}
|
|
23
|
+
//console.log("CREATE ACTION", name, ext, path);
|
|
24
|
+
switch (ext) {
|
|
25
|
+
case "js":
|
|
26
|
+
const url = pathToFileURL(path).href;
|
|
27
|
+
//console.log("CR JSA", url);
|
|
28
|
+
const mjsa = await import(/* @vite-ignore */ url);
|
|
29
|
+
run = createJsAction(mjsa.action);
|
|
30
|
+
//console.log("END CR JSA")
|
|
31
|
+
break;
|
|
32
|
+
case "yml":
|
|
33
|
+
run = systemAction(path);
|
|
34
|
+
break;
|
|
35
|
+
case "py":
|
|
36
|
+
run = pythonAction(path, options);
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
throw new Error(`Action ext ${ext} not implemented`);
|
|
40
|
+
}
|
|
41
|
+
//console.log("RUN", payload);
|
|
42
|
+
const res = await run(payload, options);
|
|
43
|
+
if (!quiet) {
|
|
44
|
+
if (res) {
|
|
45
|
+
console.log(res);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
await processOutput(res);
|
|
49
|
+
return res;
|
|
50
|
+
}
|
|
51
|
+
function systemAction(path) {
|
|
52
|
+
const run = async (params) => {
|
|
53
|
+
//console.log("SYS ACTION PARAMS", params);
|
|
54
|
+
let runArgs = new Array();
|
|
55
|
+
// convert args for tool calls
|
|
56
|
+
if (!Array.isArray(params)) {
|
|
57
|
+
try {
|
|
58
|
+
// obviously a tool call
|
|
59
|
+
if (typeof params == "string") {
|
|
60
|
+
runArgs.push(params);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
runArgs = Object.values(params);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
throw new Error(`wrong python action args: ${e}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
runArgs = params;
|
|
72
|
+
}
|
|
73
|
+
const actionSpec = readYmlFile(path);
|
|
74
|
+
if (!actionSpec.found) {
|
|
75
|
+
runtimeError("System action yml file", path, "not found");
|
|
76
|
+
}
|
|
77
|
+
//console.log("Yml action", JSON.stringify(actionSpec.data, null, " "));
|
|
78
|
+
//console.log("Args", args)
|
|
79
|
+
if (!actionSpec.data?.args) {
|
|
80
|
+
actionSpec.data.args = [];
|
|
81
|
+
}
|
|
82
|
+
//console.log("EXEC", actionSpec.data.cmd, [...actionSpec.data.args, ...runArgs]);
|
|
83
|
+
const out = await execute(actionSpec.data.cmd, [...actionSpec.data.args, ...runArgs]);
|
|
84
|
+
return out.trim();
|
|
85
|
+
};
|
|
86
|
+
return run;
|
|
87
|
+
}
|
|
88
|
+
function pythonAction(path, options) {
|
|
89
|
+
const run = async (params) => {
|
|
90
|
+
//console.log("PY ACTION PARAMS", params);
|
|
91
|
+
let runArgs = new Array();
|
|
92
|
+
if (!Array.isArray(params)) {
|
|
93
|
+
try {
|
|
94
|
+
// obviously a tool call
|
|
95
|
+
if (typeof params == "string") {
|
|
96
|
+
runArgs.push(params);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
runArgs = Object.values(params);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
throw new Error(`wrong python action args: ${e}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
runArgs = params;
|
|
108
|
+
}
|
|
109
|
+
//console.log("Py action", path);
|
|
110
|
+
const { data, error } = await runPyScript(pyShell, "python3", path, runArgs);
|
|
111
|
+
/*console.log("----------------");
|
|
112
|
+
console.log("PYOUT", data);
|
|
113
|
+
console.log("----------------");*/
|
|
114
|
+
if (error) {
|
|
115
|
+
throw new Error(`python error: ${error}`);
|
|
116
|
+
}
|
|
117
|
+
let txt = data[0];
|
|
118
|
+
if (data.length > 1) {
|
|
119
|
+
txt = data.join("\n");
|
|
120
|
+
}
|
|
121
|
+
let final = txt;
|
|
122
|
+
/*if ((txt.startsWith("{") || txt.startsWith("[")) && !options?.isToolCall) {
|
|
123
|
+
try {
|
|
124
|
+
final = JSON.parse(txt)
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.warn("Can not parse json from python action", path, e)
|
|
127
|
+
//throw new Error(`python error: ${error}`)
|
|
128
|
+
}
|
|
129
|
+
}*/
|
|
130
|
+
console.log("PYTC TXT", final);
|
|
131
|
+
return final;
|
|
132
|
+
};
|
|
133
|
+
return run;
|
|
134
|
+
}
|
|
135
|
+
export { executeAction, pythonAction, systemAction };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function createJsAction(action) {
|
|
2
|
+
const run = async (args, options) => {
|
|
3
|
+
//console.log("JS ACTION PARAMS", args);
|
|
4
|
+
try {
|
|
5
|
+
const res = await action(args, options);
|
|
6
|
+
return res;
|
|
7
|
+
}
|
|
8
|
+
catch (e) {
|
|
9
|
+
/*if (e?.text) {
|
|
10
|
+
throw new Error(`executing action:${e.text()}. Args: ${args}`);
|
|
11
|
+
}*/
|
|
12
|
+
throw new Error(`executing js action:${e}. Args: ${JSON.stringify(args, null, 2)}`);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
return run;
|
|
16
|
+
}
|
|
17
|
+
export { createJsAction };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getFeatureSpec } from "../state/features.js";
|
|
2
|
+
import { createJsAction } from "../actions/read.js";
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
4
|
+
import { getInputFromOptions } from "../utils/io.js";
|
|
5
|
+
async function executeAdaptater(name, params, options) {
|
|
6
|
+
/*if (params?.args) {
|
|
7
|
+
params = params.args;
|
|
8
|
+
}*/
|
|
9
|
+
const { found, path } = getFeatureSpec(name, "adaptater");
|
|
10
|
+
if (!found) {
|
|
11
|
+
throw new Error(`adaptater ${name} not found`);
|
|
12
|
+
}
|
|
13
|
+
const inputData = await getInputFromOptions(options);
|
|
14
|
+
if (inputData) {
|
|
15
|
+
if (Array.isArray(params)) {
|
|
16
|
+
params.push(inputData);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let run;
|
|
20
|
+
const url = pathToFileURL(path).href;
|
|
21
|
+
const jsa = await import(/* @vite-ignore */ url);
|
|
22
|
+
run = createJsAction(jsa.action);
|
|
23
|
+
let res;
|
|
24
|
+
try {
|
|
25
|
+
//console.log("ADAPT RUN PARAMS", params);
|
|
26
|
+
res = await run(params, options);
|
|
27
|
+
//console.log("ADAPT RES", res);
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
throw new Error(`adaptater ${name}: ${e}`);
|
|
31
|
+
}
|
|
32
|
+
if (res?.error) {
|
|
33
|
+
throw res.error;
|
|
34
|
+
}
|
|
35
|
+
//await processOutput(res);
|
|
36
|
+
//console.log("ADRES", res);
|
|
37
|
+
return res;
|
|
38
|
+
}
|
|
39
|
+
export { executeAdaptater, };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AgentInferenceOptions, InferenceResult } from "@agent-smith/types";
|
|
2
|
+
declare function executeAgent(name: string, args: Array<any> | Record<string, any>, options: AgentInferenceOptions & Record<string, any>): Promise<InferenceResult>;
|
|
3
|
+
export { executeAgent, };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getAgentPrompt } from "../utils/io.js";
|
|
2
|
+
import { useAgentExecutor } from "./useagent.js";
|
|
3
|
+
async function executeAgent(name, args, options) {
|
|
4
|
+
//console.log("EXEC AGENT", args, "\n", options);
|
|
5
|
+
const prompt = await getAgentPrompt(name, args, options);
|
|
6
|
+
const exec = await useAgentExecutor(name, { prompt: prompt }, options);
|
|
7
|
+
const res = exec.execute();
|
|
8
|
+
return res;
|
|
9
|
+
}
|
|
10
|
+
export { executeAgent, };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
function _replaceFilePlaceholders(text, baseDir) {
|
|
4
|
+
const fileRegex = /\{file:(.*?)\}/g;
|
|
5
|
+
// The replace function is called for each match
|
|
6
|
+
const resultText = text.replace(fileRegex, (match, filePath) => {
|
|
7
|
+
if (!baseDir) {
|
|
8
|
+
if (!path.isAbsolute(filePath)) {
|
|
9
|
+
throw new Error(`Can not replace relative file placeholder ${filePath} without a baseDir set. Use absolute paths or set a baseDir in options`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
// Resolve the absolute path relative to the baseDir (or current working directory)
|
|
13
|
+
const fullPath = path.resolve(baseDir, filePath);
|
|
14
|
+
try {
|
|
15
|
+
const fileContent = fs.readFileSync(fullPath, 'utf8');
|
|
16
|
+
return fileContent;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const msg = `Error reading file placeholder at ${fullPath}: ${error}`;
|
|
20
|
+
throw new Error(msg);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return resultText;
|
|
24
|
+
}
|
|
25
|
+
function applyFilePlaceholders(def, baseDir) {
|
|
26
|
+
def.prompt = _replaceFilePlaceholders(def.prompt, baseDir);
|
|
27
|
+
if (def.template) {
|
|
28
|
+
if (def.template?.system) {
|
|
29
|
+
def.template.system = _replaceFilePlaceholders(def.template.system, baseDir);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (def?.shots) {
|
|
33
|
+
def.shots.forEach(s => {
|
|
34
|
+
if (s?.assistant) {
|
|
35
|
+
s.assistant = _replaceFilePlaceholders(def.prompt, baseDir);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export { applyFilePlaceholders };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentInferenceOptions, AgentSpec } from "@agent-smith/types";
|
|
2
|
+
import { McpClient } from "../mcp.js";
|
|
3
|
+
declare function readAgent(name: string, payload: {
|
|
4
|
+
prompt: string;
|
|
5
|
+
} & Record<string, any>, options: AgentInferenceOptions & Record<string, any>): Promise<{
|
|
6
|
+
agentSpec: AgentSpec;
|
|
7
|
+
vars: Record<string, any>;
|
|
8
|
+
mcpServers: Array<McpClient>;
|
|
9
|
+
agentDir: string;
|
|
10
|
+
}>;
|
|
11
|
+
export { readAgent };
|