agentxjs 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -19
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -178,25 +178,54 @@ const response = await ax.rpc(request.method, request.params);
|
|
|
178
178
|
|
|
179
179
|
### Error Handling
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
AgentX has two layers of error handling, serving different purposes:
|
|
182
|
+
|
|
183
|
+
| Layer | Purpose | Who uses it | How errors arrive |
|
|
184
|
+
| ----- | ------- | ----------- | ----------------- |
|
|
185
|
+
| **Presentation** | Show errors to end users in chat | UI developers | `ErrorConversation` in `state.conversations` |
|
|
186
|
+
| **`ax.onError`** | Programmatic monitoring & alerting | Platform operators | `AgentXError` callback |
|
|
187
|
+
|
|
188
|
+
Most applications only need the Presentation layer. `ax.onError` is for advanced scenarios like Sentry integration or custom circuit-breaker logic.
|
|
189
|
+
|
|
190
|
+
#### Presentation Errors (recommended)
|
|
191
|
+
|
|
192
|
+
When an LLM call fails (e.g., 403 Forbidden, network timeout), the error automatically appears in `state.conversations` as an `ErrorConversation`:
|
|
182
193
|
|
|
183
194
|
```typescript
|
|
184
|
-
|
|
195
|
+
const presentation = await ax.presentation.create(agentId, {
|
|
196
|
+
onUpdate: (state) => {
|
|
197
|
+
for (const conv of state.conversations) {
|
|
198
|
+
if (conv.role === "user") {
|
|
199
|
+
renderUserMessage(conv);
|
|
200
|
+
} else if (conv.role === "assistant") {
|
|
201
|
+
renderAssistantMessage(conv);
|
|
202
|
+
} else if (conv.role === "error") {
|
|
203
|
+
// LLM errors show up here automatically
|
|
204
|
+
renderErrorMessage(conv.message);
|
|
205
|
+
// e.g. "403 Forbidden: Invalid API key"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
```
|
|
185
211
|
|
|
186
|
-
|
|
187
|
-
console.error(`[${error.category}] ${error.code}: ${error.message}`);
|
|
212
|
+
The flow is fully automatic — no extra code needed:
|
|
188
213
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
214
|
+
```
|
|
215
|
+
LLM API fails → Driver emits error → Engine creates ErrorConversation
|
|
216
|
+
→ Presentation state updates → onUpdate fires → UI renders error
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
`state.streaming` resets to `null` and `state.status` returns to `"idle"`, so the UI naturally stops showing loading indicators.
|
|
192
220
|
|
|
193
|
-
|
|
194
|
-
// Message failed to save — conversation continues but data may be lost
|
|
195
|
-
}
|
|
221
|
+
#### `ax.onError` (advanced)
|
|
196
222
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
223
|
+
For monitoring, logging, or custom recovery logic. Receives structured `AgentXError` from all layers (driver, persistence, connection). Independent of Presentation — fires even without a Presentation instance.
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
ax.onError((error) => {
|
|
227
|
+
reportToSentry(error);
|
|
228
|
+
console.error(`[${error.category}] ${error.code}: ${error.message}`);
|
|
200
229
|
});
|
|
201
230
|
```
|
|
202
231
|
|
|
@@ -204,13 +233,13 @@ ax.onError((error) => {
|
|
|
204
233
|
|
|
205
234
|
| Property | Type | Description |
|
|
206
235
|
| ------------- | -------- | ------------------------------------ |
|
|
207
|
-
| `code` | string |
|
|
236
|
+
| `code` | string | `DRIVER_ERROR`, `CIRCUIT_OPEN`, `PERSISTENCE_FAILED`, `CONNECTION_FAILED` |
|
|
208
237
|
| `category` | string | `"driver"` \| `"persistence"` \| `"connection"` \| `"runtime"` |
|
|
209
238
|
| `recoverable` | boolean | Whether the caller should retry |
|
|
210
239
|
| `context` | object | `{ agentId?, sessionId?, imageId? }` |
|
|
211
240
|
| `cause` | Error? | Original error |
|
|
212
241
|
|
|
213
|
-
**Built-in circuit breaker:** After 5 consecutive driver failures, the circuit opens and rejects new requests
|
|
242
|
+
**Built-in circuit breaker:** After 5 consecutive driver failures, the circuit opens and rejects new requests for 30s. This is automatic — no code required.
|
|
214
243
|
|
|
215
244
|
### Stream Events
|
|
216
245
|
|
|
@@ -222,21 +251,22 @@ ax.onError((error) => {
|
|
|
222
251
|
| `input_json_delta` | `{ partialJson }` | Incremental tool input |
|
|
223
252
|
| `tool_result` | `{ toolCallId, result }` | Tool execution result |
|
|
224
253
|
| `message_stop` | `{ stopReason }` | Response complete |
|
|
225
|
-
| `error` | `{ message }` | Error
|
|
254
|
+
| `error` | `{ message }` | Error during streaming |
|
|
255
|
+
|
|
256
|
+
> **Note:** If you use the Presentation API, you don't need to handle the `error` stream event — it is automatically converted to an `ErrorConversation` in `state.conversations`.
|
|
226
257
|
|
|
227
258
|
### Presentation API
|
|
228
259
|
|
|
229
|
-
High-level UI state management. Aggregates raw stream events into structured conversation state.
|
|
260
|
+
High-level UI state management. Aggregates raw stream events into structured conversation state — the recommended way to build chat UIs.
|
|
230
261
|
|
|
231
262
|
```typescript
|
|
232
263
|
const presentation = await ax.presentation.create(agentId, {
|
|
233
264
|
onUpdate: (state) => {
|
|
234
|
-
// state.conversations — completed messages (
|
|
265
|
+
// state.conversations — completed messages (user, assistant, and error)
|
|
235
266
|
// state.streaming — current streaming response (or null)
|
|
236
267
|
// state.status — "idle" | "thinking" | "responding" | "executing"
|
|
237
268
|
renderUI(state);
|
|
238
269
|
},
|
|
239
|
-
onError: (error) => console.error(error),
|
|
240
270
|
});
|
|
241
271
|
|
|
242
272
|
await presentation.send("What is the weather?");
|
|
@@ -244,6 +274,14 @@ const state = presentation.getState();
|
|
|
244
274
|
presentation.dispose();
|
|
245
275
|
```
|
|
246
276
|
|
|
277
|
+
**Conversation types in `state.conversations`:**
|
|
278
|
+
|
|
279
|
+
| `role` | Type | Content |
|
|
280
|
+
| ------ | ---- | ------- |
|
|
281
|
+
| `"user"` | `UserConversation` | `blocks: [{ type: "text", content }]` |
|
|
282
|
+
| `"assistant"` | `AssistantConversation` | `blocks: [{ type: "text", content }, { type: "tool_use", ... }]` |
|
|
283
|
+
| `"error"` | `ErrorConversation` | `message: string` — the error description |
|
|
284
|
+
|
|
247
285
|
For custom state management, use the exported reducer:
|
|
248
286
|
|
|
249
287
|
```typescript
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentxjs",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "AgentX Client SDK - Local and remote AI agent management",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"test": "bun test bdd/"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@agentxjs/core": "^2.3.
|
|
26
|
+
"@agentxjs/core": "^2.3.1",
|
|
27
27
|
"@deepracticex/id": "^0.2.0",
|
|
28
28
|
"@deepracticex/logger": "^1.2.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@agentxjs/devtools": "^2.3.
|
|
31
|
+
"@agentxjs/devtools": "^2.3.1",
|
|
32
32
|
"@deepracticex/bdd": "^0.3.0",
|
|
33
33
|
"tsx": "^4.19.0",
|
|
34
34
|
"typescript": "^5.3.3"
|