agentxjs 1.9.0 → 1.9.2-dev
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/build.ts +26 -0
- package/package.json +8 -27
- package/src/RemoteClient.ts +221 -0
- package/src/index.ts +118 -0
- package/src/presentation/Presentation.ts +189 -0
- package/src/presentation/index.ts +32 -0
- package/src/presentation/reducer.ts +317 -0
- package/src/presentation/types.ts +111 -0
- package/src/types.ts +337 -0
- package/tsconfig.json +11 -0
- package/README.md +0 -393
- package/dist/browser.js +0 -275
- package/dist/browser.js.map +0 -12
- package/dist/index.d.ts +0 -58
- package/dist/index.js +0 -481
- package/dist/index.js.map +0 -13
package/README.md
DELETED
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
# agentxjs
|
|
2
|
-
|
|
3
|
-
> Unified API for AI Agents - Server and Browser
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
`agentxjs` provides a **unified API** for building AI agents that works seamlessly across server (Node.js) and browser environments.
|
|
8
|
-
|
|
9
|
-
**Key Features:**
|
|
10
|
-
|
|
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.)
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
pnpm add agentxjs
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Quick Start
|
|
25
|
-
|
|
26
|
-
### Server (Source Mode)
|
|
27
|
-
|
|
28
|
-
```typescript
|
|
29
|
-
import { createAgentX } from "agentxjs";
|
|
30
|
-
|
|
31
|
-
// Minimal - reads ANTHROPIC_API_KEY from environment
|
|
32
|
-
const agentx = createAgentX();
|
|
33
|
-
|
|
34
|
-
// Or with explicit configuration
|
|
35
|
-
const agentx = createAgentX({
|
|
36
|
-
apiKey: "sk-ant-...",
|
|
37
|
-
model: "claude-sonnet-4-20250514",
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// Run an agent
|
|
41
|
-
const agent = await agentx.run({ name: "Assistant" });
|
|
42
|
-
|
|
43
|
-
// Subscribe to events
|
|
44
|
-
agent.on("text_delta", (e) => process.stdout.write(e.data.text));
|
|
45
|
-
|
|
46
|
-
// Send message
|
|
47
|
-
await agent.receive("Hello!");
|
|
48
|
-
|
|
49
|
-
// Cleanup
|
|
50
|
-
await agentx.dispose();
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Browser (Mirror Mode)
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
import { createAgentX } from "agentxjs";
|
|
57
|
-
|
|
58
|
-
// Connect to remote server via WebSocket
|
|
59
|
-
const agentx = createAgentX({
|
|
60
|
-
serverUrl: "ws://localhost:5200",
|
|
61
|
-
token: "optional-auth-token",
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Same API as server!
|
|
65
|
-
const agent = await agentx.run({ name: "Assistant" });
|
|
66
|
-
|
|
67
|
-
agent.on("text_delta", (e) => console.log(e.data.text));
|
|
68
|
-
|
|
69
|
-
await agent.receive("Hello!");
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## API Design
|
|
75
|
-
|
|
76
|
-
### Configuration Types
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
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;
|
|
85
|
-
}
|
|
86
|
-
|
|
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>;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Type discrimination: presence of `serverUrl` determines mode
|
|
95
|
-
type AgentXConfig = SourceConfig | MirrorConfig;
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Type Guards
|
|
99
|
-
|
|
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);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (isSourceConfig(config)) {
|
|
111
|
-
// TypeScript knows this is SourceConfig
|
|
112
|
-
console.log(config.apiKey);
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### AgentX Interface
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
interface AgentX {
|
|
120
|
-
// Quick start - run agent in default container
|
|
121
|
-
run(config: AgentRunConfig): Promise<Agent>;
|
|
122
|
-
|
|
123
|
-
// Container management
|
|
124
|
-
readonly containers: ContainersAPI;
|
|
125
|
-
|
|
126
|
-
// Agent management (cross-container)
|
|
127
|
-
readonly agents: AgentsAPI;
|
|
128
|
-
|
|
129
|
-
// Image (snapshot) management
|
|
130
|
-
readonly images: ImagesAPI;
|
|
131
|
-
|
|
132
|
-
// Cleanup
|
|
133
|
-
dispose(): Promise<void>;
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Sub-APIs
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
// Container management
|
|
141
|
-
interface ContainersAPI {
|
|
142
|
-
create(containerId: string): Promise<Container>;
|
|
143
|
-
get(containerId: string): Container | undefined;
|
|
144
|
-
list(): Container[];
|
|
145
|
-
}
|
|
146
|
-
|
|
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
|
-
}
|
|
155
|
-
|
|
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
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Agent Run Configuration
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
interface AgentRunConfig {
|
|
169
|
-
name: string;
|
|
170
|
-
systemPrompt?: string;
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Architecture
|
|
177
|
-
|
|
178
|
-
```text
|
|
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
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Source vs Mirror
|
|
209
|
-
|
|
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 |
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Docker-Style Lifecycle
|
|
221
|
-
|
|
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
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Image Operations
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
// Create snapshot
|
|
248
|
-
const agent = await agentx.run({ name: "Assistant" });
|
|
249
|
-
await agent.receive("Hello!");
|
|
250
|
-
const image = await agentx.images.snapshot(agent);
|
|
251
|
-
|
|
252
|
-
// Resume from snapshot
|
|
253
|
-
const resumedAgent = await image.resume();
|
|
254
|
-
// Agent has previous conversation history
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
## Event System
|
|
260
|
-
|
|
261
|
-
### Stream Events (Real-time)
|
|
262
|
-
|
|
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 */
|
|
276
|
-
});
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Subscribe to All Events
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
agent.on((event) => {
|
|
283
|
-
console.log(event.type, event.data);
|
|
284
|
-
});
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## Advanced Usage
|
|
290
|
-
|
|
291
|
-
### Container Management
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
// Create named container
|
|
295
|
-
const container = await agentx.containers.create("my-container");
|
|
296
|
-
|
|
297
|
-
// Run agent in container
|
|
298
|
-
const agent = await agentx.agents.run("my-container", {
|
|
299
|
-
name: "Assistant",
|
|
300
|
-
systemPrompt: "You are helpful",
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// List agents in container
|
|
304
|
-
const agents = agentx.agents.list("my-container");
|
|
305
|
-
|
|
306
|
-
// Destroy all agents in container
|
|
307
|
-
await agentx.agents.destroyAll("my-container");
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
### Custom Persistence (Source Mode)
|
|
311
|
-
|
|
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
|
-
}),
|
|
322
|
-
});
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
---
|
|
326
|
-
|
|
327
|
-
## Design Decisions
|
|
328
|
-
|
|
329
|
-
### Why Unified `createAgentX`?
|
|
330
|
-
|
|
331
|
-
Instead of separate `createSource()` and `createMirror()` functions, we use a single `createAgentX()` with type discrimination:
|
|
332
|
-
|
|
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
|
-
```
|
|
339
|
-
|
|
340
|
-
**Benefits:**
|
|
341
|
-
|
|
342
|
-
- Single import, single function to learn
|
|
343
|
-
- TypeScript enforces correct configuration
|
|
344
|
-
- Easy refactoring between modes
|
|
345
|
-
|
|
346
|
-
### Why WebSocket for Mirror?
|
|
347
|
-
|
|
348
|
-
Mirror mode uses WebSocket (not HTTP/SSE) for bidirectional communication:
|
|
349
|
-
|
|
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
|
|
353
|
-
|
|
354
|
-
### Why No `defineAgent`?
|
|
355
|
-
|
|
356
|
-
Previous versions required:
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
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();
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
New API is simpler:
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
const agent = await agentx.run({ name: "Assistant", ... });
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
The `AgentRunConfig` replaces `AgentDefinition` for most use cases. For advanced scenarios (versioning, derived images), use the Images API directly.
|
|
372
|
-
|
|
373
|
-
---
|
|
374
|
-
|
|
375
|
-
## Package Dependencies
|
|
376
|
-
|
|
377
|
-
```text
|
|
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)
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## License
|
|
392
|
-
|
|
393
|
-
MIT
|
package/dist/browser.js
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
7
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
8
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
9
|
-
for (let key of __getOwnPropNames(mod))
|
|
10
|
-
if (!__hasOwnProp.call(to, key))
|
|
11
|
-
__defProp(to, key, {
|
|
12
|
-
get: () => mod[key],
|
|
13
|
-
enumerable: true
|
|
14
|
-
});
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
19
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
20
|
-
}) : x)(function(x) {
|
|
21
|
-
if (typeof require !== "undefined")
|
|
22
|
-
return require.apply(this, arguments);
|
|
23
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// src/createRemoteAgentX.ts
|
|
27
|
-
import { hasSubscriptions } from "@agentxjs/types/agentx";
|
|
28
|
-
import { createLogger, generateRequestId } from "@agentxjs/common";
|
|
29
|
-
async function createRemoteAgentX(config) {
|
|
30
|
-
const { createWebSocketClient } = await import("@agentxjs/network");
|
|
31
|
-
const client = await createWebSocketClient({
|
|
32
|
-
serverUrl: config.serverUrl,
|
|
33
|
-
headers: config.headers,
|
|
34
|
-
autoReconnect: true,
|
|
35
|
-
minReconnectionDelay: 1000,
|
|
36
|
-
maxReconnectionDelay: 1e4,
|
|
37
|
-
connectionTimeout: 4000,
|
|
38
|
-
maxRetries: Infinity,
|
|
39
|
-
debug: false
|
|
40
|
-
});
|
|
41
|
-
logger.info("Client connected");
|
|
42
|
-
const handlers = new Map;
|
|
43
|
-
const pendingRequests = new Map;
|
|
44
|
-
const subscribedSessions = new Set(["global"]);
|
|
45
|
-
function subscribeToSession(sessionId) {
|
|
46
|
-
if (subscribedSessions.has(sessionId)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
client.send(JSON.stringify({
|
|
50
|
-
type: "subscribe",
|
|
51
|
-
sessionId
|
|
52
|
-
}));
|
|
53
|
-
subscribedSessions.add(sessionId);
|
|
54
|
-
logger.debug("Subscribed to session", { sessionId });
|
|
55
|
-
}
|
|
56
|
-
client.onMessage((message) => {
|
|
57
|
-
try {
|
|
58
|
-
const event = JSON.parse(message);
|
|
59
|
-
logger.debug("Received event", {
|
|
60
|
-
type: event.type,
|
|
61
|
-
category: event.category,
|
|
62
|
-
requestId: event.data?.requestId
|
|
63
|
-
});
|
|
64
|
-
if (event.type === "system_error") {
|
|
65
|
-
const errorData = event.data;
|
|
66
|
-
logger.error(errorData.message, {
|
|
67
|
-
severity: errorData.severity,
|
|
68
|
-
requestId: event.data?.requestId,
|
|
69
|
-
details: errorData.details
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
const requestId = event.data?.requestId;
|
|
73
|
-
if (event.category === "response" && requestId && pendingRequests.has(requestId)) {
|
|
74
|
-
logger.debug("Resolving pending request", { requestId, eventType: event.type });
|
|
75
|
-
const pending = pendingRequests.get(requestId);
|
|
76
|
-
clearTimeout(pending.timer);
|
|
77
|
-
pendingRequests.delete(requestId);
|
|
78
|
-
pending.resolve(event);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const typeHandlers = handlers.get(event.type);
|
|
82
|
-
if (typeHandlers) {
|
|
83
|
-
for (const handler of typeHandlers) {
|
|
84
|
-
handler(event);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const allHandlers = handlers.get("*");
|
|
88
|
-
if (allHandlers) {
|
|
89
|
-
for (const handler of allHandlers) {
|
|
90
|
-
handler(event);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
} catch {}
|
|
94
|
-
});
|
|
95
|
-
client.onClose(() => {
|
|
96
|
-
logger.warn("WebSocket closed");
|
|
97
|
-
});
|
|
98
|
-
client.onError((error) => {
|
|
99
|
-
logger.error("WebSocket error", { error: error.message });
|
|
100
|
-
});
|
|
101
|
-
client.onOpen(() => {
|
|
102
|
-
if (subscribedSessions.size > 1) {
|
|
103
|
-
logger.info("Reconnected, re-subscribing to sessions", {
|
|
104
|
-
sessions: Array.from(subscribedSessions)
|
|
105
|
-
});
|
|
106
|
-
for (const sessionId of subscribedSessions) {
|
|
107
|
-
if (sessionId !== "global") {
|
|
108
|
-
client.send(JSON.stringify({
|
|
109
|
-
type: "subscribe",
|
|
110
|
-
sessionId
|
|
111
|
-
}));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
function subscribe(type, handler) {
|
|
117
|
-
if (!handlers.has(type)) {
|
|
118
|
-
handlers.set(type, new Set);
|
|
119
|
-
}
|
|
120
|
-
handlers.get(type).add(handler);
|
|
121
|
-
return () => {
|
|
122
|
-
handlers.get(type)?.delete(handler);
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
return {
|
|
126
|
-
async request(type, data, timeout = 30000) {
|
|
127
|
-
const requestId = generateRequestId();
|
|
128
|
-
let mergedData = { ...data, requestId };
|
|
129
|
-
if (config.context) {
|
|
130
|
-
try {
|
|
131
|
-
let resolvedContext;
|
|
132
|
-
if (typeof config.context === "function") {
|
|
133
|
-
resolvedContext = await Promise.resolve(config.context());
|
|
134
|
-
} else {
|
|
135
|
-
resolvedContext = config.context;
|
|
136
|
-
}
|
|
137
|
-
mergedData = {
|
|
138
|
-
...resolvedContext,
|
|
139
|
-
...data,
|
|
140
|
-
requestId
|
|
141
|
-
};
|
|
142
|
-
logger.debug("Merged context into request", {
|
|
143
|
-
type,
|
|
144
|
-
requestId,
|
|
145
|
-
contextKeys: Object.keys(resolvedContext)
|
|
146
|
-
});
|
|
147
|
-
} catch (error) {
|
|
148
|
-
logger.error("Failed to resolve context", {
|
|
149
|
-
type,
|
|
150
|
-
requestId,
|
|
151
|
-
error: error instanceof Error ? error.message : String(error)
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
const response = await new Promise((resolve, reject) => {
|
|
156
|
-
const timer = setTimeout(() => {
|
|
157
|
-
pendingRequests.delete(requestId);
|
|
158
|
-
reject(new Error(`Request timeout: ${type}`));
|
|
159
|
-
}, timeout);
|
|
160
|
-
pendingRequests.set(requestId, {
|
|
161
|
-
resolve,
|
|
162
|
-
reject,
|
|
163
|
-
timer
|
|
164
|
-
});
|
|
165
|
-
const event = {
|
|
166
|
-
type,
|
|
167
|
-
timestamp: Date.now(),
|
|
168
|
-
data: mergedData,
|
|
169
|
-
source: "command",
|
|
170
|
-
category: "request",
|
|
171
|
-
intent: "request"
|
|
172
|
-
};
|
|
173
|
-
client.send(JSON.stringify(event));
|
|
174
|
-
});
|
|
175
|
-
const responseData = response.data;
|
|
176
|
-
if (hasSubscriptions(responseData)) {
|
|
177
|
-
for (const sessionId of responseData.__subscriptions) {
|
|
178
|
-
subscribeToSession(sessionId);
|
|
179
|
-
}
|
|
180
|
-
logger.debug("Auto-subscribed to sessions from response", {
|
|
181
|
-
type,
|
|
182
|
-
sessionIds: responseData.__subscriptions
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
return response;
|
|
186
|
-
},
|
|
187
|
-
on(type, handler) {
|
|
188
|
-
return subscribe(type, handler);
|
|
189
|
-
},
|
|
190
|
-
onCommand(type, handler) {
|
|
191
|
-
return subscribe(type, handler);
|
|
192
|
-
},
|
|
193
|
-
emitCommand(type, data) {
|
|
194
|
-
const event = {
|
|
195
|
-
type,
|
|
196
|
-
timestamp: Date.now(),
|
|
197
|
-
data,
|
|
198
|
-
source: "command",
|
|
199
|
-
category: type.toString().endsWith("_response") ? "response" : "request",
|
|
200
|
-
intent: type.toString().endsWith("_response") ? "result" : "request"
|
|
201
|
-
};
|
|
202
|
-
client.send(JSON.stringify(event));
|
|
203
|
-
},
|
|
204
|
-
async listen() {
|
|
205
|
-
throw new Error("Cannot listen in remote mode");
|
|
206
|
-
},
|
|
207
|
-
async close() {},
|
|
208
|
-
async dispose() {
|
|
209
|
-
for (const pending of pendingRequests.values()) {
|
|
210
|
-
clearTimeout(pending.timer);
|
|
211
|
-
pending.reject(new Error("AgentX disposed"));
|
|
212
|
-
}
|
|
213
|
-
pendingRequests.clear();
|
|
214
|
-
handlers.clear();
|
|
215
|
-
subscribedSessions.clear();
|
|
216
|
-
client.dispose();
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
var logger;
|
|
221
|
-
var init_createRemoteAgentX = __esm(() => {
|
|
222
|
-
logger = createLogger("agentx/RemoteClient");
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// src/browser.ts
|
|
226
|
-
import { isLocalConfig, isRemoteConfig as isRemoteConfig2 } from "@agentxjs/types/agentx";
|
|
227
|
-
import {
|
|
228
|
-
isFromSource,
|
|
229
|
-
hasIntent,
|
|
230
|
-
isRequest,
|
|
231
|
-
isResult,
|
|
232
|
-
isNotification
|
|
233
|
-
} from "@agentxjs/types/event";
|
|
234
|
-
import { isCommandEvent, isCommandRequest, isCommandResponse } from "@agentxjs/types/event";
|
|
235
|
-
import {
|
|
236
|
-
isAgentEvent,
|
|
237
|
-
isAgentStreamEvent,
|
|
238
|
-
isAgentStateEvent,
|
|
239
|
-
isAgentMessageEvent,
|
|
240
|
-
isAgentTurnEvent
|
|
241
|
-
} from "@agentxjs/types/event";
|
|
242
|
-
import { isRemoteConfig as isRemoteConfig3 } from "@agentxjs/types/agentx";
|
|
243
|
-
|
|
244
|
-
// src/createAgentX.ts
|
|
245
|
-
init_createRemoteAgentX();
|
|
246
|
-
import { isRemoteConfig } from "@agentxjs/types/agentx";
|
|
247
|
-
|
|
248
|
-
// src/browser.ts
|
|
249
|
-
async function createAgentX(config) {
|
|
250
|
-
if (!config || !isRemoteConfig3(config)) {
|
|
251
|
-
throw new Error("Browser environment only supports remote mode. " + 'Please provide { serverUrl: "ws://..." } configuration.');
|
|
252
|
-
}
|
|
253
|
-
return createRemoteAgentX(config);
|
|
254
|
-
}
|
|
255
|
-
export {
|
|
256
|
-
isResult,
|
|
257
|
-
isRequest,
|
|
258
|
-
isRemoteConfig2 as isRemoteConfig,
|
|
259
|
-
isNotification,
|
|
260
|
-
isLocalConfig,
|
|
261
|
-
isFromSource,
|
|
262
|
-
isCommandResponse,
|
|
263
|
-
isCommandRequest,
|
|
264
|
-
isCommandEvent,
|
|
265
|
-
isAgentTurnEvent,
|
|
266
|
-
isAgentStreamEvent,
|
|
267
|
-
isAgentStateEvent,
|
|
268
|
-
isAgentMessageEvent,
|
|
269
|
-
isAgentEvent,
|
|
270
|
-
hasIntent,
|
|
271
|
-
createRemoteAgentX,
|
|
272
|
-
createAgentX
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
//# debugId=DABE902E367A863664756E2164756E21
|