agentxjs 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/LICENSE +21 -0
- package/README.md +602 -0
- package/dist/index.cjs +1292 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +88 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.js +1283 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/sse/index.cjs +633 -0
- package/dist/runtime/sse/index.cjs.map +1 -0
- package/dist/runtime/sse/index.d.cts +159 -0
- package/dist/runtime/sse/index.d.ts +159 -0
- package/dist/runtime/sse/index.js +621 -0
- package/dist/runtime/sse/index.js.map +1 -0
- package/dist/server/adapters/express.cjs +81 -0
- package/dist/server/adapters/express.cjs.map +1 -0
- package/dist/server/adapters/express.d.cts +75 -0
- package/dist/server/adapters/express.d.ts +75 -0
- package/dist/server/adapters/express.js +78 -0
- package/dist/server/adapters/express.js.map +1 -0
- package/dist/server/adapters/hono.cjs +32 -0
- package/dist/server/adapters/hono.cjs.map +1 -0
- package/dist/server/adapters/hono.d.cts +96 -0
- package/dist/server/adapters/hono.d.ts +96 -0
- package/dist/server/adapters/hono.js +28 -0
- package/dist/server/adapters/hono.js.map +1 -0
- package/dist/server/adapters/index.cjs +135 -0
- package/dist/server/adapters/index.cjs.map +1 -0
- package/dist/server/adapters/index.d.cts +5 -0
- package/dist/server/adapters/index.d.ts +5 -0
- package/dist/server/adapters/index.js +125 -0
- package/dist/server/adapters/index.js.map +1 -0
- package/dist/server/adapters/next.cjs +30 -0
- package/dist/server/adapters/next.cjs.map +1 -0
- package/dist/server/adapters/next.d.cts +107 -0
- package/dist/server/adapters/next.d.ts +107 -0
- package/dist/server/adapters/next.js +25 -0
- package/dist/server/adapters/next.js.map +1 -0
- package/dist/server/index.cjs +1093 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +131 -0
- package/dist/server/index.d.ts +131 -0
- package/dist/server/index.js +1080 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types-Cgfcw91r.d.cts +282 -0
- package/dist/types-Cgfcw91r.d.ts +282 -0
- package/dist/types-OVKV6qpE.d.cts +118 -0
- package/dist/types-OVKV6qpE.d.ts +118 -0
- package/package.json +78 -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,602 @@
|
|
|
1
|
+
# agentxjs
|
|
2
|
+
|
|
3
|
+
> "Define Once, Run Anywhere" - Unified Platform API for AI Agents
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`agentxjs` is the **central entry point** for the AgentX platform, providing a complete API for building and managing AI agents across different deployment scenarios.
|
|
8
|
+
|
|
9
|
+
**Key Characteristics:**
|
|
10
|
+
|
|
11
|
+
- **"Define Once, Run Anywhere"** - Same AgentDefinition works on Server and Browser
|
|
12
|
+
- **Docker-Style Layered Architecture** - Definition → Image → Agent lifecycle
|
|
13
|
+
- **Runtime Abstraction** - Platform provides Runtime (NodeRuntime, SSERuntime)
|
|
14
|
+
- **Web Standard Based** - Server built on Request/Response API, framework-agnostic
|
|
15
|
+
- **Stream-First Transport** - Efficient SSE transmission with client-side reassembly
|
|
16
|
+
- **Framework Adapters** - Ready-to-use adapters for Express, Hono, Next.js
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add agentxjs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Architecture Overview
|
|
27
|
+
|
|
28
|
+
```text
|
|
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
|
+
---
|
|
73
|
+
|
|
74
|
+
## Docker-Style Layered Architecture
|
|
75
|
+
|
|
76
|
+
AgentX uses a Docker-inspired lifecycle for agent management:
|
|
77
|
+
|
|
78
|
+
```text
|
|
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
|
+
```
|
|
110
|
+
|
|
111
|
+
**Key Principle**: Definition cannot directly become Agent. Must go through Image first.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Module Reference
|
|
116
|
+
|
|
117
|
+
### Core API (`/`)
|
|
118
|
+
|
|
119
|
+
The main entry point for creating AgentX instances.
|
|
120
|
+
|
|
121
|
+
| Export | Type | Description |
|
|
122
|
+
| -------------- | -------- | ---------------------------------------- |
|
|
123
|
+
| `defineAgent` | Function | Define an agent template |
|
|
124
|
+
| `createAgentX` | Function | Factory for AgentX platform with Runtime |
|
|
125
|
+
| `sseRuntime` | Function | Create browser SSE runtime |
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { defineAgent, createAgentX } from "agentxjs";
|
|
129
|
+
import { nodeRuntime } from "@agentxjs/node-runtime";
|
|
130
|
+
|
|
131
|
+
// 1. Define agent (business config only)
|
|
132
|
+
const MyAgent = defineAgent({
|
|
133
|
+
name: "Assistant",
|
|
134
|
+
description: "A helpful assistant",
|
|
135
|
+
systemPrompt: "You are a helpful assistant",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// 2. Create platform with runtime
|
|
139
|
+
const agentx = createAgentX(nodeRuntime());
|
|
140
|
+
|
|
141
|
+
// 3. Register definition (creates MetaImage automatically)
|
|
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);
|
|
147
|
+
|
|
148
|
+
// 5. Use agent
|
|
149
|
+
await agent.receive("Hello!");
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### AgentX Interface
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
interface AgentX {
|
|
156
|
+
readonly runtime: Runtime;
|
|
157
|
+
readonly definitions: DefinitionManager;
|
|
158
|
+
readonly images: ImageManager;
|
|
159
|
+
readonly agents: AgentManager;
|
|
160
|
+
readonly sessions: SessionManager;
|
|
161
|
+
readonly errors: ErrorManager;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface DefinitionManager {
|
|
165
|
+
register(definition: AgentDefinition): void;
|
|
166
|
+
get(name: string): AgentDefinition | undefined;
|
|
167
|
+
has(name: string): boolean;
|
|
168
|
+
list(): AgentDefinition[];
|
|
169
|
+
unregister(name: string): boolean;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
interface ImageManager {
|
|
173
|
+
get(imageId: string): AgentImage | undefined;
|
|
174
|
+
getMetaImage(definitionName: string): AgentImage | undefined;
|
|
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
|
+
}
|
|
181
|
+
|
|
182
|
+
interface AgentManager {
|
|
183
|
+
get(agentId: string): Agent | undefined;
|
|
184
|
+
has(agentId: string): boolean;
|
|
185
|
+
list(): Agent[];
|
|
186
|
+
destroy(agentId: string): boolean;
|
|
187
|
+
destroyAll(): void;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface SessionManager {
|
|
191
|
+
create(imageId: string, options?: SessionOptions): Promise<Session>;
|
|
192
|
+
get(sessionId: string): Session | undefined;
|
|
193
|
+
list(): Session[];
|
|
194
|
+
listByImage(imageId: string): Session[];
|
|
195
|
+
listByUser(userId: string): Session[];
|
|
196
|
+
destroy(sessionId: string): boolean;
|
|
197
|
+
destroyByImage(imageId: string): boolean;
|
|
198
|
+
destroyAll(): void;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
interface ErrorManager {
|
|
202
|
+
handle(error: AgentError): void;
|
|
203
|
+
addHandler(handler: ErrorHandler): void;
|
|
204
|
+
removeHandler(handler: ErrorHandler): void;
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### Session Interface
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface Session {
|
|
212
|
+
readonly id: string;
|
|
213
|
+
readonly imageId: string;
|
|
214
|
+
readonly agent: Agent;
|
|
215
|
+
|
|
216
|
+
// Resume from previous state
|
|
217
|
+
resume(): Promise<void>;
|
|
218
|
+
|
|
219
|
+
// Fork session with copied message history
|
|
220
|
+
fork(): Promise<Session>;
|
|
221
|
+
|
|
222
|
+
// Auto-subscribe and persist messages
|
|
223
|
+
collect(): Unsubscribe;
|
|
224
|
+
|
|
225
|
+
// Get persisted conversation history
|
|
226
|
+
getMessages(): Promise<Message[]>;
|
|
227
|
+
|
|
228
|
+
// Update session metadata
|
|
229
|
+
setTitle(title: string): Promise<void>;
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
### Server Module (`/server`)
|
|
236
|
+
|
|
237
|
+
HTTP handler and SSE transport for exposing agents over the network.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { createAgentXHandler } from "agentxjs/server";
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### `createAgentXHandler(agentx, options?)`
|
|
244
|
+
|
|
245
|
+
Creates a framework-agnostic HTTP handler based on Web Standard Request/Response.
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
const handler = createAgentXHandler(agentx, {
|
|
249
|
+
basePath: "/agentx", // URL prefix
|
|
250
|
+
allowDynamicCreation: false, // Enable POST /agents
|
|
251
|
+
allowedDefinitions: [], // Whitelist for dynamic creation
|
|
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>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### HTTP API Endpoints
|
|
272
|
+
|
|
273
|
+
| Method | Path | Description |
|
|
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:
|
|
302
|
+
|
|
303
|
+
```text
|
|
304
|
+
Server AgentEngine
|
|
305
|
+
│
|
|
306
|
+
├── text_delta ─┐
|
|
307
|
+
├── tool_call │
|
|
308
|
+
├── message_start ├──▶ SSE Stream
|
|
309
|
+
├── message_stop │
|
|
310
|
+
└── error ─┘
|
|
311
|
+
│
|
|
312
|
+
▼
|
|
313
|
+
Browser Client
|
|
314
|
+
│
|
|
315
|
+
AgentEngine (client)
|
|
316
|
+
│
|
|
317
|
+
Reassembles:
|
|
318
|
+
├── assistant_message
|
|
319
|
+
├── tool_call_message
|
|
320
|
+
└── turn_response
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
### Server Adapters (`/server/adapters`)
|
|
326
|
+
|
|
327
|
+
Ready-to-use adapters for popular HTTP frameworks.
|
|
328
|
+
|
|
329
|
+
#### Express
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { toExpressHandler } from "agentxjs/server/adapters/express";
|
|
333
|
+
import express from "express";
|
|
334
|
+
|
|
335
|
+
const app = express();
|
|
336
|
+
app.use(express.json());
|
|
337
|
+
app.use("/agentx", toExpressHandler(handler));
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### Hono
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { createHonoRoutes } from "agentxjs/server/adapters/hono";
|
|
344
|
+
import { Hono } from "hono";
|
|
345
|
+
|
|
346
|
+
const app = new Hono();
|
|
347
|
+
createHonoRoutes(app, "/agentx", handler);
|
|
348
|
+
// or: app.all("/agentx/*", toHonoHandler(handler));
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### Next.js App Router
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// app/agentx/[...path]/route.ts
|
|
355
|
+
import { createNextHandler } from "agentxjs/server/adapters/next";
|
|
356
|
+
|
|
357
|
+
const handler = createAgentXHandler(agentx);
|
|
358
|
+
export const { GET, POST, DELETE } = createNextHandler(handler, {
|
|
359
|
+
basePath: "/agentx",
|
|
360
|
+
});
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### Client Module (`/client`)
|
|
366
|
+
|
|
367
|
+
Browser SDK for connecting to remote AgentX servers using the same API.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import { sseRuntime } from "agentxjs/client";
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
#### `sseRuntime(config)`
|
|
374
|
+
|
|
375
|
+
Creates a browser-compatible Runtime that connects to remote server:
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { defineAgent, createAgentX } from "agentxjs";
|
|
379
|
+
import { sseRuntime } from "agentxjs/client";
|
|
380
|
+
|
|
381
|
+
// Same agent definition as server!
|
|
382
|
+
const MyAgent = defineAgent({
|
|
383
|
+
name: "Assistant",
|
|
384
|
+
systemPrompt: "You are a helpful assistant",
|
|
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
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// Same API as server-side!
|
|
395
|
+
const agentx = createAgentX(runtime);
|
|
396
|
+
|
|
397
|
+
// Register definition (syncs with server)
|
|
398
|
+
agentx.definitions.register(MyAgent);
|
|
399
|
+
|
|
400
|
+
// Run agent
|
|
401
|
+
const metaImage = agentx.images.getMetaImage(MyAgent.name);
|
|
402
|
+
const agent = await agentx.images.run(metaImage.id);
|
|
403
|
+
|
|
404
|
+
// Subscribe to events
|
|
405
|
+
agent.on("assistant_message", (event) => {
|
|
406
|
+
console.log(event.data.content);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
await agent.receive("Hello!");
|
|
410
|
+
```
|
|
411
|
+
|
|
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
|
+
---
|
|
426
|
+
|
|
427
|
+
## Design Decisions
|
|
428
|
+
|
|
429
|
+
### Why Docker-Style Architecture?
|
|
430
|
+
|
|
431
|
+
The Definition → Image → Agent flow mirrors Docker's Dockerfile → Image → Container:
|
|
432
|
+
|
|
433
|
+
1. **Definition** = Template (like Dockerfile)
|
|
434
|
+
2. **Image** = Frozen snapshot (like Docker image)
|
|
435
|
+
3. **Agent** = Running instance (like Docker container)
|
|
436
|
+
4. **Session** = User-facing wrapper (like Docker compose service)
|
|
437
|
+
|
|
438
|
+
**Benefits:**
|
|
439
|
+
|
|
440
|
+
- Versioning: Create derived images with different configs
|
|
441
|
+
- Rollback: Return to previous image versions
|
|
442
|
+
- Consistency: Same image produces same behavior
|
|
443
|
+
- Separation: Business config (definition) vs runtime state (image)
|
|
444
|
+
|
|
445
|
+
### Why Five Managers?
|
|
446
|
+
|
|
447
|
+
| Manager | Scope | Responsibility |
|
|
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 |
|
|
454
|
+
|
|
455
|
+
**Key Principle**: AgentManager only queries. Creation happens via `images.run()` or `sessions.create()`.
|
|
456
|
+
|
|
457
|
+
### Why "Define Once, Run Anywhere"?
|
|
458
|
+
|
|
459
|
+
AgentDefinition contains only business config (name, systemPrompt).
|
|
460
|
+
Runtime provides infrastructure (Driver, Sandbox).
|
|
461
|
+
|
|
462
|
+
| Environment | Runtime | Driver | Use Case |
|
|
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) |
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Same agent definition everywhere
|
|
470
|
+
const MyAgent = defineAgent({
|
|
471
|
+
name: "Assistant",
|
|
472
|
+
systemPrompt: "You are helpful",
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// Different runtimes for different environments
|
|
476
|
+
const agentx = createAgentX(nodeRuntime()); // Server
|
|
477
|
+
const agentx = createAgentX(sseRuntime({ serverUrl })); // Browser
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Why Web Standard Request/Response?
|
|
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
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
// The handler is just a function
|
|
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
|
+
};
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Why Stream-Only SSE Transport?
|
|
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
|
+
```
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## Package Dependencies
|
|
568
|
+
|
|
569
|
+
```text
|
|
570
|
+
agentx-types (type definitions)
|
|
571
|
+
↑
|
|
572
|
+
agentx-common (logging facade)
|
|
573
|
+
↑
|
|
574
|
+
agentx-engine (event processing)
|
|
575
|
+
↑
|
|
576
|
+
agentx-agent (Agent runtime)
|
|
577
|
+
↑
|
|
578
|
+
agentx (this package) ← Platform API + defineAgent + sseRuntime
|
|
579
|
+
↑
|
|
580
|
+
agentx-runtime (NodeRuntime + ClaudeDriver)
|
|
581
|
+
↑
|
|
582
|
+
agentx-ui (React components)
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
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
|
+
## License
|
|
601
|
+
|
|
602
|
+
MIT
|