agentxjs 2.1.1 → 2.3.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 +137 -139
- package/dist/{chunk-ZFL27HK7.js → chunk-X44CQZPK.js} +103 -1
- package/dist/chunk-X44CQZPK.js.map +1 -0
- package/dist/index.d.ts +108 -4
- package/dist/index.js +129 -2
- package/dist/index.js.map +1 -1
- package/dist/server-BWI5JE4B.js +7 -0
- package/package.json +6 -6
- package/src/CommandHandler.ts +133 -0
- package/src/LocalClient.ts +13 -0
- package/src/RemoteClient.ts +13 -0
- package/src/index.ts +20 -3
- package/src/namespaces/llm.ts +140 -0
- package/src/types.ts +115 -0
- package/dist/chunk-ZFL27HK7.js.map +0 -1
- package/dist/server-IFVYHIJF.js +0 -7
- /package/dist/{server-IFVYHIJF.js.map → server-BWI5JE4B.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,84 +1,80 @@
|
|
|
1
1
|
# agentxjs
|
|
2
2
|
|
|
3
|
-
Client SDK for building AI agent applications. Supports local
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
`agentxjs` is the main SDK that developers use directly. It auto-detects the mode based on config: provide `apiKey` for local mode (no server needed), or `serverUrl` for remote mode (connects to an AgentX server over WebSocket).
|
|
3
|
+
Client SDK for building AI agent applications. Supports local, remote, and server modes through a unified fluent API.
|
|
8
4
|
|
|
9
5
|
## Quick Start
|
|
10
6
|
|
|
11
|
-
### When to use which mode?
|
|
12
|
-
|
|
13
|
-
| | Local Mode | Remote Mode |
|
|
14
|
-
| ------------- | ----------------------------------------------- | ------------------------------------------------------------ |
|
|
15
|
-
| **Use when** | Prototyping, CLI tools, single-user apps, tests | Multi-tenant apps, shared infrastructure, horizontal scaling |
|
|
16
|
-
| **Trade-off** | Simpler setup, no server to manage | Centralized state, multiple clients can share agents |
|
|
17
|
-
| **Data** | In-process SQLite (or `:memory:`) | Server-managed persistent storage |
|
|
18
|
-
| **Config** | `apiKey` | `serverUrl` |
|
|
19
|
-
|
|
20
|
-
**Start with Local mode.** Switch to Remote when you need multiple processes or users sharing the same agents.
|
|
21
|
-
|
|
22
7
|
### Local Mode (Embedded)
|
|
23
8
|
|
|
24
9
|
Runs agents directly in your process. No server required.
|
|
25
10
|
|
|
26
11
|
```typescript
|
|
27
12
|
import { createAgentX } from "agentxjs";
|
|
13
|
+
import { nodePlatform } from "@agentxjs/node-platform";
|
|
14
|
+
import { createMonoDriver } from "@agentxjs/mono-driver";
|
|
28
15
|
|
|
29
|
-
const
|
|
16
|
+
const createDriver = (config) => createMonoDriver({
|
|
17
|
+
...config,
|
|
30
18
|
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
31
|
-
provider: "anthropic",
|
|
19
|
+
options: { provider: "anthropic" },
|
|
32
20
|
});
|
|
33
21
|
|
|
34
|
-
|
|
22
|
+
const ax = createAgentX(nodePlatform({ createDriver }));
|
|
35
23
|
|
|
36
|
-
|
|
24
|
+
await ax.container.create("my-app");
|
|
25
|
+
|
|
26
|
+
const { record: image } = await ax.image.create({
|
|
37
27
|
containerId: "my-app",
|
|
38
28
|
systemPrompt: "You are a helpful assistant.",
|
|
39
29
|
});
|
|
40
30
|
|
|
41
|
-
const { agentId } = await
|
|
31
|
+
const { agentId } = await ax.agent.create({ imageId: image.imageId });
|
|
42
32
|
|
|
43
|
-
|
|
44
|
-
await
|
|
33
|
+
ax.on("text_delta", (e) => process.stdout.write(e.data.text));
|
|
34
|
+
await ax.session.send(agentId, "Hello!");
|
|
45
35
|
```
|
|
46
36
|
|
|
47
|
-
### Remote Mode (WebSocket)
|
|
37
|
+
### Remote Mode (WebSocket Client)
|
|
48
38
|
|
|
49
39
|
Connects to a running AgentX server. Same API surface.
|
|
50
40
|
|
|
51
41
|
```typescript
|
|
52
42
|
import { createAgentX } from "agentxjs";
|
|
53
43
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
});
|
|
44
|
+
const ax = createAgentX();
|
|
45
|
+
const client = await ax.connect("ws://localhost:5200");
|
|
57
46
|
|
|
58
|
-
|
|
59
|
-
await
|
|
60
|
-
const { record: image } = await agentx.images.create({
|
|
47
|
+
await client.container.create("my-app");
|
|
48
|
+
const { record: image } = await client.image.create({
|
|
61
49
|
containerId: "my-app",
|
|
62
50
|
systemPrompt: "You are a helpful assistant.",
|
|
63
51
|
});
|
|
64
|
-
const { agentId } = await
|
|
52
|
+
const { agentId } = await client.agent.create({ imageId: image.imageId });
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
await
|
|
54
|
+
client.on("text_delta", (e) => process.stdout.write(e.data.text));
|
|
55
|
+
await client.session.send(agentId, "Hello!");
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Server Mode
|
|
59
|
+
|
|
60
|
+
Start an AgentX WebSocket server for remote clients.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { createAgentX } from "agentxjs";
|
|
64
|
+
import { nodePlatform } from "@agentxjs/node-platform";
|
|
65
|
+
|
|
66
|
+
const ax = createAgentX(nodePlatform({ createDriver }));
|
|
67
|
+
const server = await ax.serve({ port: 5200 });
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
## API Reference
|
|
71
71
|
|
|
72
|
-
### `createAgentX(config
|
|
72
|
+
### `createAgentX(config?): AgentXBuilder`
|
|
73
73
|
|
|
74
|
-
Creates an AgentX
|
|
74
|
+
Creates an AgentX builder. Synchronous — returns immediately.
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
| `serverUrl` | Remote | Connects via WebSocket |
|
|
79
|
-
| `apiKey` | Local | Starts embedded runtime with MonoDriver |
|
|
80
|
-
| `createDriver` | Local | Uses custom driver factory |
|
|
81
|
-
| `customPlatform` | Local | Uses custom platform |
|
|
76
|
+
- **With config** (PlatformConfig): Local mode + `connect()` + `serve()`
|
|
77
|
+
- **Without config**: Only `connect()` available
|
|
82
78
|
|
|
83
79
|
### AgentX Interface
|
|
84
80
|
|
|
@@ -88,53 +84,133 @@ interface AgentX {
|
|
|
88
84
|
readonly events: EventBus;
|
|
89
85
|
|
|
90
86
|
// Namespaced operations
|
|
91
|
-
readonly
|
|
92
|
-
readonly
|
|
93
|
-
readonly
|
|
94
|
-
readonly
|
|
95
|
-
readonly
|
|
87
|
+
readonly container: ContainerNamespace;
|
|
88
|
+
readonly image: ImageNamespace;
|
|
89
|
+
readonly agent: AgentNamespace;
|
|
90
|
+
readonly session: SessionNamespace;
|
|
91
|
+
readonly presentation: PresentationNamespace;
|
|
92
|
+
readonly llm: LLMNamespace;
|
|
93
|
+
|
|
94
|
+
// Universal RPC
|
|
95
|
+
rpc<T = unknown>(method: string, params?: unknown): Promise<T>;
|
|
96
96
|
|
|
97
97
|
// Event subscription
|
|
98
98
|
on<T extends string>(type: T, handler: BusEventHandler): Unsubscribe;
|
|
99
99
|
onAny(handler: BusEventHandler): Unsubscribe;
|
|
100
100
|
subscribe(sessionId: string): void;
|
|
101
101
|
|
|
102
|
+
// Error handling
|
|
103
|
+
onError(handler: (error: AgentXError) => void): Unsubscribe;
|
|
104
|
+
|
|
102
105
|
// Lifecycle
|
|
103
106
|
disconnect(): Promise<void>;
|
|
104
107
|
dispose(): Promise<void>;
|
|
105
108
|
}
|
|
109
|
+
|
|
110
|
+
interface AgentXBuilder extends AgentX {
|
|
111
|
+
connect(serverUrl: string, options?: ConnectOptions): Promise<AgentX>;
|
|
112
|
+
serve(config?: ServeConfig): Promise<AgentXServer>;
|
|
113
|
+
}
|
|
106
114
|
```
|
|
107
115
|
|
|
108
116
|
### Namespace Operations
|
|
109
117
|
|
|
110
|
-
**
|
|
118
|
+
**container**:
|
|
111
119
|
|
|
112
120
|
- `create(containerId: string): Promise<ContainerCreateResponse>`
|
|
113
121
|
- `get(containerId: string): Promise<ContainerGetResponse>`
|
|
114
122
|
- `list(): Promise<ContainerListResponse>`
|
|
115
123
|
|
|
116
|
-
**
|
|
124
|
+
**image**:
|
|
117
125
|
|
|
118
|
-
- `create(params: { containerId, name?, description?, systemPrompt?, mcpServers? }): Promise<ImageCreateResponse>`
|
|
126
|
+
- `create(params: { containerId, name?, description?, systemPrompt?, mcpServers?, customData? }): Promise<ImageCreateResponse>`
|
|
119
127
|
- `get(imageId: string): Promise<ImageGetResponse>`
|
|
120
128
|
- `list(containerId?: string): Promise<ImageListResponse>`
|
|
129
|
+
- `update(imageId: string, updates: { name?, description?, customData? }): Promise<ImageUpdateResponse>`
|
|
121
130
|
- `delete(imageId: string): Promise<BaseResponse>`
|
|
131
|
+
- `getMessages(imageId: string): Promise<Message[]>`
|
|
122
132
|
|
|
123
|
-
**
|
|
133
|
+
**agent**:
|
|
124
134
|
|
|
125
135
|
- `create(params: { imageId, agentId? }): Promise<AgentCreateResponse>`
|
|
126
136
|
- `get(agentId: string): Promise<AgentGetResponse>`
|
|
127
137
|
- `list(containerId?: string): Promise<AgentListResponse>`
|
|
128
138
|
- `destroy(agentId: string): Promise<BaseResponse>`
|
|
129
139
|
|
|
130
|
-
**
|
|
140
|
+
**session**:
|
|
131
141
|
|
|
132
142
|
- `send(agentId: string, content: string | unknown[]): Promise<MessageSendResponse>`
|
|
133
143
|
- `interrupt(agentId: string): Promise<BaseResponse>`
|
|
144
|
+
- `getMessages(agentId: string): Promise<Message[]>`
|
|
145
|
+
|
|
146
|
+
**presentation**:
|
|
147
|
+
|
|
148
|
+
- `create(agentId: string, options?: PresentationOptions): Promise<Presentation>`
|
|
149
|
+
|
|
150
|
+
**llm**:
|
|
151
|
+
|
|
152
|
+
- `create(params: { containerId, name, vendor, protocol, apiKey, baseUrl?, model? }): Promise<LLMProviderCreateResponse>`
|
|
153
|
+
- `get(id: string): Promise<LLMProviderGetResponse>`
|
|
154
|
+
- `list(containerId: string): Promise<LLMProviderListResponse>`
|
|
155
|
+
- `update(id: string, updates: { name?, apiKey?, baseUrl?, model? }): Promise<LLMProviderUpdateResponse>`
|
|
156
|
+
- `delete(id: string): Promise<BaseResponse>`
|
|
157
|
+
- `setDefault(id: string): Promise<BaseResponse>`
|
|
158
|
+
- `getDefault(containerId: string): Promise<LLMProviderDefaultResponse>`
|
|
159
|
+
|
|
160
|
+
Each LLM provider has a **vendor** (who provides the service — `anthropic`, `openai`, `deepseek`, `ollama`) and a **protocol** (API format — `anthropic` or `openai`). These are separate dimensions: e.g., Deepseek uses vendor `"deepseek"` with protocol `"openai"`.
|
|
161
|
+
|
|
162
|
+
When creating an agent, the runtime validates that the container's default LLM provider protocol is supported by the driver.
|
|
163
|
+
|
|
164
|
+
### Universal RPC
|
|
165
|
+
|
|
166
|
+
Transport-agnostic JSON-RPC entry point. Works in all modes — local dispatches to CommandHandler, remote forwards via WebSocket.
|
|
134
167
|
|
|
135
|
-
|
|
168
|
+
```typescript
|
|
169
|
+
// Equivalent to ax.container.create("default")
|
|
170
|
+
await ax.rpc("container.create", { containerId: "default" });
|
|
171
|
+
|
|
172
|
+
// Equivalent to ax.image.list()
|
|
173
|
+
const { records } = await ax.rpc<{ records: ImageRecord[] }>("image.list");
|
|
174
|
+
|
|
175
|
+
// Useful for custom transport (e.g. Cloudflare Workers/DO)
|
|
176
|
+
const response = await ax.rpc(request.method, request.params);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Error Handling
|
|
180
|
+
|
|
181
|
+
Top-level error handler — receives structured `AgentXError` from all layers (driver, persistence, connection, runtime). Independent of stream events and Presentation API.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { AgentXError } from "agentxjs";
|
|
136
185
|
|
|
137
|
-
|
|
186
|
+
ax.onError((error) => {
|
|
187
|
+
console.error(`[${error.category}] ${error.code}: ${error.message}`);
|
|
188
|
+
|
|
189
|
+
if (error.code === "CIRCUIT_OPEN") {
|
|
190
|
+
// Too many consecutive LLM failures — stop sending requests
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (error.code === "PERSISTENCE_FAILED") {
|
|
194
|
+
// Message failed to save — conversation continues but data may be lost
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!error.recoverable) {
|
|
198
|
+
// Fatal error — consider restarting the agent
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**AgentXError properties:**
|
|
204
|
+
|
|
205
|
+
| Property | Type | Description |
|
|
206
|
+
| ------------- | -------- | ------------------------------------ |
|
|
207
|
+
| `code` | string | Error code (e.g. `PERSISTENCE_FAILED`) |
|
|
208
|
+
| `category` | string | `"driver"` \| `"persistence"` \| `"connection"` \| `"runtime"` |
|
|
209
|
+
| `recoverable` | boolean | Whether the caller should retry |
|
|
210
|
+
| `context` | object | `{ agentId?, sessionId?, imageId? }` |
|
|
211
|
+
| `cause` | Error? | Original error |
|
|
212
|
+
|
|
213
|
+
**Built-in circuit breaker:** After 5 consecutive driver failures, the circuit opens and rejects new requests. After 30s cooldown, one probe request is allowed through. Success closes the circuit.
|
|
138
214
|
|
|
139
215
|
### Stream Events
|
|
140
216
|
|
|
@@ -150,36 +226,24 @@ interface AgentX {
|
|
|
150
226
|
|
|
151
227
|
### Presentation API
|
|
152
228
|
|
|
153
|
-
High-level UI state management. Aggregates raw stream events into
|
|
229
|
+
High-level UI state management. Aggregates raw stream events into structured conversation state.
|
|
154
230
|
|
|
155
231
|
```typescript
|
|
156
|
-
const presentation = await
|
|
157
|
-
onUpdate: (state
|
|
232
|
+
const presentation = await ax.presentation.create(agentId, {
|
|
233
|
+
onUpdate: (state) => {
|
|
234
|
+
// state.conversations — completed messages (includes history)
|
|
235
|
+
// state.streaming — current streaming response (or null)
|
|
236
|
+
// state.status — "idle" | "thinking" | "responding" | "executing"
|
|
237
|
+
renderUI(state);
|
|
238
|
+
},
|
|
158
239
|
onError: (error) => console.error(error),
|
|
159
240
|
});
|
|
160
|
-
// For existing sessions, getState() already contains conversation history
|
|
161
241
|
|
|
162
242
|
await presentation.send("What is the weather?");
|
|
163
243
|
const state = presentation.getState();
|
|
164
|
-
// state.conversations -- completed conversations (includes history)
|
|
165
|
-
// state.streaming -- current streaming response (or null)
|
|
166
|
-
// state.status -- "idle" | "thinking" | "responding" | "executing"
|
|
167
|
-
|
|
168
244
|
presentation.dispose();
|
|
169
245
|
```
|
|
170
246
|
|
|
171
|
-
**PresentationState**:
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
interface PresentationState {
|
|
175
|
-
conversations: Conversation[]; // UserConversation | AssistantConversation | ErrorConversation
|
|
176
|
-
streaming: AssistantConversation | null;
|
|
177
|
-
status: "idle" | "thinking" | "responding" | "executing";
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
**Block types**: `TextBlock { type: "text", content }`, `ToolBlock { type: "tool", toolName, status, ... }`, `ImageBlock { type: "image", url }`
|
|
182
|
-
|
|
183
247
|
For custom state management, use the exported reducer:
|
|
184
248
|
|
|
185
249
|
```typescript
|
|
@@ -189,69 +253,3 @@ let state = createInitialState();
|
|
|
189
253
|
state = addUserConversation(state, "Hello");
|
|
190
254
|
state = presentationReducer(state, event); // pure function
|
|
191
255
|
```
|
|
192
|
-
|
|
193
|
-
## Configuration
|
|
194
|
-
|
|
195
|
-
### AgentXConfig
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
interface AgentXConfig {
|
|
199
|
-
// --- Local Mode ---
|
|
200
|
-
apiKey?: string; // LLM provider API key
|
|
201
|
-
provider?: LLMProvider; // default: "anthropic"
|
|
202
|
-
model?: string; // e.g. "claude-sonnet-4-20250514"
|
|
203
|
-
baseUrl?: string; // custom API endpoint
|
|
204
|
-
dataPath?: string; // default: ":memory:"
|
|
205
|
-
createDriver?: CreateDriver; // custom driver factory (advanced)
|
|
206
|
-
customPlatform?: AgentXPlatform; // custom platform (advanced)
|
|
207
|
-
|
|
208
|
-
// --- Remote Mode ---
|
|
209
|
-
serverUrl?: string; // WebSocket URL
|
|
210
|
-
headers?: MaybeAsync<Record<string, string>>; // auth headers
|
|
211
|
-
context?: MaybeAsync<Record<string, unknown>>; // business context
|
|
212
|
-
|
|
213
|
-
// --- Common ---
|
|
214
|
-
timeout?: number; // default: 30000 ms
|
|
215
|
-
debug?: boolean;
|
|
216
|
-
autoReconnect?: boolean; // default: true (remote only)
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
| Field | Type | Default | Description |
|
|
221
|
-
| --------------- | ------------------------------------- | ---------------- | ----------------------------------------------------------------------------------- |
|
|
222
|
-
| `apiKey` | `string` | -- | LLM provider API key (triggers local mode) |
|
|
223
|
-
| `provider` | `LLMProvider` | `"anthropic"` | `"anthropic"` \| `"openai"` \| `"google"` \| `"xai"` \| `"deepseek"` \| `"mistral"` |
|
|
224
|
-
| `model` | `string` | provider default | Model identifier |
|
|
225
|
-
| `baseUrl` | `string` | -- | Custom API endpoint |
|
|
226
|
-
| `dataPath` | `string` | `":memory:"` | SQLite path or `:memory:` |
|
|
227
|
-
| `serverUrl` | `string` | -- | WebSocket URL (triggers remote mode) |
|
|
228
|
-
| `headers` | `MaybeAsync<Record<string, string>>` | -- | Static, dynamic, or async auth headers |
|
|
229
|
-
| `context` | `MaybeAsync<Record<string, unknown>>` | -- | Business context (userId, tenantId, etc.) |
|
|
230
|
-
| `timeout` | `number` | `30000` | Request timeout in ms |
|
|
231
|
-
| `debug` | `boolean` | `false` | Enable debug logging |
|
|
232
|
-
| `autoReconnect` | `boolean` | `true` | Auto reconnect on connection loss (remote only) |
|
|
233
|
-
|
|
234
|
-
### MaybeAsync
|
|
235
|
-
|
|
236
|
-
`headers` and `context` accept static values, functions, or async functions:
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
type MaybeAsync<T> = T | (() => T) | (() => Promise<T>);
|
|
240
|
-
|
|
241
|
-
// Static
|
|
242
|
-
headers: {
|
|
243
|
-
Authorization: "Bearer sk-xxx";
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Dynamic
|
|
247
|
-
headers: () => ({ Authorization: `Bearer ${getToken()}` });
|
|
248
|
-
|
|
249
|
-
// Async
|
|
250
|
-
headers: async () => ({ Authorization: `Bearer ${await refreshToken()}` });
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Environment Variables
|
|
254
|
-
|
|
255
|
-
| Variable | Description |
|
|
256
|
-
| ------------------- | -------------------------------------- |
|
|
257
|
-
| `ANTHROPIC_API_KEY` | Default API key for Anthropic provider |
|
|
@@ -71,6 +71,19 @@ var CommandHandler = class {
|
|
|
71
71
|
// Message
|
|
72
72
|
case "message.send":
|
|
73
73
|
return await this.handleMessageSend(params);
|
|
74
|
+
// LLM Provider
|
|
75
|
+
case "llm.create":
|
|
76
|
+
return await this.handleLLMCreate(params);
|
|
77
|
+
case "llm.get":
|
|
78
|
+
return await this.handleLLMGet(params);
|
|
79
|
+
case "llm.list":
|
|
80
|
+
return await this.handleLLMList(params);
|
|
81
|
+
case "llm.update":
|
|
82
|
+
return await this.handleLLMUpdate(params);
|
|
83
|
+
case "llm.delete":
|
|
84
|
+
return await this.handleLLMDelete(params);
|
|
85
|
+
case "llm.default":
|
|
86
|
+
return await this.handleLLMDefault(params);
|
|
74
87
|
default:
|
|
75
88
|
return err(-32601, `Method not found: ${method}`);
|
|
76
89
|
}
|
|
@@ -288,6 +301,95 @@ var CommandHandler = class {
|
|
|
288
301
|
await this.runtime.receive(targetAgentId, content);
|
|
289
302
|
return ok({ agentId: targetAgentId, imageId });
|
|
290
303
|
}
|
|
304
|
+
// ==================== LLM Provider Commands ====================
|
|
305
|
+
async handleLLMCreate(params) {
|
|
306
|
+
const { containerId, name, vendor, protocol, apiKey, baseUrl, model } = params;
|
|
307
|
+
const repo = this.runtime.platform.llmProviderRepository;
|
|
308
|
+
if (!repo) {
|
|
309
|
+
return err(-32e3, "LLM provider repository not available");
|
|
310
|
+
}
|
|
311
|
+
const { generateId } = await import("@deepracticex/id");
|
|
312
|
+
const now = Date.now();
|
|
313
|
+
const record = {
|
|
314
|
+
id: generateId("llm"),
|
|
315
|
+
containerId,
|
|
316
|
+
name,
|
|
317
|
+
vendor,
|
|
318
|
+
protocol,
|
|
319
|
+
apiKey,
|
|
320
|
+
baseUrl,
|
|
321
|
+
model,
|
|
322
|
+
isDefault: false,
|
|
323
|
+
createdAt: now,
|
|
324
|
+
updatedAt: now
|
|
325
|
+
};
|
|
326
|
+
await repo.saveLLMProvider(record);
|
|
327
|
+
return ok({ record });
|
|
328
|
+
}
|
|
329
|
+
async handleLLMGet(params) {
|
|
330
|
+
const { id } = params;
|
|
331
|
+
const repo = this.runtime.platform.llmProviderRepository;
|
|
332
|
+
if (!repo) {
|
|
333
|
+
return err(-32e3, "LLM provider repository not available");
|
|
334
|
+
}
|
|
335
|
+
const record = await repo.findLLMProviderById(id);
|
|
336
|
+
return ok({ record });
|
|
337
|
+
}
|
|
338
|
+
async handleLLMList(params) {
|
|
339
|
+
const { containerId } = params;
|
|
340
|
+
const repo = this.runtime.platform.llmProviderRepository;
|
|
341
|
+
if (!repo) {
|
|
342
|
+
return err(-32e3, "LLM provider repository not available");
|
|
343
|
+
}
|
|
344
|
+
const records = await repo.findLLMProvidersByContainerId(containerId);
|
|
345
|
+
return ok({ records });
|
|
346
|
+
}
|
|
347
|
+
async handleLLMUpdate(params) {
|
|
348
|
+
const { id, updates } = params;
|
|
349
|
+
const repo = this.runtime.platform.llmProviderRepository;
|
|
350
|
+
if (!repo) {
|
|
351
|
+
return err(-32e3, "LLM provider repository not available");
|
|
352
|
+
}
|
|
353
|
+
const existing = await repo.findLLMProviderById(id);
|
|
354
|
+
if (!existing) {
|
|
355
|
+
return err(404, `LLM provider not found: ${id}`);
|
|
356
|
+
}
|
|
357
|
+
const updated = {
|
|
358
|
+
...existing,
|
|
359
|
+
...updates,
|
|
360
|
+
id: existing.id,
|
|
361
|
+
containerId: existing.containerId,
|
|
362
|
+
createdAt: existing.createdAt,
|
|
363
|
+
updatedAt: Date.now()
|
|
364
|
+
};
|
|
365
|
+
await repo.saveLLMProvider(updated);
|
|
366
|
+
return ok({ record: updated });
|
|
367
|
+
}
|
|
368
|
+
async handleLLMDelete(params) {
|
|
369
|
+
const { id } = params;
|
|
370
|
+
const repo = this.runtime.platform.llmProviderRepository;
|
|
371
|
+
if (!repo) {
|
|
372
|
+
return err(-32e3, "LLM provider repository not available");
|
|
373
|
+
}
|
|
374
|
+
await repo.deleteLLMProvider(id);
|
|
375
|
+
return ok({ id });
|
|
376
|
+
}
|
|
377
|
+
async handleLLMDefault(params) {
|
|
378
|
+
const { id, containerId } = params;
|
|
379
|
+
const repo = this.runtime.platform.llmProviderRepository;
|
|
380
|
+
if (!repo) {
|
|
381
|
+
return err(-32e3, "LLM provider repository not available");
|
|
382
|
+
}
|
|
383
|
+
if (id) {
|
|
384
|
+
await repo.setDefaultLLMProvider(id);
|
|
385
|
+
return ok({ id });
|
|
386
|
+
}
|
|
387
|
+
if (containerId) {
|
|
388
|
+
const record = await repo.findDefaultLLMProvider(containerId);
|
|
389
|
+
return ok({ record });
|
|
390
|
+
}
|
|
391
|
+
return err(-32602, "Either id or containerId is required");
|
|
392
|
+
}
|
|
291
393
|
// ==================== Lifecycle ====================
|
|
292
394
|
dispose() {
|
|
293
395
|
logger.debug("CommandHandler disposed");
|
|
@@ -464,4 +566,4 @@ export {
|
|
|
464
566
|
CommandHandler,
|
|
465
567
|
createServer
|
|
466
568
|
};
|
|
467
|
-
//# sourceMappingURL=chunk-
|
|
569
|
+
//# sourceMappingURL=chunk-X44CQZPK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/CommandHandler.ts"],"sourcesContent":["/**\n * AgentX Server Implementation (JSON-RPC 2.0)\n *\n * Creates a WebSocket server that:\n * 1. Accepts client connections\n * 2. Handles JSON-RPC requests directly via CommandHandler\n * 3. Broadcasts stream events as JSON-RPC notifications\n *\n * Message Types:\n * - RPC Request (has id): Client → Server → Client (direct response)\n * - RPC Notification (no id): Server → Client (stream events)\n */\n\nimport type { CreateDriver } from \"@agentxjs/core/driver\";\nimport type { BusEvent, SystemEvent } from \"@agentxjs/core/event\";\nimport type { ChannelConnection } from \"@agentxjs/core/network\";\nimport {\n createErrorResponse,\n createStreamEvent,\n createSuccessResponse,\n isNotification,\n isRequest,\n parseMessage,\n RpcErrorCodes,\n type RpcMethod,\n} from \"@agentxjs/core/network\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { createAgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"@deepracticex/logger\";\nimport { CommandHandler } from \"./CommandHandler\";\nimport type { AgentXServer } from \"./types\";\n\nconst logger = createLogger(\"server/Server\");\n\n/**\n * Connection state\n */\ninterface ConnectionState {\n connection: ChannelConnection;\n subscribedTopics: Set<string>;\n}\n\n/**\n * Server configuration (supports both immediate and deferred platforms)\n */\nexport interface ServerConfig {\n /**\n * AgentX Platform — must provide `channelServer` for accepting WebSocket connections.\n */\n platform: AgentXPlatform;\n\n /**\n * LLM Driver factory function - creates Driver per Agent\n */\n createDriver: CreateDriver;\n\n /**\n * Port to listen on (standalone mode)\n */\n port?: number;\n\n /**\n * Host to bind to (default: \"0.0.0.0\")\n */\n host?: string;\n\n /**\n * Existing HTTP server to attach to (attached mode)\n */\n server?: import(\"@agentxjs/core/network\").MinimalHTTPServer;\n\n /**\n * WebSocket path when attached (default: \"/ws\")\n */\n wsPath?: string;\n\n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Create an AgentX server\n */\nexport async function createServer(config: ServerConfig): Promise<AgentXServer> {\n const { wsPath = \"/ws\" } = config;\n const platform = config.platform;\n\n // Create runtime from platform + driver\n const runtime = createAgentXRuntime(platform, config.createDriver);\n\n // Get channel server from platform\n const wsServer = platform.channelServer;\n if (!wsServer) {\n throw new Error(\"Platform must provide channelServer for server mode\");\n }\n\n // Create command handler (no longer needs eventBus)\n const commandHandler = new CommandHandler(runtime);\n\n // Track connections\n const connections = new Map<string, ConnectionState>();\n\n /**\n * Subscribe connection to a topic\n */\n function subscribeToTopic(connectionId: string, topic: string): void {\n const state = connections.get(connectionId);\n if (!state || state.subscribedTopics.has(topic)) return;\n\n state.subscribedTopics.add(topic);\n logger.debug(\"Connection subscribed to topic\", { connectionId, topic });\n }\n\n /**\n * Check if event should be sent to connection based on subscriptions\n */\n function shouldSendToConnection(state: ConnectionState, event: BusEvent): boolean {\n // Skip internal driver events\n if (event.source === \"driver\" && event.intent !== \"notification\") {\n return false;\n }\n\n // Skip command events (they are handled via RPC, not broadcast)\n if (event.source === \"command\") {\n return false;\n }\n\n // Check if subscribed to event's session\n const eventWithContext = event as BusEvent & { context?: { sessionId?: string } };\n const sessionId = eventWithContext.context?.sessionId;\n if (sessionId && state.subscribedTopics.has(sessionId)) {\n return true;\n }\n\n // Send to global subscribers\n return state.subscribedTopics.has(\"global\");\n }\n\n /**\n * Send JSON-RPC response to a specific connection\n */\n function sendResponse(connection: ChannelConnection, id: string | number, result: unknown): void {\n const response = createSuccessResponse(id, result);\n connection.send(JSON.stringify(response));\n }\n\n /**\n * Send JSON-RPC error to a specific connection\n */\n function sendError(\n connection: ChannelConnection,\n id: string | number | null,\n code: number,\n message: string\n ): void {\n const response = createErrorResponse(id, code, message);\n connection.send(JSON.stringify(response));\n }\n\n // Handle new connections\n wsServer.onConnection((connection) => {\n const state: ConnectionState = {\n connection,\n subscribedTopics: new Set([\"global\"]),\n };\n connections.set(connection.id, state);\n\n logger.info(\"Client connected\", {\n connectionId: connection.id,\n totalConnections: connections.size,\n });\n\n // Handle messages from client\n connection.onMessage(async (message) => {\n try {\n const parsed = parseMessage(message);\n\n // Handle single message (not batch)\n if (!Array.isArray(parsed)) {\n await handleParsedMessage(connection, state, parsed);\n } else {\n // Handle batch (not common, but supported by JSON-RPC 2.0)\n for (const item of parsed) {\n await handleParsedMessage(connection, state, item);\n }\n }\n } catch (err) {\n logger.error(\"Failed to parse message\", { error: (err as Error).message });\n sendError(connection, null, RpcErrorCodes.PARSE_ERROR, \"Parse error\");\n }\n });\n\n // Cleanup on disconnect\n connection.onClose(() => {\n connections.delete(connection.id);\n logger.info(\"Client disconnected\", {\n connectionId: connection.id,\n totalConnections: connections.size,\n });\n });\n });\n\n /**\n * Handle a parsed JSON-RPC message\n */\n async function handleParsedMessage(\n connection: ChannelConnection,\n state: ConnectionState,\n parsed: import(\"jsonrpc-lite\").IParsedObject\n ): Promise<void> {\n if (isRequest(parsed)) {\n // JSON-RPC Request - handle and respond directly\n const payload = parsed.payload as {\n id: string | number;\n method: string;\n params: unknown;\n };\n const { id, method, params } = payload;\n\n logger.debug(\"Received RPC request\", { id, method });\n\n // Call command handler\n const result = await commandHandler.handle(method as RpcMethod, params);\n\n if (result.success) {\n sendResponse(connection, id, result.data);\n } else {\n sendError(connection, id, result.code, result.message);\n }\n } else if (isNotification(parsed)) {\n // JSON-RPC Notification - control messages\n const payload = parsed.payload as {\n method: string;\n params: unknown;\n };\n const { method, params } = payload;\n\n logger.debug(\"Received notification\", { method });\n\n if (method === \"subscribe\") {\n const { topic } = params as { topic: string };\n subscribeToTopic(connection.id, topic);\n } else if (method === \"unsubscribe\") {\n const { topic } = params as { topic: string };\n state.subscribedTopics.delete(topic);\n logger.debug(\"Connection unsubscribed from topic\", { connectionId: connection.id, topic });\n } else if (method === \"control.ack\") {\n // ACK for reliable delivery - handled by network layer\n logger.debug(\"Received ACK notification\");\n }\n } else {\n // Invalid message\n logger.warn(\"Received invalid JSON-RPC message\");\n }\n }\n\n // Route internal events to connected clients as JSON-RPC notifications\n platform.eventBus.onAny((event) => {\n // Only broadcast broadcastable events\n if (!shouldBroadcastEvent(event)) {\n return;\n }\n\n // Get topic from event context\n const eventWithContext = event as BusEvent & { context?: { sessionId?: string } };\n const topic = eventWithContext.context?.sessionId || \"global\";\n\n // Wrap as JSON-RPC notification\n const notification = createStreamEvent(topic, event as SystemEvent);\n const message = JSON.stringify(notification);\n\n for (const [connectionId, state] of connections) {\n if (shouldSendToConnection(state, event)) {\n state.connection.sendReliable(message, {\n timeout: 10000,\n onTimeout: () => {\n logger.warn(\"Event ACK timeout\", {\n connectionId,\n eventType: event.type,\n });\n },\n });\n }\n }\n });\n\n /**\n * Check if event should be broadcast\n */\n function shouldBroadcastEvent(event: BusEvent): boolean {\n // Skip internal driver events\n if (event.source === \"driver\" && event.intent !== \"notification\") {\n return false;\n }\n\n // Skip command events (handled via RPC)\n if (event.source === \"command\") {\n return false;\n }\n\n // Check broadcastable flag\n const systemEvent = event as SystemEvent;\n if (systemEvent.broadcastable === false) {\n return false;\n }\n\n return true;\n }\n\n // Attach to existing server if provided\n if (config.server) {\n wsServer.attach(config.server, wsPath);\n logger.info(\"WebSocket attached to existing server\", { path: wsPath });\n }\n\n return {\n async listen(port?: number, host?: string) {\n if (config.server) {\n throw new Error(\n \"Cannot listen when attached to existing server. The server should call listen() instead.\"\n );\n }\n\n const listenPort = port ?? config.port ?? 5200;\n const listenHost = host ?? config.host ?? \"0.0.0.0\";\n\n await wsServer.listen(listenPort, listenHost);\n logger.info(\"Server listening\", { port: listenPort, host: listenHost });\n },\n\n async close() {\n await wsServer.close();\n logger.info(\"Server closed\");\n },\n\n async dispose() {\n // Cleanup in order\n await wsServer.dispose();\n commandHandler.dispose();\n await runtime.shutdown();\n logger.info(\"Server disposed\");\n },\n };\n}\n","/**\n * CommandHandler - Handles JSON-RPC requests directly\n *\n * No longer uses EventBus for request/response. Instead:\n * - Receives RPC requests directly\n * - Returns RPC responses directly\n * - EventBus is only used for stream events (notifications)\n */\n\nimport type { UserContentPart } from \"@agentxjs/core/agent\";\nimport type { RpcMethod } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"@deepracticex/logger\";\n\nconst logger = createLogger(\"server/CommandHandler\");\n\n/**\n * RPC Result type\n */\nexport interface RpcResult<T = unknown> {\n success: true;\n data: T;\n}\n\nexport interface RpcError {\n success: false;\n code: number;\n message: string;\n}\n\nexport type RpcResponse<T = unknown> = RpcResult<T> | RpcError;\n\n/**\n * Helper to create success result\n */\nfunction ok<T>(data: T): RpcResult<T> {\n return { success: true, data };\n}\n\n/**\n * Helper to create error result\n */\nfunction err(code: number, message: string): RpcError {\n return { success: false, code, message };\n}\n\n/**\n * CommandHandler - Processes RPC requests directly\n */\nexport class CommandHandler {\n private readonly runtime: AgentXRuntime;\n\n constructor(runtime: AgentXRuntime) {\n this.runtime = runtime;\n logger.debug(\"CommandHandler created\");\n }\n\n /**\n * Handle an RPC request and return response\n */\n async handle(method: RpcMethod, params: unknown): Promise<RpcResponse> {\n logger.debug(\"Handling RPC request\", { method });\n\n try {\n switch (method) {\n // Container\n case \"container.create\":\n return await this.handleContainerCreate(params);\n case \"container.get\":\n return await this.handleContainerGet(params);\n case \"container.list\":\n return await this.handleContainerList(params);\n\n // Image\n case \"image.create\":\n return await this.handleImageCreate(params);\n case \"image.get\":\n return await this.handleImageGet(params);\n case \"image.list\":\n return await this.handleImageList(params);\n case \"image.delete\":\n return await this.handleImageDelete(params);\n case \"image.run\":\n return await this.handleImageRun(params);\n case \"image.stop\":\n return await this.handleImageStop(params);\n case \"image.update\":\n return await this.handleImageUpdate(params);\n case \"image.messages\":\n return await this.handleImageMessages(params);\n\n // Agent\n case \"agent.get\":\n return await this.handleAgentGet(params);\n case \"agent.list\":\n return await this.handleAgentList(params);\n case \"agent.destroy\":\n return await this.handleAgentDestroy(params);\n case \"agent.destroyAll\":\n return await this.handleAgentDestroyAll(params);\n case \"agent.interrupt\":\n return await this.handleAgentInterrupt(params);\n\n // Message\n case \"message.send\":\n return await this.handleMessageSend(params);\n\n // LLM Provider\n case \"llm.create\":\n return await this.handleLLMCreate(params);\n case \"llm.get\":\n return await this.handleLLMGet(params);\n case \"llm.list\":\n return await this.handleLLMList(params);\n case \"llm.update\":\n return await this.handleLLMUpdate(params);\n case \"llm.delete\":\n return await this.handleLLMDelete(params);\n case \"llm.default\":\n return await this.handleLLMDefault(params);\n\n default:\n return err(-32601, `Method not found: ${method}`);\n }\n } catch (error) {\n logger.error(\"RPC handler error\", { method, error });\n return err(-32000, error instanceof Error ? error.message : String(error));\n }\n }\n\n // ==================== Container Commands ====================\n\n private async handleContainerCreate(params: unknown): Promise<RpcResponse> {\n const { containerId } = params as { containerId: string };\n const { getOrCreateContainer } = await import(\"@agentxjs/core/container\");\n const { containerRepository, imageRepository, sessionRepository } = this.runtime.platform;\n\n const container = await getOrCreateContainer(containerId, {\n containerRepository,\n imageRepository,\n sessionRepository,\n });\n\n return ok({ containerId: container.containerId });\n }\n\n private async handleContainerGet(params: unknown): Promise<RpcResponse> {\n const { containerId } = params as { containerId: string };\n const exists = await this.runtime.platform.containerRepository.containerExists(containerId);\n return ok({ containerId, exists });\n }\n\n private async handleContainerList(_params: unknown): Promise<RpcResponse> {\n const containers = await this.runtime.platform.containerRepository.findAllContainers();\n return ok({ containerIds: containers.map((c) => c.containerId) });\n }\n\n // ==================== Image Commands ====================\n\n private async handleImageCreate(params: unknown): Promise<RpcResponse> {\n const { containerId, name, description, systemPrompt, mcpServers, customData } = params as {\n containerId: string;\n name?: string;\n description?: string;\n systemPrompt?: string;\n mcpServers?: Record<string, unknown>;\n customData?: Record<string, unknown>;\n };\n\n const { imageRepository, sessionRepository } = this.runtime.platform;\n const { createImage } = await import(\"@agentxjs/core/image\");\n\n const image = await createImage(\n { containerId, name, description, systemPrompt, mcpServers: mcpServers as any, customData },\n { imageRepository, sessionRepository }\n );\n\n return ok({\n record: image.toRecord(),\n __subscriptions: [image.sessionId],\n });\n }\n\n private async handleImageGet(params: unknown): Promise<RpcResponse> {\n const { imageId } = params as { imageId: string };\n const record = await this.runtime.platform.imageRepository.findImageById(imageId);\n return ok({\n record,\n __subscriptions: record?.sessionId ? [record.sessionId] : undefined,\n });\n }\n\n private async handleImageList(params: unknown): Promise<RpcResponse> {\n const { containerId } = params as { containerId?: string };\n const records = containerId\n ? await this.runtime.platform.imageRepository.findImagesByContainerId(containerId)\n : await this.runtime.platform.imageRepository.findAllImages();\n\n return ok({\n records,\n __subscriptions: records.map((r) => r.sessionId),\n });\n }\n\n private async handleImageDelete(params: unknown): Promise<RpcResponse> {\n const { imageId } = params as { imageId: string };\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = this.runtime.platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (image) {\n await image.delete();\n }\n\n return ok({ imageId });\n }\n\n private async handleImageRun(params: unknown): Promise<RpcResponse> {\n const { imageId, agentId: requestedAgentId } = params as {\n imageId: string;\n agentId?: string;\n };\n\n // Check if already have a running agent for this image\n const existingAgent = this.runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n\n if (existingAgent) {\n logger.debug(\"Reusing existing agent for image\", {\n imageId,\n agentId: existingAgent.agentId,\n });\n return ok({\n imageId,\n agentId: existingAgent.agentId,\n sessionId: existingAgent.sessionId,\n containerId: existingAgent.containerId,\n reused: true,\n });\n }\n\n // Create new agent (with optional custom agentId)\n const agent = await this.runtime.createAgent({\n imageId,\n agentId: requestedAgentId,\n });\n logger.info(\"Created new agent for image\", {\n imageId,\n agentId: agent.agentId,\n });\n\n return ok({\n imageId,\n agentId: agent.agentId,\n sessionId: agent.sessionId,\n containerId: agent.containerId,\n reused: false,\n });\n }\n\n private async handleImageStop(params: unknown): Promise<RpcResponse> {\n const { imageId } = params as { imageId: string };\n\n // Find running agent for this image\n const agent = this.runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n\n if (agent) {\n await this.runtime.stopAgent(agent.agentId);\n logger.info(\"Stopped agent for image\", { imageId, agentId: agent.agentId });\n } else {\n logger.debug(\"No running agent found for image\", { imageId });\n }\n\n return ok({ imageId });\n }\n\n private async handleImageUpdate(params: unknown): Promise<RpcResponse> {\n const { imageId, updates } = params as {\n imageId: string;\n updates: { name?: string; description?: string; customData?: Record<string, unknown> };\n };\n\n // Get existing image\n const imageRecord = await this.runtime.platform.imageRepository.findImageById(imageId);\n if (!imageRecord) {\n return err(404, `Image not found: ${imageId}`);\n }\n\n // Update image record\n const updatedRecord = {\n ...imageRecord,\n ...updates,\n updatedAt: Date.now(),\n };\n\n await this.runtime.platform.imageRepository.saveImage(updatedRecord);\n\n logger.info(\"Updated image\", { imageId, updates });\n\n return ok({ record: updatedRecord });\n }\n\n private async handleImageMessages(params: unknown): Promise<RpcResponse> {\n const { imageId } = params as { imageId: string };\n\n // Get image record to find sessionId\n const imageRecord = await this.runtime.platform.imageRepository.findImageById(imageId);\n if (!imageRecord) {\n return err(404, `Image not found: ${imageId}`);\n }\n\n // Get messages from session\n const messages = await this.runtime.platform.sessionRepository.getMessages(\n imageRecord.sessionId\n );\n\n logger.debug(\"Got messages for image\", { imageId, count: messages.length });\n\n return ok({ imageId, messages });\n }\n\n // ==================== Agent Commands ====================\n\n private async handleAgentGet(params: unknown): Promise<RpcResponse> {\n const { agentId } = params as { agentId: string };\n const agent = this.runtime.getAgent(agentId);\n\n return ok({\n agent: agent\n ? {\n agentId: agent.agentId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n lifecycle: agent.lifecycle,\n }\n : null,\n exists: !!agent,\n });\n }\n\n private async handleAgentList(params: unknown): Promise<RpcResponse> {\n const { containerId } = params as { containerId?: string };\n const agents = containerId\n ? this.runtime.getAgentsByContainer(containerId)\n : this.runtime.getAgents();\n\n return ok({\n agents: agents.map((a) => ({\n agentId: a.agentId,\n imageId: a.imageId,\n containerId: a.containerId,\n sessionId: a.sessionId,\n lifecycle: a.lifecycle,\n })),\n });\n }\n\n private async handleAgentDestroy(params: unknown): Promise<RpcResponse> {\n const { agentId } = params as { agentId: string };\n\n // Check if agent exists first\n const agent = this.runtime.getAgent(agentId);\n if (!agent) {\n return ok({ agentId, success: false });\n }\n\n await this.runtime.destroyAgent(agentId);\n return ok({ agentId, success: true });\n }\n\n private async handleAgentDestroyAll(params: unknown): Promise<RpcResponse> {\n const { containerId } = params as { containerId: string };\n const agents = this.runtime.getAgentsByContainer(containerId);\n for (const agent of agents) {\n await this.runtime.destroyAgent(agent.agentId);\n }\n return ok({ containerId });\n }\n\n private async handleAgentInterrupt(params: unknown): Promise<RpcResponse> {\n const { agentId } = params as { agentId: string };\n this.runtime.interrupt(agentId);\n return ok({ agentId });\n }\n\n // ==================== Message Commands ====================\n\n private async handleMessageSend(params: unknown): Promise<RpcResponse> {\n const { agentId, imageId, content } = params as {\n agentId?: string;\n imageId?: string;\n content: string | UserContentPart[];\n };\n\n let targetAgentId: string;\n\n if (agentId) {\n // Direct agent reference\n targetAgentId = agentId;\n } else if (imageId) {\n // Auto-activate image: find or create agent\n const existingAgent = this.runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n\n if (existingAgent) {\n targetAgentId = existingAgent.agentId;\n logger.debug(\"Using existing agent for message\", {\n imageId,\n agentId: targetAgentId,\n });\n } else {\n // Create new agent for this image\n const agent = await this.runtime.createAgent({ imageId });\n targetAgentId = agent.agentId;\n logger.info(\"Auto-created agent for message\", {\n imageId,\n agentId: targetAgentId,\n });\n }\n } else {\n return err(-32602, \"Either agentId or imageId is required\");\n }\n\n await this.runtime.receive(targetAgentId, content);\n return ok({ agentId: targetAgentId, imageId });\n }\n\n // ==================== LLM Provider Commands ====================\n\n private async handleLLMCreate(params: unknown): Promise<RpcResponse> {\n const { containerId, name, vendor, protocol, apiKey, baseUrl, model } = params as {\n containerId: string;\n name: string;\n vendor: string;\n protocol: string;\n apiKey: string;\n baseUrl?: string;\n model?: string;\n };\n\n const repo = this.runtime.platform.llmProviderRepository;\n if (!repo) {\n return err(-32000, \"LLM provider repository not available\");\n }\n\n const { generateId } = await import(\"@deepracticex/id\");\n const now = Date.now();\n const record = {\n id: generateId(\"llm\"),\n containerId,\n name,\n vendor,\n protocol: protocol as \"anthropic\" | \"openai\",\n apiKey,\n baseUrl,\n model,\n isDefault: false,\n createdAt: now,\n updatedAt: now,\n };\n\n await repo.saveLLMProvider(record);\n return ok({ record });\n }\n\n private async handleLLMGet(params: unknown): Promise<RpcResponse> {\n const { id } = params as { id: string };\n const repo = this.runtime.platform.llmProviderRepository;\n if (!repo) {\n return err(-32000, \"LLM provider repository not available\");\n }\n\n const record = await repo.findLLMProviderById(id);\n return ok({ record });\n }\n\n private async handleLLMList(params: unknown): Promise<RpcResponse> {\n const { containerId } = params as { containerId: string };\n const repo = this.runtime.platform.llmProviderRepository;\n if (!repo) {\n return err(-32000, \"LLM provider repository not available\");\n }\n\n const records = await repo.findLLMProvidersByContainerId(containerId);\n return ok({ records });\n }\n\n private async handleLLMUpdate(params: unknown): Promise<RpcResponse> {\n const { id, updates } = params as {\n id: string;\n updates: Record<string, unknown>;\n };\n const repo = this.runtime.platform.llmProviderRepository;\n if (!repo) {\n return err(-32000, \"LLM provider repository not available\");\n }\n\n const existing = await repo.findLLMProviderById(id);\n if (!existing) {\n return err(404, `LLM provider not found: ${id}`);\n }\n\n const updated = {\n ...existing,\n ...updates,\n id: existing.id,\n containerId: existing.containerId,\n createdAt: existing.createdAt,\n updatedAt: Date.now(),\n };\n\n await repo.saveLLMProvider(updated);\n return ok({ record: updated });\n }\n\n private async handleLLMDelete(params: unknown): Promise<RpcResponse> {\n const { id } = params as { id: string };\n const repo = this.runtime.platform.llmProviderRepository;\n if (!repo) {\n return err(-32000, \"LLM provider repository not available\");\n }\n\n await repo.deleteLLMProvider(id);\n return ok({ id });\n }\n\n private async handleLLMDefault(params: unknown): Promise<RpcResponse> {\n const { id, containerId } = params as { id?: string; containerId?: string };\n const repo = this.runtime.platform.llmProviderRepository;\n if (!repo) {\n return err(-32000, \"LLM provider repository not available\");\n }\n\n if (id) {\n // Set default\n await repo.setDefaultLLMProvider(id);\n return ok({ id });\n }\n if (containerId) {\n // Get default\n const record = await repo.findDefaultLLMProvider(containerId);\n return ok({ record });\n }\n return err(-32602, \"Either id or containerId is required\");\n }\n\n // ==================== Lifecycle ====================\n\n dispose(): void {\n logger.debug(\"CommandHandler disposed\");\n }\n}\n"],"mappings":";AAgBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,2BAA2B;AACpC,SAAS,gBAAAA,qBAAoB;;;AChB7B,SAAS,oBAAoB;AAE7B,IAAM,SAAS,aAAa,uBAAuB;AAqBnD,SAAS,GAAM,MAAuB;AACpC,SAAO,EAAE,SAAS,MAAM,KAAK;AAC/B;AAKA,SAAS,IAAI,MAAc,SAA2B;AACpD,SAAO,EAAE,SAAS,OAAO,MAAM,QAAQ;AACzC;AAKO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EAEjB,YAAY,SAAwB;AAClC,SAAK,UAAU;AACf,WAAO,MAAM,wBAAwB;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,QAAmB,QAAuC;AACrE,WAAO,MAAM,wBAAwB,EAAE,OAAO,CAAC;AAE/C,QAAI;AACF,cAAQ,QAAQ;AAAA;AAAA,QAEd,KAAK;AACH,iBAAO,MAAM,KAAK,sBAAsB,MAAM;AAAA,QAChD,KAAK;AACH,iBAAO,MAAM,KAAK,mBAAmB,MAAM;AAAA,QAC7C,KAAK;AACH,iBAAO,MAAM,KAAK,oBAAoB,MAAM;AAAA;AAAA,QAG9C,KAAK;AACH,iBAAO,MAAM,KAAK,kBAAkB,MAAM;AAAA,QAC5C,KAAK;AACH,iBAAO,MAAM,KAAK,eAAe,MAAM;AAAA,QACzC,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,MAAM;AAAA,QAC1C,KAAK;AACH,iBAAO,MAAM,KAAK,kBAAkB,MAAM;AAAA,QAC5C,KAAK;AACH,iBAAO,MAAM,KAAK,eAAe,MAAM;AAAA,QACzC,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,MAAM;AAAA,QAC1C,KAAK;AACH,iBAAO,MAAM,KAAK,kBAAkB,MAAM;AAAA,QAC5C,KAAK;AACH,iBAAO,MAAM,KAAK,oBAAoB,MAAM;AAAA;AAAA,QAG9C,KAAK;AACH,iBAAO,MAAM,KAAK,eAAe,MAAM;AAAA,QACzC,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,MAAM;AAAA,QAC1C,KAAK;AACH,iBAAO,MAAM,KAAK,mBAAmB,MAAM;AAAA,QAC7C,KAAK;AACH,iBAAO,MAAM,KAAK,sBAAsB,MAAM;AAAA,QAChD,KAAK;AACH,iBAAO,MAAM,KAAK,qBAAqB,MAAM;AAAA;AAAA,QAG/C,KAAK;AACH,iBAAO,MAAM,KAAK,kBAAkB,MAAM;AAAA;AAAA,QAG5C,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,MAAM;AAAA,QAC1C,KAAK;AACH,iBAAO,MAAM,KAAK,aAAa,MAAM;AAAA,QACvC,KAAK;AACH,iBAAO,MAAM,KAAK,cAAc,MAAM;AAAA,QACxC,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,MAAM;AAAA,QAC1C,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,MAAM;AAAA,QAC1C,KAAK;AACH,iBAAO,MAAM,KAAK,iBAAiB,MAAM;AAAA,QAE3C;AACE,iBAAO,IAAI,QAAQ,qBAAqB,MAAM,EAAE;AAAA,MACpD;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,qBAAqB,EAAE,QAAQ,MAAM,CAAC;AACnD,aAAO,IAAI,OAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAC3E;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,sBAAsB,QAAuC;AACzE,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,0BAA0B;AACxE,UAAM,EAAE,qBAAqB,iBAAiB,kBAAkB,IAAI,KAAK,QAAQ;AAEjF,UAAM,YAAY,MAAM,qBAAqB,aAAa;AAAA,MACxD;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO,GAAG,EAAE,aAAa,UAAU,YAAY,CAAC;AAAA,EAClD;AAAA,EAEA,MAAc,mBAAmB,QAAuC;AACtE,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,SAAS,MAAM,KAAK,QAAQ,SAAS,oBAAoB,gBAAgB,WAAW;AAC1F,WAAO,GAAG,EAAE,aAAa,OAAO,CAAC;AAAA,EACnC;AAAA,EAEA,MAAc,oBAAoB,SAAwC;AACxE,UAAM,aAAa,MAAM,KAAK,QAAQ,SAAS,oBAAoB,kBAAkB;AACrF,WAAO,GAAG,EAAE,cAAc,WAAW,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;AAAA,EAClE;AAAA;AAAA,EAIA,MAAc,kBAAkB,QAAuC;AACrE,UAAM,EAAE,aAAa,MAAM,aAAa,cAAc,YAAY,WAAW,IAAI;AASjF,UAAM,EAAE,iBAAiB,kBAAkB,IAAI,KAAK,QAAQ;AAC5D,UAAM,EAAE,YAAY,IAAI,MAAM,OAAO,sBAAsB;AAE3D,UAAM,QAAQ,MAAM;AAAA,MAClB,EAAE,aAAa,MAAM,aAAa,cAAc,YAA+B,WAAW;AAAA,MAC1F,EAAE,iBAAiB,kBAAkB;AAAA,IACvC;AAEA,WAAO,GAAG;AAAA,MACR,QAAQ,MAAM,SAAS;AAAA,MACvB,iBAAiB,CAAC,MAAM,SAAS;AAAA,IACnC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,eAAe,QAAuC;AAClE,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,SAAS,MAAM,KAAK,QAAQ,SAAS,gBAAgB,cAAc,OAAO;AAChF,WAAO,GAAG;AAAA,MACR;AAAA,MACA,iBAAiB,QAAQ,YAAY,CAAC,OAAO,SAAS,IAAI;AAAA,IAC5D,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,gBAAgB,QAAuC;AACnE,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,UAAU,cACZ,MAAM,KAAK,QAAQ,SAAS,gBAAgB,wBAAwB,WAAW,IAC/E,MAAM,KAAK,QAAQ,SAAS,gBAAgB,cAAc;AAE9D,WAAO,GAAG;AAAA,MACR;AAAA,MACA,iBAAiB,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,IACjD,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,kBAAkB,QAAuC;AACrE,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,EAAE,UAAU,IAAI,MAAM,OAAO,sBAAsB;AACzD,UAAM,EAAE,iBAAiB,kBAAkB,IAAI,KAAK,QAAQ;AAE5D,UAAM,QAAQ,MAAM,UAAU,SAAS,EAAE,iBAAiB,kBAAkB,CAAC;AAC7E,QAAI,OAAO;AACT,YAAM,MAAM,OAAO;AAAA,IACrB;AAEA,WAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACvB;AAAA,EAEA,MAAc,eAAe,QAAuC;AAClE,UAAM,EAAE,SAAS,SAAS,iBAAiB,IAAI;AAM/C,UAAM,gBAAgB,KAAK,QACxB,UAAU,EACV,KAAK,CAAC,MAAM,EAAE,YAAY,WAAW,EAAE,cAAc,SAAS;AAEjE,QAAI,eAAe;AACjB,aAAO,MAAM,oCAAoC;AAAA,QAC/C;AAAA,QACA,SAAS,cAAc;AAAA,MACzB,CAAC;AACD,aAAO,GAAG;AAAA,QACR;AAAA,QACA,SAAS,cAAc;AAAA,QACvB,WAAW,cAAc;AAAA,QACzB,aAAa,cAAc;AAAA,QAC3B,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,UAAM,QAAQ,MAAM,KAAK,QAAQ,YAAY;AAAA,MAC3C;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AACD,WAAO,KAAK,+BAA+B;AAAA,MACzC;AAAA,MACA,SAAS,MAAM;AAAA,IACjB,CAAC;AAED,WAAO,GAAG;AAAA,MACR;AAAA,MACA,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,aAAa,MAAM;AAAA,MACnB,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,gBAAgB,QAAuC;AACnE,UAAM,EAAE,QAAQ,IAAI;AAGpB,UAAM,QAAQ,KAAK,QAChB,UAAU,EACV,KAAK,CAAC,MAAM,EAAE,YAAY,WAAW,EAAE,cAAc,SAAS;AAEjE,QAAI,OAAO;AACT,YAAM,KAAK,QAAQ,UAAU,MAAM,OAAO;AAC1C,aAAO,KAAK,2BAA2B,EAAE,SAAS,SAAS,MAAM,QAAQ,CAAC;AAAA,IAC5E,OAAO;AACL,aAAO,MAAM,oCAAoC,EAAE,QAAQ,CAAC;AAAA,IAC9D;AAEA,WAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACvB;AAAA,EAEA,MAAc,kBAAkB,QAAuC;AACrE,UAAM,EAAE,SAAS,QAAQ,IAAI;AAM7B,UAAM,cAAc,MAAM,KAAK,QAAQ,SAAS,gBAAgB,cAAc,OAAO;AACrF,QAAI,CAAC,aAAa;AAChB,aAAO,IAAI,KAAK,oBAAoB,OAAO,EAAE;AAAA,IAC/C;AAGA,UAAM,gBAAgB;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,WAAW,KAAK,IAAI;AAAA,IACtB;AAEA,UAAM,KAAK,QAAQ,SAAS,gBAAgB,UAAU,aAAa;AAEnE,WAAO,KAAK,iBAAiB,EAAE,SAAS,QAAQ,CAAC;AAEjD,WAAO,GAAG,EAAE,QAAQ,cAAc,CAAC;AAAA,EACrC;AAAA,EAEA,MAAc,oBAAoB,QAAuC;AACvE,UAAM,EAAE,QAAQ,IAAI;AAGpB,UAAM,cAAc,MAAM,KAAK,QAAQ,SAAS,gBAAgB,cAAc,OAAO;AACrF,QAAI,CAAC,aAAa;AAChB,aAAO,IAAI,KAAK,oBAAoB,OAAO,EAAE;AAAA,IAC/C;AAGA,UAAM,WAAW,MAAM,KAAK,QAAQ,SAAS,kBAAkB;AAAA,MAC7D,YAAY;AAAA,IACd;AAEA,WAAO,MAAM,0BAA0B,EAAE,SAAS,OAAO,SAAS,OAAO,CAAC;AAE1E,WAAO,GAAG,EAAE,SAAS,SAAS,CAAC;AAAA,EACjC;AAAA;AAAA,EAIA,MAAc,eAAe,QAAuC;AAClE,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,QAAQ,KAAK,QAAQ,SAAS,OAAO;AAE3C,WAAO,GAAG;AAAA,MACR,OAAO,QACH;AAAA,QACE,SAAS,MAAM;AAAA,QACf,SAAS,MAAM;AAAA,QACf,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM;AAAA,MACnB,IACA;AAAA,MACJ,QAAQ,CAAC,CAAC;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,gBAAgB,QAAuC;AACnE,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,SAAS,cACX,KAAK,QAAQ,qBAAqB,WAAW,IAC7C,KAAK,QAAQ,UAAU;AAE3B,WAAO,GAAG;AAAA,MACR,QAAQ,OAAO,IAAI,CAAC,OAAO;AAAA,QACzB,SAAS,EAAE;AAAA,QACX,SAAS,EAAE;AAAA,QACX,aAAa,EAAE;AAAA,QACf,WAAW,EAAE;AAAA,QACb,WAAW,EAAE;AAAA,MACf,EAAE;AAAA,IACJ,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,mBAAmB,QAAuC;AACtE,UAAM,EAAE,QAAQ,IAAI;AAGpB,UAAM,QAAQ,KAAK,QAAQ,SAAS,OAAO;AAC3C,QAAI,CAAC,OAAO;AACV,aAAO,GAAG,EAAE,SAAS,SAAS,MAAM,CAAC;AAAA,IACvC;AAEA,UAAM,KAAK,QAAQ,aAAa,OAAO;AACvC,WAAO,GAAG,EAAE,SAAS,SAAS,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,MAAc,sBAAsB,QAAuC;AACzE,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,SAAS,KAAK,QAAQ,qBAAqB,WAAW;AAC5D,eAAW,SAAS,QAAQ;AAC1B,YAAM,KAAK,QAAQ,aAAa,MAAM,OAAO;AAAA,IAC/C;AACA,WAAO,GAAG,EAAE,YAAY,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAc,qBAAqB,QAAuC;AACxE,UAAM,EAAE,QAAQ,IAAI;AACpB,SAAK,QAAQ,UAAU,OAAO;AAC9B,WAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACvB;AAAA;AAAA,EAIA,MAAc,kBAAkB,QAAuC;AACrE,UAAM,EAAE,SAAS,SAAS,QAAQ,IAAI;AAMtC,QAAI;AAEJ,QAAI,SAAS;AAEX,sBAAgB;AAAA,IAClB,WAAW,SAAS;AAElB,YAAM,gBAAgB,KAAK,QACxB,UAAU,EACV,KAAK,CAAC,MAAM,EAAE,YAAY,WAAW,EAAE,cAAc,SAAS;AAEjE,UAAI,eAAe;AACjB,wBAAgB,cAAc;AAC9B,eAAO,MAAM,oCAAoC;AAAA,UAC/C;AAAA,UACA,SAAS;AAAA,QACX,CAAC;AAAA,MACH,OAAO;AAEL,cAAM,QAAQ,MAAM,KAAK,QAAQ,YAAY,EAAE,QAAQ,CAAC;AACxD,wBAAgB,MAAM;AACtB,eAAO,KAAK,kCAAkC;AAAA,UAC5C;AAAA,UACA,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,aAAO,IAAI,QAAQ,uCAAuC;AAAA,IAC5D;AAEA,UAAM,KAAK,QAAQ,QAAQ,eAAe,OAAO;AACjD,WAAO,GAAG,EAAE,SAAS,eAAe,QAAQ,CAAC;AAAA,EAC/C;AAAA;AAAA,EAIA,MAAc,gBAAgB,QAAuC;AACnE,UAAM,EAAE,aAAa,MAAM,QAAQ,UAAU,QAAQ,SAAS,MAAM,IAAI;AAUxE,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,QAAI,CAAC,MAAM;AACT,aAAO,IAAI,OAAQ,uCAAuC;AAAA,IAC5D;AAEA,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,kBAAkB;AACtD,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,SAAS;AAAA,MACb,IAAI,WAAW,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAEA,UAAM,KAAK,gBAAgB,MAAM;AACjC,WAAO,GAAG,EAAE,OAAO,CAAC;AAAA,EACtB;AAAA,EAEA,MAAc,aAAa,QAAuC;AAChE,UAAM,EAAE,GAAG,IAAI;AACf,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,QAAI,CAAC,MAAM;AACT,aAAO,IAAI,OAAQ,uCAAuC;AAAA,IAC5D;AAEA,UAAM,SAAS,MAAM,KAAK,oBAAoB,EAAE;AAChD,WAAO,GAAG,EAAE,OAAO,CAAC;AAAA,EACtB;AAAA,EAEA,MAAc,cAAc,QAAuC;AACjE,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,QAAI,CAAC,MAAM;AACT,aAAO,IAAI,OAAQ,uCAAuC;AAAA,IAC5D;AAEA,UAAM,UAAU,MAAM,KAAK,8BAA8B,WAAW;AACpE,WAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACvB;AAAA,EAEA,MAAc,gBAAgB,QAAuC;AACnE,UAAM,EAAE,IAAI,QAAQ,IAAI;AAIxB,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,QAAI,CAAC,MAAM;AACT,aAAO,IAAI,OAAQ,uCAAuC;AAAA,IAC5D;AAEA,UAAM,WAAW,MAAM,KAAK,oBAAoB,EAAE;AAClD,QAAI,CAAC,UAAU;AACb,aAAO,IAAI,KAAK,2BAA2B,EAAE,EAAE;AAAA,IACjD;AAEA,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,GAAG;AAAA,MACH,IAAI,SAAS;AAAA,MACb,aAAa,SAAS;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,WAAW,KAAK,IAAI;AAAA,IACtB;AAEA,UAAM,KAAK,gBAAgB,OAAO;AAClC,WAAO,GAAG,EAAE,QAAQ,QAAQ,CAAC;AAAA,EAC/B;AAAA,EAEA,MAAc,gBAAgB,QAAuC;AACnE,UAAM,EAAE,GAAG,IAAI;AACf,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,QAAI,CAAC,MAAM;AACT,aAAO,IAAI,OAAQ,uCAAuC;AAAA,IAC5D;AAEA,UAAM,KAAK,kBAAkB,EAAE;AAC/B,WAAO,GAAG,EAAE,GAAG,CAAC;AAAA,EAClB;AAAA,EAEA,MAAc,iBAAiB,QAAuC;AACpE,UAAM,EAAE,IAAI,YAAY,IAAI;AAC5B,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,QAAI,CAAC,MAAM;AACT,aAAO,IAAI,OAAQ,uCAAuC;AAAA,IAC5D;AAEA,QAAI,IAAI;AAEN,YAAM,KAAK,sBAAsB,EAAE;AACnC,aAAO,GAAG,EAAE,GAAG,CAAC;AAAA,IAClB;AACA,QAAI,aAAa;AAEf,YAAM,SAAS,MAAM,KAAK,uBAAuB,WAAW;AAC5D,aAAO,GAAG,EAAE,OAAO,CAAC;AAAA,IACtB;AACA,WAAO,IAAI,QAAQ,sCAAsC;AAAA,EAC3D;AAAA;AAAA,EAIA,UAAgB;AACd,WAAO,MAAM,yBAAyB;AAAA,EACxC;AACF;;;AD5gBA,IAAMC,UAASC,cAAa,eAAe;AAqD3C,eAAsB,aAAa,QAA6C;AAC9E,QAAM,EAAE,SAAS,MAAM,IAAI;AAC3B,QAAM,WAAW,OAAO;AAGxB,QAAM,UAAU,oBAAoB,UAAU,OAAO,YAAY;AAGjE,QAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAGA,QAAM,iBAAiB,IAAI,eAAe,OAAO;AAGjD,QAAM,cAAc,oBAAI,IAA6B;AAKrD,WAAS,iBAAiB,cAAsB,OAAqB;AACnE,UAAM,QAAQ,YAAY,IAAI,YAAY;AAC1C,QAAI,CAAC,SAAS,MAAM,iBAAiB,IAAI,KAAK,EAAG;AAEjD,UAAM,iBAAiB,IAAI,KAAK;AAChC,IAAAD,QAAO,MAAM,kCAAkC,EAAE,cAAc,MAAM,CAAC;AAAA,EACxE;AAKA,WAAS,uBAAuB,OAAwB,OAA0B;AAEhF,QAAI,MAAM,WAAW,YAAY,MAAM,WAAW,gBAAgB;AAChE,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,WAAW,WAAW;AAC9B,aAAO;AAAA,IACT;AAGA,UAAM,mBAAmB;AACzB,UAAM,YAAY,iBAAiB,SAAS;AAC5C,QAAI,aAAa,MAAM,iBAAiB,IAAI,SAAS,GAAG;AACtD,aAAO;AAAA,IACT;AAGA,WAAO,MAAM,iBAAiB,IAAI,QAAQ;AAAA,EAC5C;AAKA,WAAS,aAAa,YAA+B,IAAqB,QAAuB;AAC/F,UAAM,WAAW,sBAAsB,IAAI,MAAM;AACjD,eAAW,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,EAC1C;AAKA,WAAS,UACP,YACA,IACA,MACA,SACM;AACN,UAAM,WAAW,oBAAoB,IAAI,MAAM,OAAO;AACtD,eAAW,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,EAC1C;AAGA,WAAS,aAAa,CAAC,eAAe;AACpC,UAAM,QAAyB;AAAA,MAC7B;AAAA,MACA,kBAAkB,oBAAI,IAAI,CAAC,QAAQ,CAAC;AAAA,IACtC;AACA,gBAAY,IAAI,WAAW,IAAI,KAAK;AAEpC,IAAAA,QAAO,KAAK,oBAAoB;AAAA,MAC9B,cAAc,WAAW;AAAA,MACzB,kBAAkB,YAAY;AAAA,IAChC,CAAC;AAGD,eAAW,UAAU,OAAO,YAAY;AACtC,UAAI;AACF,cAAM,SAAS,aAAa,OAAO;AAGnC,YAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,gBAAM,oBAAoB,YAAY,OAAO,MAAM;AAAA,QACrD,OAAO;AAEL,qBAAW,QAAQ,QAAQ;AACzB,kBAAM,oBAAoB,YAAY,OAAO,IAAI;AAAA,UACnD;AAAA,QACF;AAAA,MACF,SAASE,MAAK;AACZ,QAAAF,QAAO,MAAM,2BAA2B,EAAE,OAAQE,KAAc,QAAQ,CAAC;AACzE,kBAAU,YAAY,MAAM,cAAc,aAAa,aAAa;AAAA,MACtE;AAAA,IACF,CAAC;AAGD,eAAW,QAAQ,MAAM;AACvB,kBAAY,OAAO,WAAW,EAAE;AAChC,MAAAF,QAAO,KAAK,uBAAuB;AAAA,QACjC,cAAc,WAAW;AAAA,QACzB,kBAAkB,YAAY;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AAKD,iBAAe,oBACb,YACA,OACA,QACe;AACf,QAAI,UAAU,MAAM,GAAG;AAErB,YAAM,UAAU,OAAO;AAKvB,YAAM,EAAE,IAAI,QAAQ,OAAO,IAAI;AAE/B,MAAAA,QAAO,MAAM,wBAAwB,EAAE,IAAI,OAAO,CAAC;AAGnD,YAAM,SAAS,MAAM,eAAe,OAAO,QAAqB,MAAM;AAEtE,UAAI,OAAO,SAAS;AAClB,qBAAa,YAAY,IAAI,OAAO,IAAI;AAAA,MAC1C,OAAO;AACL,kBAAU,YAAY,IAAI,OAAO,MAAM,OAAO,OAAO;AAAA,MACvD;AAAA,IACF,WAAW,eAAe,MAAM,GAAG;AAEjC,YAAM,UAAU,OAAO;AAIvB,YAAM,EAAE,QAAQ,OAAO,IAAI;AAE3B,MAAAA,QAAO,MAAM,yBAAyB,EAAE,OAAO,CAAC;AAEhD,UAAI,WAAW,aAAa;AAC1B,cAAM,EAAE,MAAM,IAAI;AAClB,yBAAiB,WAAW,IAAI,KAAK;AAAA,MACvC,WAAW,WAAW,eAAe;AACnC,cAAM,EAAE,MAAM,IAAI;AAClB,cAAM,iBAAiB,OAAO,KAAK;AACnC,QAAAA,QAAO,MAAM,sCAAsC,EAAE,cAAc,WAAW,IAAI,MAAM,CAAC;AAAA,MAC3F,WAAW,WAAW,eAAe;AAEnC,QAAAA,QAAO,MAAM,2BAA2B;AAAA,MAC1C;AAAA,IACF,OAAO;AAEL,MAAAA,QAAO,KAAK,mCAAmC;AAAA,IACjD;AAAA,EACF;AAGA,WAAS,SAAS,MAAM,CAAC,UAAU;AAEjC,QAAI,CAAC,qBAAqB,KAAK,GAAG;AAChC;AAAA,IACF;AAGA,UAAM,mBAAmB;AACzB,UAAM,QAAQ,iBAAiB,SAAS,aAAa;AAGrD,UAAM,eAAe,kBAAkB,OAAO,KAAoB;AAClE,UAAM,UAAU,KAAK,UAAU,YAAY;AAE3C,eAAW,CAAC,cAAc,KAAK,KAAK,aAAa;AAC/C,UAAI,uBAAuB,OAAO,KAAK,GAAG;AACxC,cAAM,WAAW,aAAa,SAAS;AAAA,UACrC,SAAS;AAAA,UACT,WAAW,MAAM;AACf,YAAAA,QAAO,KAAK,qBAAqB;AAAA,cAC/B;AAAA,cACA,WAAW,MAAM;AAAA,YACnB,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAKD,WAAS,qBAAqB,OAA0B;AAEtD,QAAI,MAAM,WAAW,YAAY,MAAM,WAAW,gBAAgB;AAChE,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,WAAW,WAAW;AAC9B,aAAO;AAAA,IACT;AAGA,UAAM,cAAc;AACpB,QAAI,YAAY,kBAAkB,OAAO;AACvC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,QAAQ;AACjB,aAAS,OAAO,OAAO,QAAQ,MAAM;AACrC,IAAAA,QAAO,KAAK,yCAAyC,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAEA,SAAO;AAAA,IACL,MAAM,OAAO,MAAe,MAAe;AACzC,UAAI,OAAO,QAAQ;AACjB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,QAAQ,OAAO,QAAQ;AAC1C,YAAM,aAAa,QAAQ,OAAO,QAAQ;AAE1C,YAAM,SAAS,OAAO,YAAY,UAAU;AAC5C,MAAAA,QAAO,KAAK,oBAAoB,EAAE,MAAM,YAAY,MAAM,WAAW,CAAC;AAAA,IACxE;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,SAAS,MAAM;AACrB,MAAAA,QAAO,KAAK,eAAe;AAAA,IAC7B;AAAA,IAEA,MAAM,UAAU;AAEd,YAAM,SAAS,QAAQ;AACvB,qBAAe,QAAQ;AACvB,YAAM,QAAQ,SAAS;AACvB,MAAAA,QAAO,KAAK,iBAAiB;AAAA,IAC/B;AAAA,EACF;AACF;","names":["createLogger","logger","createLogger","err"]}
|