agentxjs 0.0.9 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +255 -464
- package/dist/browser.cjs +395 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +32 -0
- package/dist/browser.d.ts +32 -0
- package/dist/browser.js +377 -0
- package/dist/browser.js.map +1 -0
- package/dist/index.cjs +521 -2779
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -69
- package/dist/index.d.ts +27 -69
- package/dist/index.js +504 -2773
- package/dist/index.js.map +1 -1
- package/package.json +17 -40
- package/dist/runtime/sse/index.cjs +0 -633
- package/dist/runtime/sse/index.cjs.map +0 -1
- package/dist/runtime/sse/index.d.cts +0 -159
- package/dist/runtime/sse/index.d.ts +0 -159
- package/dist/runtime/sse/index.js +0 -621
- package/dist/runtime/sse/index.js.map +0 -1
- package/dist/server/adapters/express.cjs +0 -81
- package/dist/server/adapters/express.cjs.map +0 -1
- package/dist/server/adapters/express.d.cts +0 -75
- package/dist/server/adapters/express.d.ts +0 -75
- package/dist/server/adapters/express.js +0 -78
- package/dist/server/adapters/express.js.map +0 -1
- package/dist/server/adapters/hono.cjs +0 -32
- package/dist/server/adapters/hono.cjs.map +0 -1
- package/dist/server/adapters/hono.d.cts +0 -96
- package/dist/server/adapters/hono.d.ts +0 -96
- package/dist/server/adapters/hono.js +0 -28
- package/dist/server/adapters/hono.js.map +0 -1
- package/dist/server/adapters/index.cjs +0 -135
- package/dist/server/adapters/index.cjs.map +0 -1
- package/dist/server/adapters/index.d.cts +0 -5
- package/dist/server/adapters/index.d.ts +0 -5
- package/dist/server/adapters/index.js +0 -125
- package/dist/server/adapters/index.js.map +0 -1
- package/dist/server/adapters/next.cjs +0 -30
- package/dist/server/adapters/next.cjs.map +0 -1
- package/dist/server/adapters/next.d.cts +0 -107
- package/dist/server/adapters/next.d.ts +0 -107
- package/dist/server/adapters/next.js +0 -25
- package/dist/server/adapters/next.js.map +0 -1
- package/dist/server/index.cjs +0 -1093
- package/dist/server/index.cjs.map +0 -1
- package/dist/server/index.d.cts +0 -131
- package/dist/server/index.d.ts +0 -131
- package/dist/server/index.js +0 -1080
- package/dist/server/index.js.map +0 -1
- package/dist/types-Cgfcw91r.d.cts +0 -282
- package/dist/types-Cgfcw91r.d.ts +0 -282
- package/dist/types-OVKV6qpE.d.cts +0 -118
- package/dist/types-OVKV6qpE.d.ts +0 -118
package/README.md
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
# agentxjs
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Unified API for AI Agents - Server and Browser
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
`agentxjs`
|
|
7
|
+
`agentxjs` provides a **unified API** for building AI agents that works seamlessly across server (Node.js) and browser environments.
|
|
8
8
|
|
|
9
|
-
**Key
|
|
9
|
+
**Key Features:**
|
|
10
10
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **Stream-First Transport** - Efficient SSE transmission with client-side reassembly
|
|
16
|
-
- **Framework Adapters** - Ready-to-use adapters for Express, Hono, Next.js
|
|
11
|
+
- **Unified API** - Same `createAgentX()` function for both server and browser
|
|
12
|
+
- **Type-Safe Configuration** - TypeScript discriminates between Source and Mirror modes
|
|
13
|
+
- **Docker-Style Lifecycle** - Container → Agent → Image
|
|
14
|
+
- **Event-Driven** - Real-time streaming events (text_delta, tool_call, etc.)
|
|
17
15
|
|
|
18
16
|
## Installation
|
|
19
17
|
|
|
@@ -23,580 +21,373 @@ pnpm add agentxjs
|
|
|
23
21
|
|
|
24
22
|
---
|
|
25
23
|
|
|
26
|
-
##
|
|
24
|
+
## Quick Start
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
┌─────────────────────────────────────────────────────────────────────┐
|
|
30
|
-
│ agentxjs │
|
|
31
|
-
├─────────────────────────────────────────────────────────────────────┤
|
|
32
|
-
│ │
|
|
33
|
-
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
34
|
-
│ │ createAgentX(runtime) │ │
|
|
35
|
-
│ │ │ │
|
|
36
|
-
│ │ NodeRuntime (server) SSERuntime (browser) │ │
|
|
37
|
-
│ │ │ │ │ │
|
|
38
|
-
│ │ ▼ ▼ │ │
|
|
39
|
-
│ │ ┌──────────────┐ ┌───────────────────┐ │ │
|
|
40
|
-
│ │ │ ClaudeDriver │ │ SSEDriver │ │ │
|
|
41
|
-
│ │ │ LocalSandbox │ │ RemoteContainer │ │ │
|
|
42
|
-
│ │ │ SQLiteRepo │ │ RemoteRepository │ │ │
|
|
43
|
-
│ │ └──────────────┘ └───────────────────┘ │ │
|
|
44
|
-
│ └─────────────────────────────────────────────────────────────┘ │
|
|
45
|
-
│ │
|
|
46
|
-
│ ┌──────────────────────────────────────────────────────────────┐ │
|
|
47
|
-
│ │ AgentX Platform API │ │
|
|
48
|
-
│ │ │ │
|
|
49
|
-
│ │ agentx.containers - Container lifecycle management │ │
|
|
50
|
-
│ │ agentx.definitions - Register agent templates │ │
|
|
51
|
-
│ │ agentx.images - Build/manage agent snapshots │ │
|
|
52
|
-
│ │ agentx.agents - Query running agents │ │
|
|
53
|
-
│ │ agentx.sessions - User-facing session management │ │
|
|
54
|
-
│ │ agentx.errors - Platform-level error handling │ │
|
|
55
|
-
│ └──────────────────────────────────────────────────────────────┘ │
|
|
56
|
-
│ │
|
|
57
|
-
│ ┌──────────────────────┐ ┌──────────────────────────────────┐ │
|
|
58
|
-
│ │ /server │ │ /client │ │
|
|
59
|
-
│ │ │ │ │ │
|
|
60
|
-
│ │ createAgentXHandler │ │ sseRuntime (browser) │ │
|
|
61
|
-
│ │ SSEConnection │ │ SSERuntime │ │
|
|
62
|
-
│ │ │ │ SSEDriver │ │
|
|
63
|
-
│ │ /adapters: │ │ RemoteContainer │ │
|
|
64
|
-
│ │ • express │ │ RemoteRepository │ │
|
|
65
|
-
│ │ • hono │ │ │ │
|
|
66
|
-
│ │ • next │ │ │ │
|
|
67
|
-
│ └──────────────────────┘ └──────────────────────────────────┘ │
|
|
68
|
-
│ │
|
|
69
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
---
|
|
26
|
+
### Server (Source Mode)
|
|
73
27
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
AgentX uses a Docker-inspired lifecycle for agent management:
|
|
28
|
+
```typescript
|
|
29
|
+
import { createAgentX } from "agentxjs";
|
|
77
30
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
│ Docker-Style Lifecycle │
|
|
81
|
-
├─────────────────────────────────────────────────────────────────────┤
|
|
82
|
-
│ │
|
|
83
|
-
│ Definition (template) │
|
|
84
|
-
│ │ │
|
|
85
|
-
│ │ register │
|
|
86
|
-
│ ▼ │
|
|
87
|
-
│ DefinitionManager + (auto-create MetaImage) │
|
|
88
|
-
│ │ │
|
|
89
|
-
│ │ build (optional: create DerivedImage) │
|
|
90
|
-
│ ▼ │
|
|
91
|
-
│ ImageManager (MetaImage or DerivedImage snapshot) │
|
|
92
|
-
│ │ │
|
|
93
|
-
│ │ run │
|
|
94
|
-
│ ▼ │
|
|
95
|
-
│ Container (creates Agent from Image) │
|
|
96
|
-
│ │ │
|
|
97
|
-
│ │ runtime │
|
|
98
|
-
│ ▼ │
|
|
99
|
-
│ Agent (running instance) │
|
|
100
|
-
│ │ │
|
|
101
|
-
│ │ user action │
|
|
102
|
-
│ ▼ │
|
|
103
|
-
│ SessionManager (wrap for UI/external) │
|
|
104
|
-
│ │ │
|
|
105
|
-
│ ▼ │
|
|
106
|
-
│ Session (external view with metadata: title, userId) │
|
|
107
|
-
│ │
|
|
108
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
109
|
-
```
|
|
31
|
+
// Minimal - reads ANTHROPIC_API_KEY from environment
|
|
32
|
+
const agentx = createAgentX();
|
|
110
33
|
|
|
111
|
-
|
|
34
|
+
// Or with explicit configuration
|
|
35
|
+
const agentx = createAgentX({
|
|
36
|
+
apiKey: "sk-ant-...",
|
|
37
|
+
model: "claude-sonnet-4-20250514",
|
|
38
|
+
});
|
|
112
39
|
|
|
113
|
-
|
|
40
|
+
// Run an agent
|
|
41
|
+
const agent = await agentx.run({ name: "Assistant" });
|
|
114
42
|
|
|
115
|
-
|
|
43
|
+
// Subscribe to events
|
|
44
|
+
agent.on("text_delta", (e) => process.stdout.write(e.data.text));
|
|
116
45
|
|
|
117
|
-
|
|
46
|
+
// Send message
|
|
47
|
+
await agent.receive("Hello!");
|
|
118
48
|
|
|
119
|
-
|
|
49
|
+
// Cleanup
|
|
50
|
+
await agentx.dispose();
|
|
51
|
+
```
|
|
120
52
|
|
|
121
|
-
|
|
122
|
-
| -------------- | -------- | ---------------------------------------- |
|
|
123
|
-
| `defineAgent` | Function | Define an agent template |
|
|
124
|
-
| `createAgentX` | Function | Factory for AgentX platform with Runtime |
|
|
125
|
-
| `sseRuntime` | Function | Create browser SSE runtime |
|
|
53
|
+
### Browser (Mirror Mode)
|
|
126
54
|
|
|
127
55
|
```typescript
|
|
128
|
-
import {
|
|
129
|
-
import { nodeRuntime } from "@agentxjs/node-runtime";
|
|
56
|
+
import { createAgentX } from "agentxjs";
|
|
130
57
|
|
|
131
|
-
//
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
systemPrompt: "You are a helpful assistant",
|
|
58
|
+
// Connect to remote server via WebSocket
|
|
59
|
+
const agentx = createAgentX({
|
|
60
|
+
serverUrl: "ws://localhost:5200",
|
|
61
|
+
token: "optional-auth-token",
|
|
136
62
|
});
|
|
137
63
|
|
|
138
|
-
//
|
|
139
|
-
const
|
|
64
|
+
// Same API as server!
|
|
65
|
+
const agent = await agentx.run({ name: "Assistant" });
|
|
140
66
|
|
|
141
|
-
|
|
142
|
-
agentx.definitions.register(MyAgent);
|
|
143
|
-
|
|
144
|
-
// 4. Run agent from image
|
|
145
|
-
const metaImage = agentx.images.getMetaImage(MyAgent.name);
|
|
146
|
-
const agent = await agentx.images.run(metaImage.id);
|
|
67
|
+
agent.on("text_delta", (e) => console.log(e.data.text));
|
|
147
68
|
|
|
148
|
-
// 5. Use agent
|
|
149
69
|
await agent.receive("Hello!");
|
|
150
70
|
```
|
|
151
71
|
|
|
152
|
-
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## API Design
|
|
75
|
+
|
|
76
|
+
### Configuration Types
|
|
153
77
|
|
|
154
78
|
```typescript
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
readonly errors: ErrorManager;
|
|
79
|
+
// Server-side configuration (Source mode)
|
|
80
|
+
interface SourceConfig {
|
|
81
|
+
apiKey?: string; // Default: process.env.ANTHROPIC_API_KEY
|
|
82
|
+
model?: string; // Default: "claude-sonnet-4-20250514"
|
|
83
|
+
baseUrl?: string; // Default: "https://api.anthropic.com"
|
|
84
|
+
persistence?: Persistence;
|
|
162
85
|
}
|
|
163
86
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
unregister(name: string): boolean;
|
|
87
|
+
// Browser-side configuration (Mirror mode)
|
|
88
|
+
interface MirrorConfig {
|
|
89
|
+
serverUrl: string; // WebSocket URL, e.g., "ws://localhost:5200"
|
|
90
|
+
token?: string; // Authentication token
|
|
91
|
+
headers?: Record<string, string>;
|
|
170
92
|
}
|
|
171
93
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
list(): AgentImage[];
|
|
176
|
-
listByDefinition(definitionName: string): AgentImage[];
|
|
177
|
-
exists(imageId: string): boolean;
|
|
178
|
-
delete(imageId: string): boolean;
|
|
179
|
-
run(imageId: string): Promise<Agent>;
|
|
180
|
-
}
|
|
94
|
+
// Type discrimination: presence of `serverUrl` determines mode
|
|
95
|
+
type AgentXConfig = SourceConfig | MirrorConfig;
|
|
96
|
+
```
|
|
181
97
|
|
|
182
|
-
|
|
183
|
-
get(agentId: string): Agent | undefined;
|
|
184
|
-
has(agentId: string): boolean;
|
|
185
|
-
list(): Agent[];
|
|
186
|
-
destroy(agentId: string): boolean;
|
|
187
|
-
destroyAll(): void;
|
|
188
|
-
}
|
|
98
|
+
### Type Guards
|
|
189
99
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
destroyAll(): void;
|
|
100
|
+
```typescript
|
|
101
|
+
import { isMirrorConfig, isSourceConfig } from "agentxjs";
|
|
102
|
+
|
|
103
|
+
const config: AgentXConfig = { serverUrl: "ws://localhost:5200" };
|
|
104
|
+
|
|
105
|
+
if (isMirrorConfig(config)) {
|
|
106
|
+
// TypeScript knows this is MirrorConfig
|
|
107
|
+
console.log(config.serverUrl);
|
|
199
108
|
}
|
|
200
109
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
removeHandler(handler: ErrorHandler): void;
|
|
110
|
+
if (isSourceConfig(config)) {
|
|
111
|
+
// TypeScript knows this is SourceConfig
|
|
112
|
+
console.log(config.apiKey);
|
|
205
113
|
}
|
|
206
114
|
```
|
|
207
115
|
|
|
208
|
-
|
|
116
|
+
### AgentX Interface
|
|
209
117
|
|
|
210
118
|
```typescript
|
|
211
|
-
interface
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
readonly agent: Agent;
|
|
215
|
-
|
|
216
|
-
// Resume from previous state
|
|
217
|
-
resume(): Promise<void>;
|
|
119
|
+
interface AgentX {
|
|
120
|
+
// Quick start - run agent in default container
|
|
121
|
+
run(config: AgentRunConfig): Promise<Agent>;
|
|
218
122
|
|
|
219
|
-
//
|
|
220
|
-
|
|
123
|
+
// Container management
|
|
124
|
+
readonly containers: ContainersAPI;
|
|
221
125
|
|
|
222
|
-
//
|
|
223
|
-
|
|
126
|
+
// Agent management (cross-container)
|
|
127
|
+
readonly agents: AgentsAPI;
|
|
224
128
|
|
|
225
|
-
//
|
|
226
|
-
|
|
129
|
+
// Image (snapshot) management
|
|
130
|
+
readonly images: ImagesAPI;
|
|
227
131
|
|
|
228
|
-
//
|
|
229
|
-
|
|
132
|
+
// Cleanup
|
|
133
|
+
dispose(): Promise<void>;
|
|
230
134
|
}
|
|
231
135
|
```
|
|
232
136
|
|
|
233
|
-
|
|
137
|
+
### Sub-APIs
|
|
234
138
|
|
|
235
|
-
|
|
139
|
+
```typescript
|
|
140
|
+
// Container management
|
|
141
|
+
interface ContainersAPI {
|
|
142
|
+
create(containerId: string): Promise<Container>;
|
|
143
|
+
get(containerId: string): Container | undefined;
|
|
144
|
+
list(): Container[];
|
|
145
|
+
}
|
|
236
146
|
|
|
237
|
-
|
|
147
|
+
// Agent management
|
|
148
|
+
interface AgentsAPI {
|
|
149
|
+
run(containerId: string, config: AgentRunConfig): Promise<Agent>;
|
|
150
|
+
get(agentId: string): Agent | undefined;
|
|
151
|
+
list(containerId: string): Agent[];
|
|
152
|
+
destroy(agentId: string): Promise<boolean>;
|
|
153
|
+
destroyAll(containerId: string): Promise<void>;
|
|
154
|
+
}
|
|
238
155
|
|
|
239
|
-
|
|
240
|
-
|
|
156
|
+
// Image management
|
|
157
|
+
interface ImagesAPI {
|
|
158
|
+
snapshot(agent: Agent): Promise<AgentImage>;
|
|
159
|
+
list(): Promise<AgentImage[]>;
|
|
160
|
+
get(imageId: string): Promise<AgentImage | null>;
|
|
161
|
+
delete(imageId: string): Promise<void>;
|
|
162
|
+
}
|
|
241
163
|
```
|
|
242
164
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
Creates a framework-agnostic HTTP handler based on Web Standard Request/Response.
|
|
165
|
+
### Agent Run Configuration
|
|
246
166
|
|
|
247
167
|
```typescript
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
hooks: {
|
|
253
|
-
onConnect: (agentId, connectionId) => {
|
|
254
|
-
/* SSE connected */
|
|
255
|
-
},
|
|
256
|
-
onDisconnect: (agentId, connectionId) => {
|
|
257
|
-
/* SSE disconnected */
|
|
258
|
-
},
|
|
259
|
-
onMessage: (agentId, message) => {
|
|
260
|
-
/* Message received */
|
|
261
|
-
},
|
|
262
|
-
onError: (agentId, error) => {
|
|
263
|
-
/* Error occurred */
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
// Returns: (request: Request) => Promise<Response>
|
|
168
|
+
interface AgentRunConfig {
|
|
169
|
+
name: string;
|
|
170
|
+
systemPrompt?: string;
|
|
171
|
+
}
|
|
269
172
|
```
|
|
270
173
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
| ------ | ------------------------------- | ---------------------- |
|
|
275
|
-
| GET | `/info` | Platform info |
|
|
276
|
-
| GET | `/health` | Health check |
|
|
277
|
-
| GET | `/definitions` | List all definitions |
|
|
278
|
-
| GET | `/definitions/:name` | Get definition by name |
|
|
279
|
-
| POST | `/definitions` | Register definition |
|
|
280
|
-
| DELETE | `/definitions/:name` | Unregister definition |
|
|
281
|
-
| GET | `/images` | List all images |
|
|
282
|
-
| GET | `/images/:imageId` | Get image by ID |
|
|
283
|
-
| POST | `/images/:imageId/run` | Run agent from image |
|
|
284
|
-
| DELETE | `/images/:imageId` | Delete image |
|
|
285
|
-
| GET | `/agents` | List all agents |
|
|
286
|
-
| GET | `/agents/:agentId` | Get agent info |
|
|
287
|
-
| DELETE | `/agents/:agentId` | Destroy agent |
|
|
288
|
-
| GET | `/agents/:agentId/sse` | SSE event stream |
|
|
289
|
-
| POST | `/agents/:agentId/messages` | Send message to agent |
|
|
290
|
-
| POST | `/agents/:agentId/interrupt` | Interrupt processing |
|
|
291
|
-
| GET | `/sessions` | List all sessions |
|
|
292
|
-
| GET | `/sessions/:sessionId` | Get session by ID |
|
|
293
|
-
| POST | `/sessions` | Create session |
|
|
294
|
-
| POST | `/sessions/:sessionId/resume` | Resume session |
|
|
295
|
-
| POST | `/sessions/:sessionId/fork` | Fork session |
|
|
296
|
-
| GET | `/sessions/:sessionId/messages` | Get session messages |
|
|
297
|
-
| DELETE | `/sessions/:sessionId` | Destroy session |
|
|
298
|
-
|
|
299
|
-
#### SSE Transport
|
|
300
|
-
|
|
301
|
-
The server only forwards **Stream Layer events** via SSE:
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Architecture
|
|
302
177
|
|
|
303
178
|
```text
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
179
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
180
|
+
│ createAgentX(config) │
|
|
181
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
182
|
+
│ │
|
|
183
|
+
│ config has serverUrl? │
|
|
184
|
+
│ │ │
|
|
185
|
+
│ ├── YES ──▶ Mirror Mode (Browser) │
|
|
186
|
+
│ │ - MirrorRuntime │
|
|
187
|
+
│ │ - WebSocket communication │
|
|
188
|
+
│ │ - Local state mirrors server │
|
|
189
|
+
│ │ │
|
|
190
|
+
│ └── NO ───▶ Source Mode (Server) │
|
|
191
|
+
│ - Runtime │
|
|
192
|
+
│ - Direct LLM access │
|
|
193
|
+
│ - Persistence layer │
|
|
194
|
+
│ │
|
|
195
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
196
|
+
│ │
|
|
197
|
+
│ AgentX API │
|
|
198
|
+
│ │
|
|
199
|
+
│ agentx.run(config) Quick start │
|
|
200
|
+
│ agentx.containers.* Container lifecycle │
|
|
201
|
+
│ agentx.agents.* Agent operations │
|
|
202
|
+
│ agentx.images.* Snapshot management │
|
|
203
|
+
│ agentx.dispose() Cleanup │
|
|
204
|
+
│ │
|
|
205
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
321
206
|
```
|
|
322
207
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
### Server Adapters (`/server/adapters`)
|
|
208
|
+
### Source vs Mirror
|
|
326
209
|
|
|
327
|
-
|
|
210
|
+
| Aspect | Source (Server) | Mirror (Browser) |
|
|
211
|
+
| ------------- | -------------------- | ---------------- |
|
|
212
|
+
| Runtime | Runtime | MirrorRuntime |
|
|
213
|
+
| LLM Access | Direct API calls | Via server |
|
|
214
|
+
| Persistence | Local (SQLite, etc.) | Server-side |
|
|
215
|
+
| Communication | N/A | WebSocket events |
|
|
216
|
+
| Use Case | Backend services | Frontend apps |
|
|
328
217
|
|
|
329
|
-
|
|
218
|
+
---
|
|
330
219
|
|
|
331
|
-
|
|
332
|
-
import { toExpressHandler } from "agentxjs/server/adapters/express";
|
|
333
|
-
import express from "express";
|
|
220
|
+
## Docker-Style Lifecycle
|
|
334
221
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
222
|
+
```text
|
|
223
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
224
|
+
│ Lifecycle Flow │
|
|
225
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
226
|
+
│ │
|
|
227
|
+
│ Container │
|
|
228
|
+
│ │ │
|
|
229
|
+
│ │ run(config) │
|
|
230
|
+
│ ▼ │
|
|
231
|
+
│ Agent (running instance) │
|
|
232
|
+
│ │ │
|
|
233
|
+
│ │ snapshot() │
|
|
234
|
+
│ ▼ │
|
|
235
|
+
│ AgentImage (frozen state) │
|
|
236
|
+
│ │ │
|
|
237
|
+
│ │ resume() │
|
|
238
|
+
│ ▼ │
|
|
239
|
+
│ Agent (restored from image) │
|
|
240
|
+
│ │
|
|
241
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
338
242
|
```
|
|
339
243
|
|
|
340
|
-
|
|
244
|
+
### Image Operations
|
|
341
245
|
|
|
342
246
|
```typescript
|
|
343
|
-
|
|
344
|
-
|
|
247
|
+
// Create snapshot
|
|
248
|
+
const agent = await agentx.run({ name: "Assistant" });
|
|
249
|
+
await agent.receive("Hello!");
|
|
250
|
+
const image = await agentx.images.snapshot(agent);
|
|
345
251
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
//
|
|
252
|
+
// Resume from snapshot
|
|
253
|
+
const resumedAgent = await image.resume();
|
|
254
|
+
// Agent has previous conversation history
|
|
349
255
|
```
|
|
350
256
|
|
|
351
|
-
|
|
257
|
+
---
|
|
352
258
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
259
|
+
## Event System
|
|
260
|
+
|
|
261
|
+
### Stream Events (Real-time)
|
|
356
262
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
263
|
+
```typescript
|
|
264
|
+
agent.on("message_start", (e) => {
|
|
265
|
+
/* Response started */
|
|
266
|
+
});
|
|
267
|
+
agent.on("text_delta", (e) => console.log(e.data.text));
|
|
268
|
+
agent.on("tool_call", (e) => {
|
|
269
|
+
/* Tool being called */
|
|
270
|
+
});
|
|
271
|
+
agent.on("tool_result", (e) => {
|
|
272
|
+
/* Tool result received */
|
|
273
|
+
});
|
|
274
|
+
agent.on("message_stop", (e) => {
|
|
275
|
+
/* Response complete */
|
|
360
276
|
});
|
|
361
277
|
```
|
|
362
278
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
### Client Module (`/client`)
|
|
366
|
-
|
|
367
|
-
Browser SDK for connecting to remote AgentX servers using the same API.
|
|
279
|
+
### Subscribe to All Events
|
|
368
280
|
|
|
369
281
|
```typescript
|
|
370
|
-
|
|
282
|
+
agent.on((event) => {
|
|
283
|
+
console.log(event.type, event.data);
|
|
284
|
+
});
|
|
371
285
|
```
|
|
372
286
|
|
|
373
|
-
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Advanced Usage
|
|
374
290
|
|
|
375
|
-
|
|
291
|
+
### Container Management
|
|
376
292
|
|
|
377
293
|
```typescript
|
|
378
|
-
|
|
379
|
-
|
|
294
|
+
// Create named container
|
|
295
|
+
const container = await agentx.containers.create("my-container");
|
|
380
296
|
|
|
381
|
-
//
|
|
382
|
-
const
|
|
297
|
+
// Run agent in container
|
|
298
|
+
const agent = await agentx.agents.run("my-container", {
|
|
383
299
|
name: "Assistant",
|
|
384
|
-
systemPrompt: "You are
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// Create SSE runtime for browser
|
|
388
|
-
const runtime = sseRuntime({
|
|
389
|
-
serverUrl: "http://localhost:5200/agentx",
|
|
390
|
-
headers: { Authorization: "Bearer xxx" }, // Optional: for HTTP requests
|
|
391
|
-
sseParams: { token: "xxx" }, // Optional: for SSE auth via query string
|
|
300
|
+
systemPrompt: "You are helpful",
|
|
392
301
|
});
|
|
393
302
|
|
|
394
|
-
//
|
|
395
|
-
const
|
|
303
|
+
// List agents in container
|
|
304
|
+
const agents = agentx.agents.list("my-container");
|
|
396
305
|
|
|
397
|
-
//
|
|
398
|
-
agentx.
|
|
306
|
+
// Destroy all agents in container
|
|
307
|
+
await agentx.agents.destroyAll("my-container");
|
|
308
|
+
```
|
|
399
309
|
|
|
400
|
-
|
|
401
|
-
const metaImage = agentx.images.getMetaImage(MyAgent.name);
|
|
402
|
-
const agent = await agentx.images.run(metaImage.id);
|
|
310
|
+
### Custom Persistence (Source Mode)
|
|
403
311
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
312
|
+
```typescript
|
|
313
|
+
import { createAgentX } from "agentxjs";
|
|
314
|
+
import { createPersistence } from "@agentxjs/persistence";
|
|
315
|
+
|
|
316
|
+
const agentx = createAgentX({
|
|
317
|
+
apiKey: "sk-ant-...",
|
|
318
|
+
persistence: createPersistence({
|
|
319
|
+
driver: "sqlite",
|
|
320
|
+
path: "./data.db",
|
|
321
|
+
}),
|
|
407
322
|
});
|
|
408
|
-
|
|
409
|
-
await agent.receive("Hello!");
|
|
410
323
|
```
|
|
411
324
|
|
|
412
|
-
**Key Point**: Browser uses the same `defineAgent` + `createAgentX` API.
|
|
413
|
-
Only the Runtime differs (`sseRuntime` vs `nodeRuntime`).
|
|
414
|
-
|
|
415
|
-
#### Browser Runtime Components
|
|
416
|
-
|
|
417
|
-
| Component | Description |
|
|
418
|
-
| ------------------ | --------------------------------------------------- |
|
|
419
|
-
| `SSERuntime` | Browser runtime implementation |
|
|
420
|
-
| `RemoteContainer` | Calls server to create agents, caches locally |
|
|
421
|
-
| `RemoteRepository` | HTTP-based persistence (noop for saveMessage) |
|
|
422
|
-
| `SSEDriver` | EventSource-based driver with persistent connection |
|
|
423
|
-
| `BrowserLogger` | Styled console logging for browser |
|
|
424
|
-
|
|
425
325
|
---
|
|
426
326
|
|
|
427
327
|
## Design Decisions
|
|
428
328
|
|
|
429
|
-
### Why
|
|
329
|
+
### Why Unified `createAgentX`?
|
|
430
330
|
|
|
431
|
-
|
|
331
|
+
Instead of separate `createSource()` and `createMirror()` functions, we use a single `createAgentX()` with type discrimination:
|
|
432
332
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
333
|
+
```typescript
|
|
334
|
+
// Type system determines mode automatically
|
|
335
|
+
createAgentX(); // Source (no serverUrl)
|
|
336
|
+
createAgentX({ apiKey: "..." }); // Source (no serverUrl)
|
|
337
|
+
createAgentX({ serverUrl: "ws://..." }); // Mirror (has serverUrl)
|
|
338
|
+
```
|
|
437
339
|
|
|
438
340
|
**Benefits:**
|
|
439
341
|
|
|
440
|
-
-
|
|
441
|
-
-
|
|
442
|
-
-
|
|
443
|
-
- Separation: Business config (definition) vs runtime state (image)
|
|
444
|
-
|
|
445
|
-
### Why Five Managers?
|
|
342
|
+
- Single import, single function to learn
|
|
343
|
+
- TypeScript enforces correct configuration
|
|
344
|
+
- Easy refactoring between modes
|
|
446
345
|
|
|
447
|
-
|
|
448
|
-
| ----------- | -------- | ---------------------------------------- |
|
|
449
|
-
| definitions | Platform | Template registry (register, get, list) |
|
|
450
|
-
| images | Platform | Snapshot management (build, list, run) |
|
|
451
|
-
| agents | Platform | Running agent query (get, list, destroy) |
|
|
452
|
-
| sessions | Platform | User-facing wrapper (create, resume) |
|
|
453
|
-
| errors | Platform | Centralized error handling |
|
|
346
|
+
### Why WebSocket for Mirror?
|
|
454
347
|
|
|
455
|
-
|
|
348
|
+
Mirror mode uses WebSocket (not HTTP/SSE) for bidirectional communication:
|
|
456
349
|
|
|
457
|
-
|
|
350
|
+
1. **Request/Response pattern** - Browser sends commands, server responds
|
|
351
|
+
2. **Real-time events** - Server pushes stream events to browser
|
|
352
|
+
3. **State synchronization** - Browser maintains local mirror of server state
|
|
458
353
|
|
|
459
|
-
|
|
460
|
-
Runtime provides infrastructure (Driver, Sandbox).
|
|
354
|
+
### Why No `defineAgent`?
|
|
461
355
|
|
|
462
|
-
|
|
463
|
-
| ----------- | ------------- | ------------ | --------------------------- |
|
|
464
|
-
| Server | `nodeRuntime` | ClaudeDriver | Direct LLM API calls |
|
|
465
|
-
| Browser | `sseRuntime` | SSEDriver | Connect to server via SSE |
|
|
466
|
-
| Edge | EdgeRuntime | EdgeDriver | Cloudflare Workers (future) |
|
|
356
|
+
Previous versions required:
|
|
467
357
|
|
|
468
358
|
```typescript
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
// Different runtimes for different environments
|
|
476
|
-
const agentx = createAgentX(nodeRuntime()); // Server
|
|
477
|
-
const agentx = createAgentX(sseRuntime({ serverUrl })); // Browser
|
|
359
|
+
const MyAgent = defineAgent({ name: "Assistant", ... });
|
|
360
|
+
agentx.definitions.register(MyAgent);
|
|
361
|
+
const image = agentx.images.getMetaImage(MyAgent.name);
|
|
362
|
+
const agent = await image.run();
|
|
478
363
|
```
|
|
479
364
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
The server handler is built on Web Standard APIs instead of Express/Fastify/etc:
|
|
483
|
-
|
|
484
|
-
1. **Framework Agnostic** - Works with any framework via thin adapters
|
|
485
|
-
2. **Edge Compatible** - Runs on Cloudflare Workers, Deno Deploy, etc.
|
|
486
|
-
3. **Future Proof** - Web Standards are stable and widely supported
|
|
487
|
-
4. **Testable** - Can test handlers without framework boilerplate
|
|
365
|
+
New API is simpler:
|
|
488
366
|
|
|
489
367
|
```typescript
|
|
490
|
-
|
|
491
|
-
type AgentXHandler = (request: Request) => Promise<Response>;
|
|
492
|
-
|
|
493
|
-
// Adapters are thin wrappers
|
|
494
|
-
const toExpressHandler = (handler) => (req, res) => {
|
|
495
|
-
const request = toWebRequest(req);
|
|
496
|
-
const response = await handler(request);
|
|
497
|
-
copyToExpressResponse(response, res);
|
|
498
|
-
};
|
|
368
|
+
const agent = await agentx.run({ name: "Assistant", ... });
|
|
499
369
|
```
|
|
500
370
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
Server forwards only Stream Layer events, not Message/State/Turn events:
|
|
504
|
-
|
|
505
|
-
1. **Efficient Bandwidth** - Only transmit incremental deltas
|
|
506
|
-
2. **Decoupling** - Server doesn't need to know client's event needs
|
|
507
|
-
3. **Consistency** - Same AgentEngine code runs on server and client
|
|
508
|
-
4. **Flexibility** - Different clients can process events differently
|
|
509
|
-
|
|
510
|
-
```text
|
|
511
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
512
|
-
│ WRONG: Server sends assembled messages │
|
|
513
|
-
│ │
|
|
514
|
-
│ Server → [assembled message] → Client │
|
|
515
|
-
│ (large payload) (just displays) │
|
|
516
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
517
|
-
|
|
518
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
519
|
-
│ CORRECT: Server sends stream events │
|
|
520
|
-
│ │
|
|
521
|
-
│ Server → [text_delta, text_delta, ...] → Client.AgentEngine │
|
|
522
|
-
│ (small increments) (reassembles) │
|
|
523
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### Why RemoteRepository noop for saveMessage?
|
|
527
|
-
|
|
528
|
-
Browser's `RemoteRepository.saveMessage()` is intentionally a noop:
|
|
529
|
-
|
|
530
|
-
1. Server-side `SessionCollector` persists messages
|
|
531
|
-
2. Prevents duplicate persistence (both server and client saving)
|
|
532
|
-
3. Browser only reads messages via HTTP GET
|
|
533
|
-
|
|
534
|
-
---
|
|
535
|
-
|
|
536
|
-
## Package Structure
|
|
537
|
-
|
|
538
|
-
```text
|
|
539
|
-
agentxjs/src/
|
|
540
|
-
├── AgentX.ts # Core platform factory
|
|
541
|
-
├── defineAgent.ts # Agent definition helper
|
|
542
|
-
├── index.ts # Main entry point
|
|
543
|
-
├── managers/ # Platform-level managers
|
|
544
|
-
│ ├── agent/ # AgentManager (query running agents)
|
|
545
|
-
│ ├── definition/ # DefinitionManager (agent templates)
|
|
546
|
-
│ ├── image/ # ImageManager (agent snapshots)
|
|
547
|
-
│ ├── session/ # SessionManager (user-facing wrapper)
|
|
548
|
-
│ ├── error/ # ErrorManager (error handling)
|
|
549
|
-
│ └── remote/ # Remote platform utilities
|
|
550
|
-
├── runtime/ # Runtime implementations
|
|
551
|
-
│ └── sse/ # Browser SSE runtime
|
|
552
|
-
│ ├── SSERuntime.ts # Main runtime + RemoteContainer
|
|
553
|
-
│ ├── SSEDriver.ts # Browser SSE driver
|
|
554
|
-
│ ├── logger/ # BrowserLogger
|
|
555
|
-
│ └── repository/ # RemoteRepository
|
|
556
|
-
└── server/ # Server-side HTTP handler
|
|
557
|
-
├── createAgentXHandler.ts # Framework-agnostic handler
|
|
558
|
-
├── SSEServerTransport.ts # SSE transport
|
|
559
|
-
└── adapters/ # Framework adapters
|
|
560
|
-
├── express.ts
|
|
561
|
-
├── hono.ts
|
|
562
|
-
└── next.ts
|
|
563
|
-
```
|
|
371
|
+
The `AgentRunConfig` replaces `AgentDefinition` for most use cases. For advanced scenarios (versioning, derived images), use the Images API directly.
|
|
564
372
|
|
|
565
373
|
---
|
|
566
374
|
|
|
567
375
|
## Package Dependencies
|
|
568
376
|
|
|
569
377
|
```text
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
↑
|
|
580
|
-
agentx-runtime (NodeRuntime + ClaudeDriver)
|
|
581
|
-
↑
|
|
582
|
-
agentx-ui (React components)
|
|
378
|
+
@agentxjs/types Type definitions
|
|
379
|
+
↑
|
|
380
|
+
@agentxjs/common Logger facade
|
|
381
|
+
↑
|
|
382
|
+
@agentxjs/runtime Runtime implementation
|
|
383
|
+
↑
|
|
384
|
+
@agentxjs/mirror MirrorRuntime implementation
|
|
385
|
+
↑
|
|
386
|
+
agentxjs This package (unified API)
|
|
583
387
|
```
|
|
584
388
|
|
|
585
389
|
---
|
|
586
390
|
|
|
587
|
-
## Related Packages
|
|
588
|
-
|
|
589
|
-
| Package | Description |
|
|
590
|
-
| ------------------------------------------- | -------------------------- |
|
|
591
|
-
| [@agentxjs/types](../agentx-types) | Type definitions |
|
|
592
|
-
| [@agentxjs/agent](../agentx-agent) | Agent runtime |
|
|
593
|
-
| [@agentxjs/engine](../agentx-engine) | Event processing engine |
|
|
594
|
-
| [@agentxjs/node-runtime](../agentx-runtime) | NodeRuntime + ClaudeDriver |
|
|
595
|
-
| [@agentxjs/common](../agentx-common) | Logging facade |
|
|
596
|
-
| [@agentxjs/ui](../agentx-ui) | React components |
|
|
597
|
-
|
|
598
|
-
---
|
|
599
|
-
|
|
600
391
|
## License
|
|
601
392
|
|
|
602
393
|
MIT
|