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/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