@agentxjs/core 1.9.10-dev → 2.0.0
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 +342 -0
- package/dist/RpcClient-BcJ_zAGu.d.ts +304 -0
- package/dist/agent/engine/internal/index.d.ts +20 -15
- package/dist/agent/engine/internal/index.js +1 -2
- package/dist/agent/engine/mealy/index.js +0 -1
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +15 -15
- package/dist/agent/types/index.d.ts +4 -4
- package/dist/agent/types/index.js +1 -2
- package/dist/bash/index.d.ts +29 -0
- package/dist/bash/index.js +7 -0
- package/dist/{bus-uF1DM2ox.d.ts → bus-C9FLWIu8.d.ts} +3 -1
- package/dist/{chunk-K6WXQ2RW.js → chunk-23UUBQXR.js} +1 -2
- package/dist/chunk-23UUBQXR.js.map +1 -0
- package/dist/chunk-BHOD5PKR.js +55 -0
- package/dist/chunk-BHOD5PKR.js.map +1 -0
- package/dist/{chunk-I7GYR3MN.js → chunk-DEAR6N3O.js} +77 -91
- package/dist/chunk-DEAR6N3O.js.map +1 -0
- package/dist/chunk-FI7WQFGV.js +37 -0
- package/dist/chunk-FI7WQFGV.js.map +1 -0
- package/dist/{chunk-AT5P47YA.js → chunk-JTKCV7IS.js} +9 -9
- package/dist/chunk-JTKCV7IS.js.map +1 -0
- package/dist/{chunk-E5FPOAPO.js → chunk-LTVNPHST.js} +1 -1
- package/dist/chunk-LTVNPHST.js.map +1 -0
- package/dist/chunk-SKS7S2RY.js +1 -0
- package/dist/common/logger/index.js +0 -2
- package/dist/common/logger/index.js.map +1 -1
- package/dist/container/index.d.ts +3 -4
- package/dist/container/index.js +0 -2
- package/dist/container/index.js.map +1 -1
- package/dist/driver/index.d.ts +2 -310
- package/dist/event/index.d.ts +4 -4
- package/dist/event/index.js +1 -2
- package/dist/event/types/index.d.ts +4 -10
- package/dist/event/types/index.js +1 -2
- package/dist/{event-CDuTzs__.d.ts → event-DNWOBSBO.d.ts} +3 -4
- package/dist/image/index.d.ts +9 -5
- package/dist/image/index.js +5 -2
- package/dist/image/index.js.map +1 -1
- package/dist/index-CuS1i5V-.d.ts +609 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +16 -16
- package/dist/{message-BMrMm1pq.d.ts → message-03TJzvIX.d.ts} +10 -33
- package/dist/mq/index.js +0 -2
- package/dist/mq/index.js.map +1 -1
- package/dist/network/index.d.ts +3 -291
- package/dist/network/index.js +3 -14
- package/dist/network/index.js.map +1 -1
- package/dist/persistence/index.d.ts +2 -155
- package/dist/platform/index.d.ts +76 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/runtime/index.d.ts +26 -59
- package/dist/runtime/index.js +117 -33
- package/dist/runtime/index.js.map +1 -1
- package/dist/session/index.d.ts +4 -52
- package/dist/session/index.js +4 -51
- package/dist/session/index.js.map +1 -1
- package/dist/types-aE74Eo6G.d.ts +90 -0
- package/package.json +10 -5
- package/src/agent/__tests__/engine/internal/messageAssemblerProcessor.test.ts +291 -87
- package/src/agent/__tests__/engine/internal/turnTrackerProcessor.test.ts +56 -75
- package/src/agent/engine/MealyMachine.ts +1 -1
- package/src/agent/engine/internal/messageAssemblerProcessor.ts +99 -114
- package/src/agent/engine/internal/turnTrackerProcessor.ts +23 -27
- package/src/agent/types/event.ts +0 -4
- package/src/agent/types/index.ts +1 -3
- package/src/agent/types/message.ts +9 -43
- package/src/bash/index.ts +21 -0
- package/src/bash/tool.ts +57 -0
- package/src/bash/types.ts +108 -0
- package/src/driver/index.ts +1 -0
- package/src/driver/types.ts +122 -4
- package/src/event/__tests__/EventBus.test.ts +1 -1
- package/src/event/types/agent.ts +0 -11
- package/src/event/types/command.ts +3 -1
- package/src/image/Image.ts +11 -1
- package/src/image/types.ts +8 -2
- package/src/network/RpcClient.ts +21 -20
- package/src/network/index.ts +1 -1
- package/src/persistence/types.ts +5 -2
- package/src/platform/index.ts +21 -0
- package/src/platform/types.ts +84 -0
- package/src/runtime/AgentXRuntime.ts +184 -57
- package/src/runtime/__tests__/AgentXRuntime.test.ts +343 -0
- package/src/runtime/index.ts +7 -19
- package/src/runtime/types.ts +10 -62
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-AT5P47YA.js.map +0 -1
- package/dist/chunk-E5FPOAPO.js.map +0 -1
- package/dist/chunk-I7GYR3MN.js.map +0 -1
- package/dist/chunk-K6WXQ2RW.js.map +0 -1
- package/dist/workspace/index.d.ts +0 -111
- package/dist/wrapper-Y3UTVU2E.js +0 -3635
- package/dist/wrapper-Y3UTVU2E.js.map +0 -1
- package/src/workspace/index.ts +0 -27
- package/src/workspace/types.ts +0 -131
- /package/dist/{workspace → bash}/index.js.map +0 -0
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-SKS7S2RY.js.map} +0 -0
- /package/dist/{workspace → platform}/index.js +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# @agentxjs/core
|
|
2
|
+
|
|
3
|
+
Foundation library for the AgentX framework — a TypeScript toolkit for building AI agent applications with tool use, streaming, and multi-turn conversation.
|
|
4
|
+
|
|
5
|
+
`@agentxjs/core` defines the types, interfaces, and agent engine that every other AgentX package depends on. You typically don't install it directly — it's pulled in as a dependency of `agentxjs`, `@agentxjs/server`, or driver packages.
|
|
6
|
+
|
|
7
|
+
## Core Concepts
|
|
8
|
+
|
|
9
|
+
AgentX is built around five concepts that work together:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Container ──contains──► Image ──has──► Session
|
|
13
|
+
│
|
|
14
|
+
created as──► Agent ──uses──► Driver
|
|
15
|
+
│
|
|
16
|
+
runs on──► Platform
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Container
|
|
20
|
+
|
|
21
|
+
A **Container** groups related agent configurations. Think of it as a namespace — one per app, workspace, or tenant. All Images inside a Container share the same isolation boundary.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Create a container for your app
|
|
25
|
+
const container = await runtime.getOrCreateContainer("my-app");
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Image
|
|
29
|
+
|
|
30
|
+
An **Image** is a persistent agent configuration: system prompt, MCP server definitions, and settings. One Image can spawn many Agents over time. When you update the Image, the next Agent created from it picks up the changes.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Create an image (configuration) inside the container
|
|
34
|
+
const image = await createImage(
|
|
35
|
+
{
|
|
36
|
+
containerId: "my-app",
|
|
37
|
+
name: "CodeReviewer",
|
|
38
|
+
systemPrompt: "You are a code review assistant.",
|
|
39
|
+
mcpServers: {
|
|
40
|
+
/* optional tool servers */
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
ctx
|
|
44
|
+
);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Session
|
|
48
|
+
|
|
49
|
+
A **Session** holds the conversation message history for an Image. Each Image has one active Session. Messages accumulate across multiple Agent runs, providing continuity.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Session is created automatically with the Image
|
|
53
|
+
// Messages are persisted and survive agent restarts
|
|
54
|
+
const messages = session.getMessages(); // full conversation history
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Driver
|
|
58
|
+
|
|
59
|
+
A **Driver** handles communication with an LLM provider. It takes a user message, sends it to the API, and returns a stream of events (text chunks, tool calls, etc.). To support a new LLM provider, you implement the Driver interface:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
interface Driver {
|
|
63
|
+
receive(message: UserMessage): AsyncIterable<DriverStreamEvent>;
|
|
64
|
+
initialize(): Promise<void>;
|
|
65
|
+
dispose(): Promise<void>;
|
|
66
|
+
interrupt(): void;
|
|
67
|
+
readonly state: DriverState; // "idle" | "active" | "disposed"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Factory function that the runtime calls to create a Driver per agent
|
|
71
|
+
type CreateDriver = (config: DriverConfig) => Driver;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**To add a new LLM provider**: implement `Driver` and export a `CreateDriver` factory. Your factory receives `DriverConfig` with `apiKey`, `model`, `systemPrompt`, `session` (for message history), and `mcpServers`. See `@agentxjs/mono-driver` for a reference implementation.
|
|
75
|
+
|
|
76
|
+
### Platform
|
|
77
|
+
|
|
78
|
+
A **Platform** provides the infrastructure: repositories for data storage, an event bus for streaming, and optional bash execution. To change where data is stored (e.g., from SQLite to PostgreSQL), you implement the repository interfaces and wire them into a Platform:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
interface AgentXPlatform {
|
|
82
|
+
containerRepository: ContainerRepository; // CRUD for containers
|
|
83
|
+
imageRepository: ImageRepository; // CRUD for images + metadata
|
|
84
|
+
sessionRepository: SessionRepository; // CRUD for sessions + messages
|
|
85
|
+
eventBus: EventBus; // pub/sub for stream events
|
|
86
|
+
bashProvider?: BashProvider; // optional shell execution
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**To change storage backend**: implement `ContainerRepository`, `ImageRepository`, and `SessionRepository`. Each repository is a simple CRUD interface. See `@agentxjs/node-platform` for a SQLite reference implementation.
|
|
91
|
+
|
|
92
|
+
## AgentEngine Pipeline
|
|
93
|
+
|
|
94
|
+
The Runtime doesn't just relay raw driver events — it processes them through a **MealyMachine** that derives higher-level events:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Driver Stream Events (raw)
|
|
98
|
+
│
|
|
99
|
+
├── message_start, text_delta, tool_use_start, message_stop ...
|
|
100
|
+
│
|
|
101
|
+
▼
|
|
102
|
+
MealyMachine ── pure (state, event) → [newState, outputs]
|
|
103
|
+
│
|
|
104
|
+
├── MessageAssembler ── stream → message events
|
|
105
|
+
│ └── assistant_message, tool_call_message, tool_result_message, error_message
|
|
106
|
+
│
|
|
107
|
+
├── StateEventProcessor ── stream → state events
|
|
108
|
+
│ └── conversation_start, conversation_responding, conversation_end
|
|
109
|
+
│
|
|
110
|
+
└── TurnTracker ── stream → turn events
|
|
111
|
+
└── turn_request (from message_start), turn_response (from message_stop)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Key design**: only raw `StreamEvent`s enter the MealyMachine. All message, state, and turn events are **derived** — never injected from outside. Processors can chain: outputs from one processor feed into others (e.g., TurnTracker reads `message_start` / `message_stop` from the stream layer).
|
|
115
|
+
|
|
116
|
+
The Runtime's **Presenter** handles the outputs:
|
|
117
|
+
|
|
118
|
+
- **Stream events**: emitted directly to EventBus (for real-time UI streaming)
|
|
119
|
+
- **Message events**: emitted to EventBus + persisted to SessionRepository
|
|
120
|
+
- **State/Turn events**: emitted to EventBus
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Subscribe to different event layers
|
|
124
|
+
runtime.subscribe(agentId, (event) => {
|
|
125
|
+
switch (event.type) {
|
|
126
|
+
// Stream layer — real-time chunks
|
|
127
|
+
case "text_delta":
|
|
128
|
+
process.stdout.write(event.data.text);
|
|
129
|
+
break;
|
|
130
|
+
|
|
131
|
+
// Message layer — complete, persisted messages
|
|
132
|
+
case "assistant_message":
|
|
133
|
+
console.log("Full reply:", event.data.content);
|
|
134
|
+
break;
|
|
135
|
+
|
|
136
|
+
// State layer — conversation lifecycle
|
|
137
|
+
case "conversation_start":
|
|
138
|
+
case "conversation_end":
|
|
139
|
+
break;
|
|
140
|
+
|
|
141
|
+
// Turn layer — request-response tracking
|
|
142
|
+
case "turn_response":
|
|
143
|
+
console.log(`Turn took ${event.data.duration}ms`);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Quick Start
|
|
150
|
+
|
|
151
|
+
Most developers use `agentxjs` (the SDK) instead of `@agentxjs/core` directly. Core is for building custom drivers, platforms, or extending the framework.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { createAgentXRuntime } from "@agentxjs/core/runtime";
|
|
155
|
+
|
|
156
|
+
// Platform and driver come from other packages
|
|
157
|
+
const runtime = createAgentXRuntime(platform, createDriver);
|
|
158
|
+
|
|
159
|
+
const agent = await runtime.createAgent({ imageId: "img_xxx" });
|
|
160
|
+
|
|
161
|
+
const sub = runtime.subscribe(agent.agentId, (event) => {
|
|
162
|
+
if (event.type === "text_delta") {
|
|
163
|
+
process.stdout.write(event.data.text);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
await runtime.receive(agent.agentId, "Hello!");
|
|
168
|
+
|
|
169
|
+
sub.unsubscribe();
|
|
170
|
+
await runtime.destroyAgent(agent.agentId);
|
|
171
|
+
await runtime.shutdown();
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## API Reference
|
|
175
|
+
|
|
176
|
+
### Sub-module Imports
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { ... } from "@agentxjs/core"; // common + agent
|
|
180
|
+
import { ... } from "@agentxjs/core/agent"; // agent engine
|
|
181
|
+
import { ... } from "@agentxjs/core/container"; // container management
|
|
182
|
+
import { ... } from "@agentxjs/core/image"; // image management
|
|
183
|
+
import { ... } from "@agentxjs/core/session"; // session/message management
|
|
184
|
+
import { ... } from "@agentxjs/core/driver"; // LLM driver interface
|
|
185
|
+
import { ... } from "@agentxjs/core/platform"; // platform interface
|
|
186
|
+
import { ... } from "@agentxjs/core/runtime"; // runtime orchestration
|
|
187
|
+
import { ... } from "@agentxjs/core/event"; // event bus system
|
|
188
|
+
import { ... } from "@agentxjs/core/bash"; // command execution
|
|
189
|
+
import { ... } from "@agentxjs/core/network"; // client-server protocol
|
|
190
|
+
import { ... } from "@agentxjs/core/persistence"; // repository interfaces
|
|
191
|
+
import { ... } from "@agentxjs/core/mq"; // message queue interface
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Runtime (`@agentxjs/core/runtime`)
|
|
195
|
+
|
|
196
|
+
Orchestrates agent lifecycle. Takes platform and driver as separate parameters.
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
function createAgentXRuntime(platform: AgentXPlatform, createDriver: CreateDriver): AgentXRuntime;
|
|
200
|
+
|
|
201
|
+
interface AgentXRuntime {
|
|
202
|
+
createAgent(options: CreateAgentOptions): Promise<RuntimeAgent>;
|
|
203
|
+
destroyAgent(agentId: string): Promise<void>;
|
|
204
|
+
receive(agentId: string, content: string | unknown[]): Promise<void>;
|
|
205
|
+
subscribe(agentId: string, handler: AgentEventHandler): Subscription;
|
|
206
|
+
shutdown(): Promise<void>;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Driver (`@agentxjs/core/driver`)
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
interface DriverConfig<TOptions = Record<string, unknown>> {
|
|
214
|
+
apiKey: string;
|
|
215
|
+
baseUrl?: string;
|
|
216
|
+
model?: string;
|
|
217
|
+
timeout?: number; // default: 600000 (10 min)
|
|
218
|
+
agentId: string;
|
|
219
|
+
systemPrompt?: string;
|
|
220
|
+
cwd?: string;
|
|
221
|
+
mcpServers?: Record<string, McpServerConfig>; // MCP tool servers
|
|
222
|
+
tools?: ToolDefinition[]; // inline tools
|
|
223
|
+
session?: Session; // conversation history
|
|
224
|
+
resumeSessionId?: string;
|
|
225
|
+
onSessionIdCaptured?: (sessionId: string) => void;
|
|
226
|
+
options?: TOptions; // driver-specific options
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**DriverStreamEvent** — the events your driver yields:
|
|
231
|
+
|
|
232
|
+
| Event | Data | When |
|
|
233
|
+
| ------------------ | ---------------------------------- | ------------------------ |
|
|
234
|
+
| `message_start` | `{ messageId, model }` | LLM starts responding |
|
|
235
|
+
| `text_delta` | `{ text }` | Incremental text chunk |
|
|
236
|
+
| `tool_use_start` | `{ toolCallId, toolName }` | LLM wants to call a tool |
|
|
237
|
+
| `input_json_delta` | `{ partialJson }` | Incremental tool input |
|
|
238
|
+
| `tool_use_stop` | `{ toolCallId, toolName, input }` | Tool call complete |
|
|
239
|
+
| `tool_result` | `{ toolCallId, result, isError? }` | Tool execution result |
|
|
240
|
+
| `message_stop` | `{ stopReason }` | LLM finished responding |
|
|
241
|
+
| `error` | `{ message, errorCode? }` | Error occurred |
|
|
242
|
+
|
|
243
|
+
**McpServerConfig** — two transports for connecting external tool servers:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// Local subprocess (stdio)
|
|
247
|
+
{ command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] }
|
|
248
|
+
|
|
249
|
+
// Remote server (HTTP Streamable)
|
|
250
|
+
{ type: "http", url: "https://mcp.example.com/sse" }
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Container (`@agentxjs/core/container`)
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
function createContainer(config: ContainerCreateConfig, ctx: ContainerContext): Promise<Container>;
|
|
257
|
+
function loadContainer(containerId: string, ctx: ContainerContext): Promise<Container | null>;
|
|
258
|
+
function getOrCreateContainer(containerId: string, ctx: ContainerContext): Promise<Container>;
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`ContainerContext` provides the repository: `{ containerRepository: ContainerRepository }`.
|
|
262
|
+
|
|
263
|
+
### Image (`@agentxjs/core/image`)
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
function createImage(config: ImageCreateConfig, ctx: ImageContext): Promise<Image>;
|
|
267
|
+
function loadImage(imageId: string, ctx: ImageContext): Promise<Image | null>;
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
`ImageCreateConfig`: `{ containerId, name?, description?, systemPrompt?, mcpServers? }`.
|
|
271
|
+
`ImageContext` provides repositories: `{ imageRepository, sessionRepository }`.
|
|
272
|
+
|
|
273
|
+
### Session (`@agentxjs/core/session`)
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
function createSession(config: SessionConfig): Session;
|
|
277
|
+
|
|
278
|
+
interface Session {
|
|
279
|
+
initialize(): Promise<void>;
|
|
280
|
+
addMessage(msg: Message): Promise<void>;
|
|
281
|
+
getMessages(): Message[];
|
|
282
|
+
clear(): Promise<void>;
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Event (`@agentxjs/core/event`)
|
|
287
|
+
|
|
288
|
+
Typed pub/sub event bus.
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
interface EventBus {
|
|
292
|
+
emit(event: BusEvent): void;
|
|
293
|
+
on<T extends string>(type: T, handler: BusEventHandler): Unsubscribe;
|
|
294
|
+
onAny(handler: BusEventHandler): Unsubscribe;
|
|
295
|
+
asProducer(): EventProducer; // write-only view
|
|
296
|
+
asConsumer(): EventConsumer; // read-only view
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Persistence (`@agentxjs/core/persistence`)
|
|
301
|
+
|
|
302
|
+
Repository interfaces for data storage. Each is a simple CRUD interface:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
interface ContainerRepository {
|
|
306
|
+
create(record: ContainerRecord): Promise<void>;
|
|
307
|
+
findById(containerId: string): Promise<ContainerRecord | null>;
|
|
308
|
+
findAll(): Promise<ContainerRecord[]>;
|
|
309
|
+
delete(containerId: string): Promise<void>;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ImageRepository and SessionRepository follow the same CRUD pattern
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Bash (`@agentxjs/core/bash`)
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
interface BashProvider {
|
|
319
|
+
execute(command: string, options?: BashOptions): Promise<BashResult>;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
interface BashResult {
|
|
323
|
+
stdout: string;
|
|
324
|
+
stderr: string;
|
|
325
|
+
exitCode: number;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function createBashTool(provider: BashProvider): ToolDefinition;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Configuration
|
|
332
|
+
|
|
333
|
+
This package has no runtime configuration. It provides interfaces configured through implementation packages:
|
|
334
|
+
|
|
335
|
+
| Concern | Configured via |
|
|
336
|
+
| ----------- | ------------------------------------------------------------------------------------ |
|
|
337
|
+
| Persistence | `@agentxjs/node-platform` (`dataPath`) |
|
|
338
|
+
| Driver | `@agentxjs/mono-driver` or `@agentxjs/claude-driver` (`apiKey`, `provider`, `model`) |
|
|
339
|
+
| Event Bus | Created by platform (`new EventBusImpl()`) |
|
|
340
|
+
| Bash | Created by platform (`NodeBashProvider`) |
|
|
341
|
+
|
|
342
|
+
**Dependencies**: `commonxjs`, `rxjs`, `jsonrpc-lite`
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { JsonRpc, IParsedObject } from 'jsonrpc-lite';
|
|
2
|
+
import { S as SystemEvent } from './base-m40r3Qgu.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* JSON-RPC 2.0 Protocol for AgentX Network Communication
|
|
6
|
+
*
|
|
7
|
+
* Uses jsonrpc-lite for message parsing/serialization.
|
|
8
|
+
*
|
|
9
|
+
* Message Types:
|
|
10
|
+
* - Request: Client → Server (has id, expects response)
|
|
11
|
+
* - Response: Server → Client (success or error)
|
|
12
|
+
* - Notification: Server → Client (no id, stream events)
|
|
13
|
+
*
|
|
14
|
+
* @see https://www.jsonrpc.org/specification
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* All RPC method names supported by AgentX
|
|
19
|
+
*/
|
|
20
|
+
type RpcMethod = "container.create" | "container.get" | "container.list" | "image.create" | "image.get" | "image.list" | "image.delete" | "image.run" | "image.stop" | "image.update" | "image.messages" | "agent.get" | "agent.list" | "agent.destroy" | "agent.destroyAll" | "agent.interrupt" | "message.send";
|
|
21
|
+
/**
|
|
22
|
+
* Notification method names (server push)
|
|
23
|
+
*/
|
|
24
|
+
type NotificationMethod = "stream.event" | "control.ack";
|
|
25
|
+
/**
|
|
26
|
+
* JSON-RPC Request structure
|
|
27
|
+
*/
|
|
28
|
+
interface RpcRequest<M extends RpcMethod = RpcMethod, P = unknown> {
|
|
29
|
+
jsonrpc: "2.0";
|
|
30
|
+
method: M;
|
|
31
|
+
params: P;
|
|
32
|
+
id: string | number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* JSON-RPC Success Response structure
|
|
36
|
+
*/
|
|
37
|
+
interface RpcSuccessResponse<R = unknown> {
|
|
38
|
+
jsonrpc: "2.0";
|
|
39
|
+
result: R;
|
|
40
|
+
id: string | number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* JSON-RPC Error Response structure
|
|
44
|
+
*/
|
|
45
|
+
interface RpcErrorResponse {
|
|
46
|
+
jsonrpc: "2.0";
|
|
47
|
+
error: {
|
|
48
|
+
code: number;
|
|
49
|
+
message: string;
|
|
50
|
+
data?: unknown;
|
|
51
|
+
};
|
|
52
|
+
id: string | number | null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* JSON-RPC Notification structure (no id, no response expected)
|
|
56
|
+
*/
|
|
57
|
+
interface RpcNotification<M extends NotificationMethod = NotificationMethod, P = unknown> {
|
|
58
|
+
jsonrpc: "2.0";
|
|
59
|
+
method: M;
|
|
60
|
+
params: P;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Stream event notification params
|
|
64
|
+
*/
|
|
65
|
+
interface StreamEventParams {
|
|
66
|
+
topic: string;
|
|
67
|
+
event: SystemEvent;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Control ACK notification params
|
|
71
|
+
*/
|
|
72
|
+
interface ControlAckParams {
|
|
73
|
+
msgId: string;
|
|
74
|
+
}
|
|
75
|
+
declare const RpcErrorCodes: {
|
|
76
|
+
readonly PARSE_ERROR: -32700;
|
|
77
|
+
readonly INVALID_REQUEST: -32600;
|
|
78
|
+
readonly METHOD_NOT_FOUND: -32601;
|
|
79
|
+
readonly INVALID_PARAMS: -32602;
|
|
80
|
+
readonly INTERNAL_ERROR: -32603;
|
|
81
|
+
readonly SERVER_ERROR: -32000;
|
|
82
|
+
readonly NOT_FOUND: 404;
|
|
83
|
+
readonly UNAUTHORIZED: 401;
|
|
84
|
+
readonly FORBIDDEN: 403;
|
|
85
|
+
readonly TIMEOUT: 408;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Create a JSON-RPC request
|
|
89
|
+
*/
|
|
90
|
+
declare function createRequest(id: string | number, method: RpcMethod | string, params: unknown): JsonRpc;
|
|
91
|
+
/**
|
|
92
|
+
* Create a JSON-RPC notification (no response expected)
|
|
93
|
+
*/
|
|
94
|
+
declare function createNotification(method: NotificationMethod | string, params: unknown): JsonRpc;
|
|
95
|
+
/**
|
|
96
|
+
* Create a stream event notification
|
|
97
|
+
*/
|
|
98
|
+
declare function createStreamEvent(topic: string, event: SystemEvent): JsonRpc;
|
|
99
|
+
/**
|
|
100
|
+
* Create an ACK notification
|
|
101
|
+
*/
|
|
102
|
+
declare function createAckNotification(msgId: string): JsonRpc;
|
|
103
|
+
/**
|
|
104
|
+
* Create a success response
|
|
105
|
+
*/
|
|
106
|
+
declare function createSuccessResponse(id: string | number, result: unknown): JsonRpc;
|
|
107
|
+
/**
|
|
108
|
+
* Create an error response
|
|
109
|
+
*/
|
|
110
|
+
declare function createErrorResponse(id: string | number | null, code: number, message: string, data?: unknown): JsonRpc;
|
|
111
|
+
/**
|
|
112
|
+
* Parse a JSON-RPC message string
|
|
113
|
+
*/
|
|
114
|
+
declare function parseMessage(message: string): IParsedObject | IParsedObject[];
|
|
115
|
+
/**
|
|
116
|
+
* Parse a JSON-RPC message object
|
|
117
|
+
*/
|
|
118
|
+
declare function parseMessageObject(obj: unknown): IParsedObject;
|
|
119
|
+
/**
|
|
120
|
+
* Check if parsed message is a request
|
|
121
|
+
*/
|
|
122
|
+
declare function isRequest(parsed: IParsedObject): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Check if parsed message is a notification
|
|
125
|
+
*/
|
|
126
|
+
declare function isNotification(parsed: IParsedObject): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Check if parsed message is a success response
|
|
129
|
+
*/
|
|
130
|
+
declare function isSuccessResponse(parsed: IParsedObject): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Check if parsed message is an error response
|
|
133
|
+
*/
|
|
134
|
+
declare function isErrorResponse(parsed: IParsedObject): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Check if parsed message is invalid
|
|
137
|
+
*/
|
|
138
|
+
declare function isInvalid(parsed: IParsedObject): boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Check if notification is a stream event
|
|
141
|
+
*/
|
|
142
|
+
declare function isStreamEvent(parsed: IParsedObject): parsed is IParsedObject & {
|
|
143
|
+
payload: RpcNotification<"stream.event", StreamEventParams>;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Check if notification is a control ACK
|
|
147
|
+
*/
|
|
148
|
+
declare function isControlAck(parsed: IParsedObject): parsed is IParsedObject & {
|
|
149
|
+
payload: RpcNotification<"control.ack", ControlAckParams>;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Map old event type names to new RPC method names
|
|
153
|
+
*/
|
|
154
|
+
declare const eventTypeToRpcMethod: Record<string, RpcMethod>;
|
|
155
|
+
/**
|
|
156
|
+
* Map RPC method names back to response event types
|
|
157
|
+
*/
|
|
158
|
+
declare const rpcMethodToResponseType: Record<RpcMethod, string>;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* RpcClient - JSON-RPC 2.0 Client over WebSocket
|
|
162
|
+
*
|
|
163
|
+
* Provides:
|
|
164
|
+
* - Request/Response with automatic ID matching
|
|
165
|
+
* - Notification handling (stream events)
|
|
166
|
+
* - Timeout management
|
|
167
|
+
* - Reconnection support
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* const client = new RpcClient({ url: "ws://localhost:5200" });
|
|
172
|
+
* await client.connect();
|
|
173
|
+
*
|
|
174
|
+
* // RPC call
|
|
175
|
+
* const result = await client.call("container.list", {});
|
|
176
|
+
*
|
|
177
|
+
* // Stream events
|
|
178
|
+
* client.onNotification("stream.event", (params) => {
|
|
179
|
+
* console.log("Event:", params.event);
|
|
180
|
+
* });
|
|
181
|
+
*
|
|
182
|
+
* // Subscribe to topic
|
|
183
|
+
* client.notify("subscribe", { topic: "session-123" });
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Factory function for creating WebSocket instances.
|
|
189
|
+
* Platform layer provides the implementation:
|
|
190
|
+
* - Browser: native WebSocket (default)
|
|
191
|
+
* - Node.js: ws library (via @agentxjs/node-platform)
|
|
192
|
+
*/
|
|
193
|
+
type WebSocketFactory = (url: string) => WebSocket;
|
|
194
|
+
/**
|
|
195
|
+
* RpcClient configuration
|
|
196
|
+
*/
|
|
197
|
+
interface RpcClientConfig {
|
|
198
|
+
/**
|
|
199
|
+
* WebSocket URL
|
|
200
|
+
*/
|
|
201
|
+
url: string;
|
|
202
|
+
/**
|
|
203
|
+
* Factory for creating WebSocket instances.
|
|
204
|
+
* If not provided, falls back to the global WebSocket constructor.
|
|
205
|
+
*/
|
|
206
|
+
createWebSocket?: WebSocketFactory;
|
|
207
|
+
/**
|
|
208
|
+
* Request timeout in milliseconds (default: 30000)
|
|
209
|
+
*/
|
|
210
|
+
timeout?: number;
|
|
211
|
+
/**
|
|
212
|
+
* Auto reconnect on disconnect (default: true)
|
|
213
|
+
*/
|
|
214
|
+
autoReconnect?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Reconnect delay in milliseconds (default: 3000)
|
|
217
|
+
*/
|
|
218
|
+
reconnectDelay?: number;
|
|
219
|
+
/**
|
|
220
|
+
* Headers for authentication (sent in first message after connection)
|
|
221
|
+
*/
|
|
222
|
+
headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
223
|
+
/**
|
|
224
|
+
* Debug logging
|
|
225
|
+
*/
|
|
226
|
+
debug?: boolean;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Notification handler
|
|
230
|
+
*/
|
|
231
|
+
type NotificationHandler = (method: string, params: unknown) => void;
|
|
232
|
+
/**
|
|
233
|
+
* Stream event handler
|
|
234
|
+
*/
|
|
235
|
+
type StreamEventHandler = (topic: string, event: SystemEvent) => void;
|
|
236
|
+
/**
|
|
237
|
+
* Connection state
|
|
238
|
+
*/
|
|
239
|
+
type RpcClientState = "disconnected" | "connecting" | "connected";
|
|
240
|
+
/**
|
|
241
|
+
* JSON-RPC 2.0 Client
|
|
242
|
+
*/
|
|
243
|
+
declare class RpcClient {
|
|
244
|
+
private readonly config;
|
|
245
|
+
private readonly timeout;
|
|
246
|
+
private readonly pendingRequests;
|
|
247
|
+
private readonly notificationHandlers;
|
|
248
|
+
private readonly streamEventHandlers;
|
|
249
|
+
private ws;
|
|
250
|
+
private state;
|
|
251
|
+
private requestId;
|
|
252
|
+
private reconnectTimer;
|
|
253
|
+
private disposed;
|
|
254
|
+
constructor(config: RpcClientConfig);
|
|
255
|
+
/**
|
|
256
|
+
* Current connection state
|
|
257
|
+
*/
|
|
258
|
+
get connectionState(): RpcClientState;
|
|
259
|
+
/**
|
|
260
|
+
* Whether client is connected
|
|
261
|
+
*/
|
|
262
|
+
get connected(): boolean;
|
|
263
|
+
/**
|
|
264
|
+
* Connect to server
|
|
265
|
+
*/
|
|
266
|
+
connect(): Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Disconnect from server
|
|
269
|
+
*/
|
|
270
|
+
disconnect(): void;
|
|
271
|
+
/**
|
|
272
|
+
* Dispose client and clean up resources
|
|
273
|
+
*/
|
|
274
|
+
dispose(): void;
|
|
275
|
+
private scheduleReconnect;
|
|
276
|
+
/**
|
|
277
|
+
* Call an RPC method and wait for response
|
|
278
|
+
*/
|
|
279
|
+
call<T = unknown>(method: RpcMethod, params: unknown): Promise<T>;
|
|
280
|
+
/**
|
|
281
|
+
* Send a notification (no response expected)
|
|
282
|
+
*/
|
|
283
|
+
notify(method: NotificationMethod | string, params: unknown): void;
|
|
284
|
+
/**
|
|
285
|
+
* Subscribe to a topic (convenience method)
|
|
286
|
+
*/
|
|
287
|
+
subscribe(topic: string): void;
|
|
288
|
+
/**
|
|
289
|
+
* Unsubscribe from a topic (convenience method)
|
|
290
|
+
*/
|
|
291
|
+
unsubscribe(topic: string): void;
|
|
292
|
+
/**
|
|
293
|
+
* Register handler for all notifications
|
|
294
|
+
*/
|
|
295
|
+
onNotification(handler: NotificationHandler): () => void;
|
|
296
|
+
/**
|
|
297
|
+
* Register handler for stream events
|
|
298
|
+
*/
|
|
299
|
+
onStreamEvent(handler: StreamEventHandler): () => void;
|
|
300
|
+
private handleMessage;
|
|
301
|
+
private handleParsedMessage;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export { type ControlAckParams as C, type NotificationMethod as N, type RpcMethod as R, type StreamEventParams as S, type WebSocketFactory as W, type RpcRequest as a, type RpcSuccessResponse as b, type RpcErrorResponse as c, type RpcNotification as d, RpcErrorCodes as e, createRequest as f, createNotification as g, createStreamEvent as h, createAckNotification as i, createSuccessResponse as j, createErrorResponse as k, parseMessageObject as l, isRequest as m, isNotification as n, isSuccessResponse as o, parseMessage as p, isErrorResponse as q, isInvalid as r, isStreamEvent as s, isControlAck as t, eventTypeToRpcMethod as u, rpcMethodToResponseType as v, type RpcClientConfig as w, type RpcClientState as x, RpcClient as y };
|