@agentxjs/runtime 0.1.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/LICENSE +21 -0
- package/README.md +598 -0
- package/dist/index.cjs +3214 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +131 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.js +3176 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Deepractice
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
# @agentxjs/runtime
|
|
2
|
+
|
|
3
|
+
> Complete Runtime implementation for AI Agents with Claude SDK integration
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@agentxjs/runtime` provides the complete runtime infrastructure for AI agents, including:
|
|
8
|
+
|
|
9
|
+
- **SystemBus** - Event-driven communication backbone
|
|
10
|
+
- **Container** - Agent lifecycle management
|
|
11
|
+
- **Environment** (Receptor + Effector) - External world interface (Claude SDK)
|
|
12
|
+
- **Session** - Message persistence
|
|
13
|
+
- **Persistence** - Storage layer (SQLite, Memory)
|
|
14
|
+
|
|
15
|
+
**Key Features:**
|
|
16
|
+
|
|
17
|
+
- **Event-Driven Architecture** - All operations via command events
|
|
18
|
+
- **Claude SDK Integration** - Production-ready ClaudeEnvironment
|
|
19
|
+
- **Pluggable Storage** - SQLite, Memory, or custom backends
|
|
20
|
+
- **Type-Safe Commands** - Request/response pattern with full typing
|
|
21
|
+
- **Cross-Platform** - Works in Node.js (Browser support via agentxjs)
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @agentxjs/runtime
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Dependencies:**
|
|
30
|
+
|
|
31
|
+
- `@anthropic-ai/claude-agent-sdk` - Claude API client
|
|
32
|
+
- `better-sqlite3` - SQLite database (optional, for persistence)
|
|
33
|
+
- `unstorage` - Unified storage layer
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Minimal Setup
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { createRuntime } from "@agentxjs/runtime";
|
|
43
|
+
|
|
44
|
+
// Minimal - uses environment variable ANTHROPIC_API_KEY
|
|
45
|
+
const runtime = createRuntime();
|
|
46
|
+
|
|
47
|
+
// Subscribe to events
|
|
48
|
+
runtime.on("text_delta", (e) => {
|
|
49
|
+
console.log(e.data.text);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Create container
|
|
53
|
+
const containerRes = await runtime.request("container_create_request", {
|
|
54
|
+
containerId: "my-container",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Run agent
|
|
58
|
+
const agentRes = await runtime.request("agent_run_request", {
|
|
59
|
+
containerId: "my-container",
|
|
60
|
+
config: {
|
|
61
|
+
name: "Assistant",
|
|
62
|
+
systemPrompt: "You are a helpful assistant",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Send message
|
|
67
|
+
await runtime.request("agent_receive_request", {
|
|
68
|
+
agentId: agentRes.data.agentId,
|
|
69
|
+
content: "Hello!",
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Cleanup
|
|
73
|
+
await runtime.dispose();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### With Configuration
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { createRuntime, createPersistence } from "@agentxjs/runtime";
|
|
80
|
+
|
|
81
|
+
const runtime = createRuntime({
|
|
82
|
+
// LLM configuration
|
|
83
|
+
llm: {
|
|
84
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
85
|
+
baseUrl: "https://api.anthropic.com",
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
// Persistence
|
|
89
|
+
persistence: createPersistence({
|
|
90
|
+
driver: "sqlite",
|
|
91
|
+
options: {
|
|
92
|
+
filename: "./data.db",
|
|
93
|
+
},
|
|
94
|
+
}),
|
|
95
|
+
|
|
96
|
+
// Logger
|
|
97
|
+
logger: {
|
|
98
|
+
level: "info",
|
|
99
|
+
enableTimestamp: true,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Architecture
|
|
107
|
+
|
|
108
|
+
### System Overview
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
┌────────────────────────────────────────────────────────────────┐
|
|
112
|
+
│ Runtime │
|
|
113
|
+
├────────────────────────────────────────────────────────────────┤
|
|
114
|
+
│ │
|
|
115
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
116
|
+
│ │ SystemBus │ │
|
|
117
|
+
│ │ (Central event bus - all communication flows here) │ │
|
|
118
|
+
│ └──────────────────────┬──────────────────────────────────┘ │
|
|
119
|
+
│ │ │
|
|
120
|
+
│ ┌───────────────┼───────────────┐ │
|
|
121
|
+
│ │ │ │ │
|
|
122
|
+
│ ▼ ▼ ▼ │
|
|
123
|
+
│ ┌─────────────┐ ┌──────────┐ ┌────────────┐ │
|
|
124
|
+
│ │Environment │ │Container │ │Persistence │ │
|
|
125
|
+
│ │ │ │ │ │ │ │
|
|
126
|
+
│ │ Receptor │ │ Agent1 │ │ SQLite │ │
|
|
127
|
+
│ │ Effector │ │ Agent2 │ │ Images │ │
|
|
128
|
+
│ │ (Claude SDK)│ │ Agent3 │ │ Sessions │ │
|
|
129
|
+
│ └─────────────┘ └──────────┘ └────────────┘ │
|
|
130
|
+
│ │
|
|
131
|
+
└────────────────────────────────────────────────────────────────┘
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Component Responsibilities
|
|
135
|
+
|
|
136
|
+
| Component | Role | Examples |
|
|
137
|
+
| --------------- | ------------------------ | --------------------------------- |
|
|
138
|
+
| **SystemBus** | Event distribution | Emit, subscribe, request/response |
|
|
139
|
+
| **Environment** | External world interface | Claude API calls, streaming |
|
|
140
|
+
| **Container** | Agent lifecycle | Create, destroy, manage agents |
|
|
141
|
+
| **Session** | Message persistence | Save/load conversation history |
|
|
142
|
+
| **Persistence** | Storage backend | SQLite, Memory, custom |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## SystemBus - Event Backbone
|
|
147
|
+
|
|
148
|
+
All Runtime operations go through the SystemBus using **command events**.
|
|
149
|
+
|
|
150
|
+
### Request/Response Pattern
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Type-safe request
|
|
154
|
+
const response = await runtime.request("container_create_request", {
|
|
155
|
+
containerId: "my-container",
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Response is fully typed
|
|
159
|
+
console.log(response.data.containerId); // ✓ TypeScript knows this exists
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Event Subscription
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Subscribe to specific event type
|
|
166
|
+
runtime.on("text_delta", (event) => {
|
|
167
|
+
console.log(event.data.text);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Subscribe to multiple types
|
|
171
|
+
runtime.on(["message_start", "message_stop"], (event) => {
|
|
172
|
+
console.log(event.type);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Subscribe to all events
|
|
176
|
+
runtime.onAny((event) => {
|
|
177
|
+
console.log(event.type, event.data);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Unsubscribe
|
|
181
|
+
const unsubscribe = runtime.on("text_delta", handler);
|
|
182
|
+
unsubscribe();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Available Commands
|
|
186
|
+
|
|
187
|
+
#### Container Commands
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Create container
|
|
191
|
+
const res = await runtime.request("container_create_request", {
|
|
192
|
+
containerId: "my-container",
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Destroy container
|
|
196
|
+
await runtime.request("container_destroy_request", {
|
|
197
|
+
containerId: "my-container",
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### Agent Commands
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// Run agent
|
|
205
|
+
const res = await runtime.request("agent_run_request", {
|
|
206
|
+
containerId: "my-container",
|
|
207
|
+
config: {
|
|
208
|
+
name: "Assistant",
|
|
209
|
+
systemPrompt: "You are helpful",
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Send message
|
|
214
|
+
await runtime.request("agent_receive_request", {
|
|
215
|
+
agentId: res.data.agentId,
|
|
216
|
+
content: "Hello!",
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Interrupt agent
|
|
220
|
+
await runtime.request("agent_interrupt_request", {
|
|
221
|
+
agentId: res.data.agentId,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Destroy agent
|
|
225
|
+
await runtime.request("agent_destroy_request", {
|
|
226
|
+
agentId: res.data.agentId,
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### Session Commands
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// Create session
|
|
234
|
+
await runtime.request("session_create_request", {
|
|
235
|
+
sessionId: "session_123",
|
|
236
|
+
containerId: "my-container",
|
|
237
|
+
agentId: "agent_123",
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Get session
|
|
241
|
+
const res = await runtime.request("session_get_request", {
|
|
242
|
+
sessionId: "session_123",
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Delete session
|
|
246
|
+
await runtime.request("session_delete_request", {
|
|
247
|
+
sessionId: "session_123",
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Direct Command Emission
|
|
252
|
+
|
|
253
|
+
For advanced use cases:
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// Emit command directly (fire and forget)
|
|
257
|
+
runtime.emitCommand("agent_receive_request", {
|
|
258
|
+
requestId: "req_123",
|
|
259
|
+
agentId: "agent_123",
|
|
260
|
+
content: "Hello!",
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Listen for response
|
|
264
|
+
runtime.onCommand("agent_receive_response", (event) => {
|
|
265
|
+
if (event.data.requestId === "req_123") {
|
|
266
|
+
console.log("Response:", event.data);
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Environment - External World Interface
|
|
274
|
+
|
|
275
|
+
Environment connects Runtime to the external world (Claude API).
|
|
276
|
+
|
|
277
|
+
### ClaudeEnvironment
|
|
278
|
+
|
|
279
|
+
Built-in implementation using `@anthropic-ai/claude-agent-sdk`:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { createRuntime } from "@agentxjs/runtime";
|
|
283
|
+
|
|
284
|
+
const runtime = createRuntime({
|
|
285
|
+
llm: {
|
|
286
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
287
|
+
baseUrl: "https://api.anthropic.com",
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Architecture
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
┌────────────────────────────────────────────────────────────┐
|
|
296
|
+
│ Environment │
|
|
297
|
+
├────────────────────────────────────────────────────────────┤
|
|
298
|
+
│ │
|
|
299
|
+
│ Receptor (Perceives external world → emits to SystemBus) │
|
|
300
|
+
│ │ │
|
|
301
|
+
│ │ Claude API Streaming Response │
|
|
302
|
+
│ ▼ │
|
|
303
|
+
│ ┌──────────────────────────────────────────────────────┐ │
|
|
304
|
+
│ │ Transforms Claude SDK events → DriveableEvent │ │
|
|
305
|
+
│ │ (message_delta, tool_use, etc.) │ │
|
|
306
|
+
│ └──────────────────────────────────────────────────────┘ │
|
|
307
|
+
│ │ │
|
|
308
|
+
│ │ emit to SystemBus │
|
|
309
|
+
│ ▼ │
|
|
310
|
+
│ SystemBus │
|
|
311
|
+
│ │ │
|
|
312
|
+
│ │ subscribe │
|
|
313
|
+
│ ▼ │
|
|
314
|
+
│ Effector (Subscribes to SystemBus → acts on external world)│
|
|
315
|
+
│ │ │
|
|
316
|
+
│ │ Executes tool calls │
|
|
317
|
+
│ ▼ │
|
|
318
|
+
│ External Tools (MCP, filesystem, etc.) │
|
|
319
|
+
│ │
|
|
320
|
+
└────────────────────────────────────────────────────────────┘
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Container - Agent Lifecycle
|
|
326
|
+
|
|
327
|
+
Container manages multiple agents:
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
// Via command events (recommended)
|
|
331
|
+
const res = await runtime.request("container_create_request", {
|
|
332
|
+
containerId: "my-container",
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// Run agents in container
|
|
336
|
+
const agent1 = await runtime.request("agent_run_request", {
|
|
337
|
+
containerId: "my-container",
|
|
338
|
+
config: { name: "Agent1" },
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const agent2 = await runtime.request("agent_run_request", {
|
|
342
|
+
containerId: "my-container",
|
|
343
|
+
config: { name: "Agent2" },
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Destroy container (destroys all agents)
|
|
347
|
+
await runtime.request("container_destroy_request", {
|
|
348
|
+
containerId: "my-container",
|
|
349
|
+
});
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Persistence - Storage Layer
|
|
355
|
+
|
|
356
|
+
### Built-in Storage Backends
|
|
357
|
+
|
|
358
|
+
#### SQLite (Production)
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
import { createRuntime, createPersistence } from "@agentxjs/runtime";
|
|
362
|
+
|
|
363
|
+
const runtime = createRuntime({
|
|
364
|
+
persistence: createPersistence({
|
|
365
|
+
driver: "sqlite",
|
|
366
|
+
options: {
|
|
367
|
+
filename: "./data.db",
|
|
368
|
+
},
|
|
369
|
+
}),
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
#### Memory (Development)
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
const runtime = createRuntime({
|
|
377
|
+
persistence: createPersistence({
|
|
378
|
+
driver: "memory",
|
|
379
|
+
}),
|
|
380
|
+
});
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Storage Schema
|
|
384
|
+
|
|
385
|
+
Persistence stores:
|
|
386
|
+
|
|
387
|
+
- **Images** - Agent snapshots with conversation history
|
|
388
|
+
- **Containers** - Container metadata
|
|
389
|
+
- **Sessions** - Message history per agent
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
// Save agent image
|
|
393
|
+
const image = await runtime.request("image_snapshot_request", {
|
|
394
|
+
agentId: "agent_123",
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// Resume from image
|
|
398
|
+
const agent = await runtime.request("image_resume_request", {
|
|
399
|
+
imageId: image.data.imageId,
|
|
400
|
+
});
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Advanced Usage
|
|
406
|
+
|
|
407
|
+
### Custom Persistence Backend
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { type StorageDriver } from "@agentxjs/runtime";
|
|
411
|
+
|
|
412
|
+
const customDriver: StorageDriver = {
|
|
413
|
+
async getItem(key) {
|
|
414
|
+
// Fetch from your backend
|
|
415
|
+
},
|
|
416
|
+
async setItem(key, value) {
|
|
417
|
+
// Save to your backend
|
|
418
|
+
},
|
|
419
|
+
async removeItem(key) {
|
|
420
|
+
// Delete from your backend
|
|
421
|
+
},
|
|
422
|
+
async getKeys(base) {
|
|
423
|
+
// List keys with prefix
|
|
424
|
+
},
|
|
425
|
+
async clear() {
|
|
426
|
+
// Clear all data
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
const runtime = createRuntime({
|
|
431
|
+
persistence: createPersistence({
|
|
432
|
+
driver: customDriver,
|
|
433
|
+
}),
|
|
434
|
+
});
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Event Filtering
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
// Filter events by agent
|
|
441
|
+
runtime.on(
|
|
442
|
+
"text_delta",
|
|
443
|
+
(event) => {
|
|
444
|
+
console.log(event.data.text);
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
filter: (event) => event.context?.agentId === "agent_123",
|
|
448
|
+
}
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
// Priority execution
|
|
452
|
+
runtime.on("message_stop", handler, {
|
|
453
|
+
priority: 10, // Higher priority runs first
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// One-time subscription
|
|
457
|
+
runtime.once("agent_created", (event) => {
|
|
458
|
+
console.log("Agent created:", event.data.agentId);
|
|
459
|
+
});
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Testing
|
|
465
|
+
|
|
466
|
+
Runtime is designed for easy testing:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
import { createRuntime, createPersistence } from "@agentxjs/runtime";
|
|
470
|
+
import { describe, it, expect } from "vitest";
|
|
471
|
+
|
|
472
|
+
describe("Runtime", () => {
|
|
473
|
+
it("creates and runs agent", async () => {
|
|
474
|
+
const runtime = createRuntime({
|
|
475
|
+
llm: {
|
|
476
|
+
apiKey: "test-key",
|
|
477
|
+
},
|
|
478
|
+
persistence: createPersistence({ driver: "memory" }),
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// Create container
|
|
482
|
+
const containerRes = await runtime.request("container_create_request", {
|
|
483
|
+
containerId: "test-container",
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
expect(containerRes.data.containerId).toBe("test-container");
|
|
487
|
+
|
|
488
|
+
// Run agent
|
|
489
|
+
const agentRes = await runtime.request("agent_run_request", {
|
|
490
|
+
containerId: "test-container",
|
|
491
|
+
config: { name: "TestAgent" },
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
expect(agentRes.data.name).toBe("TestAgent");
|
|
495
|
+
|
|
496
|
+
await runtime.dispose();
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Design Decisions
|
|
504
|
+
|
|
505
|
+
### Why Event-Driven?
|
|
506
|
+
|
|
507
|
+
Event-driven architecture enables:
|
|
508
|
+
|
|
509
|
+
1. **Decoupling** - Components communicate via events, not direct calls
|
|
510
|
+
2. **Extensibility** - Add new components without modifying existing ones
|
|
511
|
+
3. **Testability** - Mock events instead of entire components
|
|
512
|
+
4. **Observability** - All operations are visible as events
|
|
513
|
+
|
|
514
|
+
### Why SystemBus?
|
|
515
|
+
|
|
516
|
+
SystemBus provides:
|
|
517
|
+
|
|
518
|
+
1. **Single Source of Truth** - All communication flows through one point
|
|
519
|
+
2. **Type Safety** - Commands are fully typed
|
|
520
|
+
3. **Request/Response** - Async operations with correlation IDs
|
|
521
|
+
4. **Priority/Filtering** - Advanced subscription options
|
|
522
|
+
|
|
523
|
+
### Why Separate Environment?
|
|
524
|
+
|
|
525
|
+
Environment abstraction allows:
|
|
526
|
+
|
|
527
|
+
1. **Multiple Backends** - Claude, OpenAI, local models
|
|
528
|
+
2. **Testing** - Mock Environment in tests
|
|
529
|
+
3. **Cross-Platform** - Different implementations for Node.js, Browser
|
|
530
|
+
4. **Clear Boundary** - External world vs. internal logic
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## Configuration Reference
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
interface RuntimeConfig {
|
|
538
|
+
// LLM configuration
|
|
539
|
+
llm?: {
|
|
540
|
+
apiKey?: string; // Default: process.env.ANTHROPIC_API_KEY
|
|
541
|
+
baseUrl?: string; // Default: "https://api.anthropic.com"
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
// Persistence
|
|
545
|
+
persistence?: Persistence;
|
|
546
|
+
|
|
547
|
+
// Logger
|
|
548
|
+
logger?: {
|
|
549
|
+
level?: LogLevel;
|
|
550
|
+
enableTimestamp?: boolean;
|
|
551
|
+
enableColor?: boolean;
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
## Environment Variables
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
# Required
|
|
562
|
+
ANTHROPIC_API_KEY=sk-ant-xxxxx
|
|
563
|
+
|
|
564
|
+
# Optional
|
|
565
|
+
ANTHROPIC_BASE_URL=https://api.anthropic.com # Custom endpoint
|
|
566
|
+
LOG_LEVEL=info # debug, info, warn, error
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Package Dependencies
|
|
572
|
+
|
|
573
|
+
```text
|
|
574
|
+
@agentxjs/types Type definitions
|
|
575
|
+
↑
|
|
576
|
+
@agentxjs/common Logger facade
|
|
577
|
+
↑
|
|
578
|
+
@agentxjs/agent AgentEngine
|
|
579
|
+
↑
|
|
580
|
+
@agentxjs/runtime This package (Runtime + Environment + Persistence)
|
|
581
|
+
↑
|
|
582
|
+
agentxjs High-level unified API
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
## Related Packages
|
|
588
|
+
|
|
589
|
+
- **[@agentxjs/types](../types)** - Type definitions
|
|
590
|
+
- **[@agentxjs/common](../common)** - Logger facade
|
|
591
|
+
- **[@agentxjs/agent](../agent)** - AgentEngine
|
|
592
|
+
- **[agentxjs](../agentx)** - High-level unified API
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## License
|
|
597
|
+
|
|
598
|
+
MIT
|