@ai-matrx/agents 0.5.1 → 0.6.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/CHANGELOG.md +52 -0
- package/README.md +41 -16
- package/dist/index.cjs +415 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +396 -3
- package/dist/index.js.map +1 -1
- package/dist/matrx/index.cjs +401 -26
- package/dist/matrx/index.cjs.map +1 -1
- package/dist/matrx/index.d.cts +345 -1
- package/dist/matrx/index.d.ts +345 -1
- package/dist/matrx/index.js +382 -3
- package/dist/matrx/index.js.map +1 -1
- package/dist/presentation/result.cjs +23 -4
- package/dist/presentation/result.cjs.map +1 -1
- package/dist/presentation/result.js +3 -3
- package/dist/presentation/result.js.map +1 -1
- package/dist/projection/request.cjs +25 -6
- package/dist/projection/request.cjs.map +1 -1
- package/dist/projection/request.js +5 -3
- package/dist/projection/request.js.map +1 -1
- package/dist/projection/workflow.cjs +25 -6
- package/dist/projection/workflow.cjs.map +1 -1
- package/dist/projection/workflow.js +5 -3
- package/dist/projection/workflow.js.map +1 -1
- package/dist/react/index.cjs +1038 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +540 -0
- package/dist/react/index.d.ts +540 -0
- package/dist/react/index.js +1016 -0
- package/dist/react/index.js.map +1 -0
- package/dist/stream/ndjson.cjs +26 -7
- package/dist/stream/ndjson.cjs.map +1 -1
- package/dist/stream/ndjson.js +6 -3
- package/dist/stream/ndjson.js.map +1 -1
- package/dist/stream/sse.cjs +25 -6
- package/dist/stream/sse.cjs.map +1 -1
- package/dist/stream/sse.js +5 -3
- package/dist/stream/sse.js.map +1 -1
- package/package.json +28 -2
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
type AgentProjectionStatus = "pending" | "streaming" | "awaiting-tools" | "complete" | "error" | "cancelled";
|
|
2
|
+
interface AgentProjectionOperation {
|
|
3
|
+
operationId: string;
|
|
4
|
+
operation: string;
|
|
5
|
+
parentOperationId: string | null;
|
|
6
|
+
status: "active" | "success" | "failed" | "cancelled";
|
|
7
|
+
metadata: Record<string, unknown> | null;
|
|
8
|
+
result: Record<string, unknown> | null;
|
|
9
|
+
}
|
|
10
|
+
interface AgentProjectionTool {
|
|
11
|
+
callId: string;
|
|
12
|
+
toolName: string;
|
|
13
|
+
status: "started" | "progress" | "step" | "preview" | "completed" | "error" | "delegated";
|
|
14
|
+
message: string | null;
|
|
15
|
+
data: Record<string, unknown> | null;
|
|
16
|
+
}
|
|
17
|
+
interface AgentProjectionRenderBlock {
|
|
18
|
+
blockId: string;
|
|
19
|
+
blockIndex: number;
|
|
20
|
+
type: string;
|
|
21
|
+
status: "streaming" | "complete" | "error";
|
|
22
|
+
content: string | null;
|
|
23
|
+
data: Record<string, unknown> | null;
|
|
24
|
+
metadata: Record<string, unknown> | null;
|
|
25
|
+
}
|
|
26
|
+
interface AgentRequestProjection {
|
|
27
|
+
requestId: string;
|
|
28
|
+
conversationId: string | null;
|
|
29
|
+
status: AgentProjectionStatus;
|
|
30
|
+
answer: string;
|
|
31
|
+
reasoning: string;
|
|
32
|
+
reasoningActive: boolean;
|
|
33
|
+
phase: string | null;
|
|
34
|
+
phaseHistory: string[];
|
|
35
|
+
operations: Record<string, AgentProjectionOperation>;
|
|
36
|
+
tools: Record<string, AgentProjectionTool>;
|
|
37
|
+
renderBlocks: Record<string, AgentProjectionRenderBlock>;
|
|
38
|
+
renderBlockOrder: string[];
|
|
39
|
+
completion: Record<string, unknown> | null;
|
|
40
|
+
error: Record<string, unknown> | null;
|
|
41
|
+
lastTransportSeq: number;
|
|
42
|
+
eventCount: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* `@ai-matrx/agents/matrx` — the Matrx transport port.
|
|
47
|
+
*
|
|
48
|
+
* The ONE seam between this package's wire semantics and a host's connection
|
|
49
|
+
* policy. This package owns WHAT is said to the AI Matrx server — paths,
|
|
50
|
+
* methods, JSON bodies, streaming Accept headers, the `Last-Event-ID` cursor
|
|
51
|
+
* header — and the host owns HOW the connection is made:
|
|
52
|
+
*
|
|
53
|
+
* - base-URL / backend-channel resolution (global, sandbox override, local
|
|
54
|
+
* engine, EC2-dedicated — whatever ladder the host runs);
|
|
55
|
+
* - credentials (Supabase JWT `Authorization: Bearer`, guest
|
|
56
|
+
* `X-Fingerprint-ID`, or the API-key lane) — NEVER implemented here;
|
|
57
|
+
* - the `X-Organization-Id` context header;
|
|
58
|
+
* - retry policy, network-level timeouts, and diagnostics capture.
|
|
59
|
+
*
|
|
60
|
+
* A host implements the port in a few lines:
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* const transport: MatrxTransport = {
|
|
64
|
+
* fetch: (path, init) =>
|
|
65
|
+
* fetch(`${baseUrl}${path}`, {
|
|
66
|
+
* ...init,
|
|
67
|
+
* headers: { ...init.headers, ...authHeaders() },
|
|
68
|
+
* }),
|
|
69
|
+
* };
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* The port is deliberately structural and `fetch`-shaped so `@ai-matrx/data`'s
|
|
73
|
+
* `/api` transport can implement it without importing this package.
|
|
74
|
+
*/
|
|
75
|
+
/**
|
|
76
|
+
* The request this package hands the port. A strict subset of `RequestInit`,
|
|
77
|
+
* so a host can spread it straight into `fetch`.
|
|
78
|
+
*/
|
|
79
|
+
interface MatrxTransportRequest {
|
|
80
|
+
method: "GET" | "POST";
|
|
81
|
+
/**
|
|
82
|
+
* Wire-semantic headers the CALL requires (`Content-Type`, `Accept`,
|
|
83
|
+
* `Last-Event-ID`). The host merges its policy headers (auth, org) on top;
|
|
84
|
+
* it must not drop these.
|
|
85
|
+
*/
|
|
86
|
+
headers: Record<string, string>;
|
|
87
|
+
/** Pre-serialized JSON body, present on POST calls that carry one. */
|
|
88
|
+
body?: string;
|
|
89
|
+
/** Caller cancellation. The host must wire it to the underlying fetch. */
|
|
90
|
+
signal?: AbortSignal;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The transport port. `path` is server-relative and always starts with `/`
|
|
94
|
+
* (`/ai/...`, `/runtime/...`); the host prepends its resolved base URL.
|
|
95
|
+
*/
|
|
96
|
+
interface MatrxTransport {
|
|
97
|
+
fetch(path: string, init: MatrxTransportRequest): Promise<Response>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The PRODUCTION `MatrxTransport` — the full connection pipeline every Matrx
|
|
102
|
+
* host used to hand-roll, moved in under C22 (THE HARD PARTS LIVE IN THE
|
|
103
|
+
* PACKAGE). A host constructs it from identity alone:
|
|
104
|
+
*
|
|
105
|
+
* ```ts
|
|
106
|
+
* const transport = createMatrxTransport({
|
|
107
|
+
* baseUrl: "https://server.app.matrxserver.com",
|
|
108
|
+
* credentials, // CredentialsPort (@ai-matrx/data)
|
|
109
|
+
* organizationId: () => activeOrgId, // omit for conversation-lane calls
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* Everything else is defaulted to the proven production values:
|
|
114
|
+
*
|
|
115
|
+
* - **timeouts** — connect 15s (for a non-streaming FastAPI handler this is
|
|
116
|
+
* effectively time-to-response), total UNCAPPED (the port cannot tell a JSON
|
|
117
|
+
* call from a long-lived NDJSON/SSE stream; the connect timeout is the JSON
|
|
118
|
+
* guard), via `@ai-matrx/data/net`'s `resilientFetch`;
|
|
119
|
+
* - **protocol** — the AI API version transform (`applyAiApiVersion`, default
|
|
120
|
+
* v2) + the loud v2 → v1 transport fallback (`./protocol`);
|
|
121
|
+
* - **credentials** — read fresh from the injected `CredentialsPort` on EVERY
|
|
122
|
+
* call, so a token refresh mid-run is picked up; mapped to headers by the
|
|
123
|
+
* ONE `credentialToHeaders`;
|
|
124
|
+
* - **org context** — the fail-closed `X-Organization-Id` binding
|
|
125
|
+
* (`./org-context`): configured lanes REQUIRE an org and refuse before the
|
|
126
|
+
* wire; unconfigured lanes (conversation-scoped calls, which carry org in
|
|
127
|
+
* the body) send none;
|
|
128
|
+
* - **error classification** — every failure normalizes through
|
|
129
|
+
* `normalizeMatrxError` into the ONE `MatrxCallError` envelope;
|
|
130
|
+
* - **diagnostics** — a typed sink the host wires to its capture/telemetry
|
|
131
|
+
* (`onRequest`, `onError`, `onProtocolDowngrade`); wiring it is optional,
|
|
132
|
+
* the transport works silently without it.
|
|
133
|
+
*
|
|
134
|
+
* Header merge order is part of the port contract: wire headers first
|
|
135
|
+
* (`Content-Type` / `Accept` / `Last-Event-ID` — the package's), then
|
|
136
|
+
* credentials, then resolver policy headers, then the org header. Policy
|
|
137
|
+
* headers never carry `Content-Type` — the wire owns it, and a policy
|
|
138
|
+
* `Content-Type` merged over a GET SSE call would corrupt the wire, so the
|
|
139
|
+
* factory strips it defensively.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The ONE classified error shape for Matrx client calls — the envelope hosts
|
|
144
|
+
* branch on instead of string-matching exceptions. Structurally compatible
|
|
145
|
+
* with matrx-frontend's `ApiCallError` by design.
|
|
146
|
+
*/
|
|
147
|
+
interface MatrxCallError {
|
|
148
|
+
type: "auth_error" | "network_error" | "http_error" | "validation_error" | "abort_error" | "unknown";
|
|
149
|
+
message: string;
|
|
150
|
+
/** HTTP status code, if applicable. */
|
|
151
|
+
status?: number;
|
|
152
|
+
/** Raw error detail from the server (the parsed error body). */
|
|
153
|
+
serverDetail?: unknown;
|
|
154
|
+
/** Machine code preserved through normalization (server `code`, org-context code, …). */
|
|
155
|
+
code?: string;
|
|
156
|
+
/** Original exception identity for diagnostics. */
|
|
157
|
+
name?: string;
|
|
158
|
+
/** Original exception stack. */
|
|
159
|
+
stack?: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The conversation-start contract — client-minted `conversation_id`, `is_new`,
|
|
164
|
+
* `store` — typed exactly per the cross-repo System of Record
|
|
165
|
+
* (`common-docs/systems/agents/conversation-start-contract/FEATURE.md`;
|
|
166
|
+
* server truth `aidream/services/conversation_context/scope.py::
|
|
167
|
+
* ConversationStartRequest`).
|
|
168
|
+
*
|
|
169
|
+
* Every request that STARTS a conversation sends all three fields, no
|
|
170
|
+
* defaults:
|
|
171
|
+
*
|
|
172
|
+
* | `is_new` | `store` | Result |
|
|
173
|
+
* |----------|---------|----------------------------------------------------------|
|
|
174
|
+
* | true | true | Create the row with the caller's id — 409 if it exists |
|
|
175
|
+
* | true | false | No row. The id is correlation only (ephemeral run) |
|
|
176
|
+
* | false | true | Continue it — 404 if the caller doesn't own it |
|
|
177
|
+
* | false | false | Ephemeral run on a known id; nothing read, nothing written |
|
|
178
|
+
*
|
|
179
|
+
* `store` is the ONLY ephemeral signal; `is_new` is the caller's assertion
|
|
180
|
+
* about the id, never a persistence switch. `prior_messages` (the client-owned
|
|
181
|
+
* transcript of an ephemeral multi-turn run) is only valid with
|
|
182
|
+
* `store: false` — the union below makes the invalid combination
|
|
183
|
+
* unrepresentable, mirroring the server's 422.
|
|
184
|
+
*
|
|
185
|
+
* Continue routes (`POST /ai/conversations/{id}`) take the id from the path
|
|
186
|
+
* and do not carry this triple.
|
|
187
|
+
*/
|
|
188
|
+
/** Recursive JSON value — the package's honest type for free-form wire bags. */
|
|
189
|
+
type MatrxJsonValue = string | number | boolean | null | MatrxJsonValue[] | {
|
|
190
|
+
[key: string]: MatrxJsonValue;
|
|
191
|
+
};
|
|
192
|
+
/** A JSON object on the wire. */
|
|
193
|
+
type MatrxJsonObject = {
|
|
194
|
+
[key: string]: MatrxJsonValue;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* One LLM message on the request wire — `prior_messages` entries for
|
|
198
|
+
* stateless multi-turn runs. Mirrors aidream's `ChatMessageInput`
|
|
199
|
+
* (`aidream/schemas/messages.py`, `extra="allow"` — additional provider
|
|
200
|
+
* fields round-trip untouched).
|
|
201
|
+
*/
|
|
202
|
+
interface MatrxChatMessage {
|
|
203
|
+
role: string;
|
|
204
|
+
content?: string | MatrxJsonValue[] | null;
|
|
205
|
+
name?: string | null;
|
|
206
|
+
tool_call_id?: string | null;
|
|
207
|
+
tool_calls?: MatrxJsonObject[] | null;
|
|
208
|
+
[extra: string]: MatrxJsonValue | undefined;
|
|
209
|
+
}
|
|
210
|
+
/** `is_new: true, store: true` — create the row with the caller's id. */
|
|
211
|
+
interface MatrxStoredConversationCreate {
|
|
212
|
+
conversation_id: string;
|
|
213
|
+
is_new: true;
|
|
214
|
+
store: true;
|
|
215
|
+
}
|
|
216
|
+
/** `is_new: false, store: true` — continue an owned stored conversation via a start route. */
|
|
217
|
+
interface MatrxStoredConversationContinue {
|
|
218
|
+
conversation_id: string;
|
|
219
|
+
is_new: false;
|
|
220
|
+
store: true;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* `store: false` — ephemeral: nothing read, nothing written; the id is the
|
|
224
|
+
* caller's correlation handle. This is the ONLY member that may carry
|
|
225
|
+
* `prior_messages` (the server 422s a client transcript on a stored run).
|
|
226
|
+
*/
|
|
227
|
+
interface MatrxEphemeralConversation {
|
|
228
|
+
conversation_id: string;
|
|
229
|
+
is_new: boolean;
|
|
230
|
+
store: false;
|
|
231
|
+
prior_messages?: MatrxChatMessage[];
|
|
232
|
+
}
|
|
233
|
+
/** The full conversation-start triple, one member per contract cell. */
|
|
234
|
+
type MatrxConversationStart = MatrxStoredConversationCreate | MatrxStoredConversationContinue | MatrxEphemeralConversation;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Canonical AI Matrx NDJSON wire kernel.
|
|
238
|
+
*
|
|
239
|
+
* This module is deliberately independent of React, Redux, Next.js, Supabase,
|
|
240
|
+
* and generated application types. Every Matrx client uses it to turn the
|
|
241
|
+
* backend's byte stream into the same normalized `{ event, data }` envelopes.
|
|
242
|
+
* Host runtimes remain responsible for HTTP/auth errors and for deciding what
|
|
243
|
+
* each event means in their state model.
|
|
244
|
+
*/
|
|
245
|
+
interface MatrxStreamEnvelope<TData = unknown> {
|
|
246
|
+
event: string;
|
|
247
|
+
data: TData;
|
|
248
|
+
/** Monotonic transport sequence from full envelopes, when supplied. */
|
|
249
|
+
stream_seq?: number;
|
|
250
|
+
}
|
|
251
|
+
interface MatrxNdjsonIssue {
|
|
252
|
+
line: string;
|
|
253
|
+
error: unknown;
|
|
254
|
+
/** One-based physical NDJSON line number. */
|
|
255
|
+
lineNumber: number;
|
|
256
|
+
/** True when an unterminated trailing fragment was parsed by `finish()`. */
|
|
257
|
+
atCompletion: boolean;
|
|
258
|
+
}
|
|
259
|
+
interface MatrxStreamEnvelopeObservation {
|
|
260
|
+
/** Exact parsed JSON value before compact/full normalization. */
|
|
261
|
+
raw: unknown;
|
|
262
|
+
envelope: MatrxStreamEnvelope;
|
|
263
|
+
line: string;
|
|
264
|
+
lineNumber: number;
|
|
265
|
+
atCompletion: boolean;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Internal request plumbing for `@ai-matrx/agents/matrx`. Not part of the
|
|
270
|
+
* public surface — `matrx/index.ts` deliberately does not re-export this
|
|
271
|
+
* module. Everything here is pure: no globals, no work at import time.
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Options for every streaming call, riding the NDJSON kernel's contract.
|
|
276
|
+
* Public via `./run`'s re-export.
|
|
277
|
+
*/
|
|
278
|
+
interface MatrxStreamCallOptions {
|
|
279
|
+
/** Abort the fetch and end the events iterator. */
|
|
280
|
+
signal?: AbortSignal;
|
|
281
|
+
/** Bounded background read-ahead (see `stream/ndjson`). */
|
|
282
|
+
maxReadAhead?: number;
|
|
283
|
+
/** Malformed NDJSON is non-fatal but must never disappear silently. */
|
|
284
|
+
onMalformedLine?: (issue: MatrxNdjsonIssue) => void;
|
|
285
|
+
/** Valid JSON with no recognized Matrx envelope. */
|
|
286
|
+
onUnknownEnvelope?: (value: unknown) => void;
|
|
287
|
+
/** Observe every valid envelope in its exact wire form. */
|
|
288
|
+
onValidEnvelope?: (observation: MatrxStreamEnvelopeObservation) => void;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Agent run lifecycle against the AI Matrx API — start, continue, resume,
|
|
293
|
+
* cancel — over the `MatrxTransport` port, with every streaming response
|
|
294
|
+
* parsed through the package's ONE NDJSON wire kernel (`stream/ndjson`).
|
|
295
|
+
*
|
|
296
|
+
* Server truth (verified against aidream source):
|
|
297
|
+
* - `POST /ai/agents/{agent_id}` — start (`aidream/api/routers/agents.py`)
|
|
298
|
+
* - `POST /ai/conversations/{conversation_id}` — continue (`aidream/api/routers/conversations.py`)
|
|
299
|
+
* - `POST /ai/conversations/{conversation_id}/resume` — resume after
|
|
300
|
+
* client-delegated tool suspension (same router)
|
|
301
|
+
* - `POST /ai/cancel/{request_id}?mode=interrupt` — cancel (`aidream/api/routers/cancel.py`)
|
|
302
|
+
*
|
|
303
|
+
* Response headers arrive before the body: `X-Conversation-ID` and
|
|
304
|
+
* `X-Request-ID` are surfaced on the run handle immediately. `X-Request-ID`
|
|
305
|
+
* is the ONLY id the server accepts for cancel — a client-local id means
|
|
306
|
+
* nothing to it.
|
|
307
|
+
*
|
|
308
|
+
* Host policy stays out: no retry, no store, no timeouts, no persistence
|
|
309
|
+
* (C10: no-persistence). Cancellation is the caller's `AbortSignal`; a client
|
|
310
|
+
* disconnect never stops server work (`detach_on_disconnect`).
|
|
311
|
+
*/
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Stable identity of the durable entity whose saved context owns a run —
|
|
315
|
+
* the server reloads the row and uses ITS scope (`ContextAnchor`,
|
|
316
|
+
* `aidream/services/conversation_context/scope.py`).
|
|
317
|
+
*/
|
|
318
|
+
interface MatrxContextAnchor {
|
|
319
|
+
resource_type: string;
|
|
320
|
+
resource_id: string;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Scope and source fields shared by every scoped request
|
|
324
|
+
* (`ScopedRequest` / `AcceptsInjectedScope` server-side). All optional here;
|
|
325
|
+
* the start request narrows `organization_id` to required.
|
|
326
|
+
*/
|
|
327
|
+
interface MatrxRequestScope {
|
|
328
|
+
organization_id?: string;
|
|
329
|
+
project_id?: string | null;
|
|
330
|
+
task_id?: string | null;
|
|
331
|
+
/** Active context-scope ids from the client's global picker (membership-validated server-side). */
|
|
332
|
+
scope_ids?: string[] | null;
|
|
333
|
+
/** Active scope-TYPE ids — a type-level selection with no specific scope chosen. */
|
|
334
|
+
active_scope_type_ids?: string[] | null;
|
|
335
|
+
context_anchor?: MatrxContextAnchor | null;
|
|
336
|
+
/** Stable application slug that initiated the request. */
|
|
337
|
+
source_app?: string | null;
|
|
338
|
+
/** Stable feature slug within the source application. */
|
|
339
|
+
source_feature?: string | null;
|
|
340
|
+
/** "user" = a person directly triggered this; "auto" = client automation; omit for API callers. */
|
|
341
|
+
initiation?: "user" | "auto" | null;
|
|
342
|
+
/** Specific connected desktop instance allowed to claim delegated local tools. */
|
|
343
|
+
target_instance_id?: string | null;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Fields shared by start/continue turn requests (tool injection, client
|
|
347
|
+
* capability envelope, context object). The complex bags (`tools`, `client`,
|
|
348
|
+
* `user`, `config_overrides`) are typed as JSON objects — their authoritative
|
|
349
|
+
* schemas are the server's Pydantic models and the generated API types;
|
|
350
|
+
* this package stays payload-agnostic about them by design.
|
|
351
|
+
*/
|
|
352
|
+
interface MatrxTurnFields {
|
|
353
|
+
/** What the human typed (string), or structured input parts. Never smuggle machine content here. */
|
|
354
|
+
user_input?: string | MatrxJsonValue[] | null;
|
|
355
|
+
/** Per-run model/config overrides (LLMParams shape). */
|
|
356
|
+
config_overrides?: MatrxJsonObject | null;
|
|
357
|
+
debug?: boolean;
|
|
358
|
+
/** Additive tool specs merged into the agent's resolved tool set. */
|
|
359
|
+
tools?: MatrxJsonObject[];
|
|
360
|
+
/** When set, becomes the agent's ENTIRE tool set for the turn. */
|
|
361
|
+
tools_replace?: MatrxJsonObject[] | null;
|
|
362
|
+
/** Client capability envelope (`ClientContext`). */
|
|
363
|
+
client?: MatrxJsonObject | null;
|
|
364
|
+
/** Per-request user-level tool inclusion/exclusion overrides. */
|
|
365
|
+
user?: MatrxJsonObject | null;
|
|
366
|
+
/** Per-route context object, free-form by design. */
|
|
367
|
+
context?: MatrxJsonObject;
|
|
368
|
+
writable_variables?: string[];
|
|
369
|
+
allow_context_create?: boolean;
|
|
370
|
+
/** Request-snapshot capture override (tri-state; omit for the platform default). */
|
|
371
|
+
snapshot?: boolean | null;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* `POST /ai/agents/{agent_id}` body (`AgentStartRequest` server-side).
|
|
375
|
+
* The conversation-start triple is required by construction; `organization_id`
|
|
376
|
+
* is required (the server 422s a blank one — it never manufactures an org).
|
|
377
|
+
* `stream` is not accepted here: this client is the streaming path and always
|
|
378
|
+
* sends `stream: true`.
|
|
379
|
+
*/
|
|
380
|
+
type MatrxAgentStartRequest = MatrxConversationStart & Omit<MatrxRequestScope, "organization_id"> & MatrxTurnFields & {
|
|
381
|
+
organization_id: string;
|
|
382
|
+
/** Variable name → value map filling the agent's declared variables. */
|
|
383
|
+
variables?: MatrxJsonObject | null;
|
|
384
|
+
/** Run the versions table row instead of the live agent row. */
|
|
385
|
+
is_version?: boolean;
|
|
386
|
+
max_iterations?: number;
|
|
387
|
+
max_retries_per_iteration?: number;
|
|
388
|
+
};
|
|
389
|
+
/** `POST /ai/conversations/{id}` body (`ConversationContinueRequest` server-side). */
|
|
390
|
+
type MatrxConversationContinueRequest = MatrxRequestScope & MatrxTurnFields & {
|
|
391
|
+
/** Re-run the conversation's current persisted state (recovery after a failed turn); omit `user_input`. */
|
|
392
|
+
retry?: boolean;
|
|
393
|
+
};
|
|
394
|
+
/** `POST /ai/cancel/{request_id}` response (`CancelResponse` server-side). */
|
|
395
|
+
interface MatrxCancelResponse {
|
|
396
|
+
status: string;
|
|
397
|
+
request_id: string;
|
|
398
|
+
spine_executions_signalled: string[];
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Runtime operations — the canonical reconnect & resume read surface of the
|
|
403
|
+
* execution spine, over the `MatrxTransport` port.
|
|
404
|
+
*
|
|
405
|
+
* Server truth (verified against aidream source,
|
|
406
|
+
* `aidream/api/routers/runtime_operations.py` + `aidream/services/runtime/
|
|
407
|
+
* reconnect.py`; mounted at bare `/runtime`):
|
|
408
|
+
* - `GET /runtime/operations/{request_id}` — identify by `X-Request-ID`
|
|
409
|
+
* - `GET /runtime/operations/by-link/{kind}/{id}` — identify by feature record
|
|
410
|
+
* - `GET /runtime/executions/{id}/events` — durable seq-cursored page
|
|
411
|
+
* - `GET /runtime/executions/{id}/events/stream` — SSE replay-then-follow,
|
|
412
|
+
* `id:` = per-tree seq, reconnect with `Last-Event-ID`
|
|
413
|
+
* - `POST /runtime/operations/{request_id}/rejoin` — replay + follow the
|
|
414
|
+
* ORIGINAL NDJSON response while its detached task is alive (409 when live
|
|
415
|
+
* delivery is unavailable — fall back to the durable lifecycle stream)
|
|
416
|
+
*
|
|
417
|
+
* The contract: identify → recover durable progress → follow live → re-query
|
|
418
|
+
* the final result from the feature's own record. Token text is deliberately
|
|
419
|
+
* never replayed on the lifecycle stream — that is what `/rejoin` is for.
|
|
420
|
+
*
|
|
421
|
+
* The SSE wire rides the package's own `stream/sse` kernel. This module owns
|
|
422
|
+
* ONE connection's semantics (frames → typed events, cursor advancement,
|
|
423
|
+
* terminal `end`); stall timers, retry budgets, and reconnect loops stay host
|
|
424
|
+
* policy — every yielded item carries the cursor the next attempt resumes from.
|
|
425
|
+
*/
|
|
426
|
+
|
|
427
|
+
/** `matrx_runtime.models.ExecutionStatus` — the only progress column. */
|
|
428
|
+
type MatrxRuntimeExecutionStatus = "pending" | "running" | "paused" | "waiting_input" | "completed" | "failed" | "cancelled";
|
|
429
|
+
/** One durable spine event on the wire (`OperationEvent`) — `seq` is the reconnect cursor. */
|
|
430
|
+
interface MatrxRuntimeOperationEvent {
|
|
431
|
+
seq: number | null;
|
|
432
|
+
/** Lifecycle vocabulary: created | started | paused | resumed | waiting_input | completed | failed | cancelled | checkpoint_saved | note. */
|
|
433
|
+
kind: string;
|
|
434
|
+
execution_id: string;
|
|
435
|
+
root_execution_id: string | null;
|
|
436
|
+
detail: MatrxJsonObject | null;
|
|
437
|
+
created_at: string | null;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* `useAgentRun` — the package's run/stream hook: start, continue, and cancel
|
|
442
|
+
* an agent run over an injected `MatrxTransport`, with the streamed state
|
|
443
|
+
* exposed as the parity-proven request projection
|
|
444
|
+
* (`@ai-matrx/agents/projection/request` — the ONE event interpreter).
|
|
445
|
+
*
|
|
446
|
+
* The hook owns the whole loop the hosts used to hand-roll: the streaming
|
|
447
|
+
* call, folding every NDJSON envelope through `projectAgentEvent`, terminal
|
|
448
|
+
* status/error interpretation, unmount/stale-run teardown, and server-side
|
|
449
|
+
* cancel by the run's `X-Request-ID` (the ONLY id the cancel route accepts).
|
|
450
|
+
* The host injects only the transport — typically the production
|
|
451
|
+
* `createMatrxTransport` from `@ai-matrx/agents/matrx`.
|
|
452
|
+
*/
|
|
453
|
+
|
|
454
|
+
type AgentRunPhase = "idle" | "starting" | "streaming" | "complete" | "error" | "cancelled";
|
|
455
|
+
interface UseAgentRunOptions {
|
|
456
|
+
/** The transport (or a per-run factory — resolved fresh at each start). */
|
|
457
|
+
transport: MatrxTransport | (() => MatrxTransport);
|
|
458
|
+
/** Stream-kernel knobs forwarded to every run (malformed-line hooks, read-ahead). */
|
|
459
|
+
streamOptions?: Omit<MatrxStreamCallOptions, "signal">;
|
|
460
|
+
/** Fired after every folded event with the fresh projection. */
|
|
461
|
+
onProjection?: (projection: AgentRequestProjection) => void;
|
|
462
|
+
/** Fired when a run fails, with the classified envelope. */
|
|
463
|
+
onError?: (error: MatrxCallError) => void;
|
|
464
|
+
}
|
|
465
|
+
interface UseAgentRun {
|
|
466
|
+
/** The lifecycle phase of the CURRENT run. */
|
|
467
|
+
phase: AgentRunPhase;
|
|
468
|
+
/** The live projection of the current run (null before the first start). */
|
|
469
|
+
projection: AgentRequestProjection | null;
|
|
470
|
+
/** Server-assigned `X-Request-ID` — feeds cancel and reconnect. */
|
|
471
|
+
requestId: string | null;
|
|
472
|
+
/** Server-assigned `X-Conversation-ID`. */
|
|
473
|
+
conversationId: string | null;
|
|
474
|
+
/** The classified failure of the current run, when phase is "error". */
|
|
475
|
+
error: MatrxCallError | null;
|
|
476
|
+
/** Start an agent run (`POST /ai/agents/{agent_id}`); resolves the final projection. */
|
|
477
|
+
start: (agentId: string, request: MatrxAgentStartRequest) => Promise<AgentRequestProjection>;
|
|
478
|
+
/** Continue a stored conversation (`POST /ai/conversations/{id}`); resolves the final projection. */
|
|
479
|
+
continueConversation: (conversationId: string, request: MatrxConversationContinueRequest) => Promise<AgentRequestProjection>;
|
|
480
|
+
/**
|
|
481
|
+
* Server-side cancel of the current run by its `X-Request-ID`.
|
|
482
|
+
* `mode: "interrupt"` = stop-and-fork. Resolves null when no run id is
|
|
483
|
+
* known yet. The stream stays open until the server ends it — everything
|
|
484
|
+
* already streamed persists.
|
|
485
|
+
*/
|
|
486
|
+
cancel: (mode?: "cancel" | "interrupt") => Promise<MatrxCancelResponse | null>;
|
|
487
|
+
/** Abort the in-flight fetch/stream locally (server work continues by design). */
|
|
488
|
+
abort: () => void;
|
|
489
|
+
/** Clear state back to idle (aborts any in-flight run first). */
|
|
490
|
+
reset: () => void;
|
|
491
|
+
}
|
|
492
|
+
declare function useAgentRun(options: UseAgentRunOptions): UseAgentRun;
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* `useFollowRuntimeOperation` — the reconnect follower as a hook: follow one
|
|
496
|
+
* runtime operation's durable lifecycle stream
|
|
497
|
+
* (`GET /runtime/executions/{id}/events/stream`, `@ai-matrx/agents/stream/sse`
|
|
498
|
+
* under the hood) with the FULL production reconnect policy built in —
|
|
499
|
+
* stall watchdog, bounded retry budget, `Last-Event-ID` cursor — via
|
|
500
|
+
* `followRuntimeOperationToEnd`. Tuning knobs are typed and default to the
|
|
501
|
+
* proven production values (45s stall, 60 × 2s budget).
|
|
502
|
+
*
|
|
503
|
+
* The host injects the transport and what each event MEANS (`onEvent`);
|
|
504
|
+
* everything else is package policy.
|
|
505
|
+
*/
|
|
506
|
+
|
|
507
|
+
interface UseFollowRuntimeOperationOptions {
|
|
508
|
+
/** The transport (typically the production `createMatrxTransport`). */
|
|
509
|
+
transport: MatrxTransport | (() => MatrxTransport);
|
|
510
|
+
/** The execution to follow — null/undefined idles the hook. */
|
|
511
|
+
executionId: string | null | undefined;
|
|
512
|
+
/** Resume cursor — the operation view's `last_event_seq` (0 = from start). */
|
|
513
|
+
lastEventSeq?: number;
|
|
514
|
+
/** Gate — false tears the follow down (default true when an id is set). */
|
|
515
|
+
enabled?: boolean;
|
|
516
|
+
/** Stall watchdog, ms. Default 45_000. */
|
|
517
|
+
stallTimeoutMs?: number;
|
|
518
|
+
/** Consecutive-failure budget. Default 60. */
|
|
519
|
+
reconnectLimit?: number;
|
|
520
|
+
/** Delay between attempts, ms. Default 2_000. */
|
|
521
|
+
reconnectDelayMs?: number;
|
|
522
|
+
/** Fired per durable spine event (lifecycle transitions + notes). */
|
|
523
|
+
onEvent?: (event: MatrxRuntimeOperationEvent, seq: number | null) => void;
|
|
524
|
+
/** Fired once when the follow settles (server `end`, exhausted budget, or teardown). */
|
|
525
|
+
onSettled?: (result: {
|
|
526
|
+
ended: boolean;
|
|
527
|
+
status: MatrxRuntimeExecutionStatus | null;
|
|
528
|
+
}) => void;
|
|
529
|
+
}
|
|
530
|
+
interface UseFollowRuntimeOperation {
|
|
531
|
+
/** True while a follow loop is live for the current execution. */
|
|
532
|
+
following: boolean;
|
|
533
|
+
/** True once the server sent the terminal `end` frame. */
|
|
534
|
+
ended: boolean;
|
|
535
|
+
/** The root status from the `end` frame, when ended. */
|
|
536
|
+
status: MatrxRuntimeExecutionStatus | null;
|
|
537
|
+
}
|
|
538
|
+
declare function useFollowRuntimeOperation(options: UseFollowRuntimeOperationOptions): UseFollowRuntimeOperation;
|
|
539
|
+
|
|
540
|
+
export { type AgentRunPhase, type UseAgentRun, type UseAgentRunOptions, type UseFollowRuntimeOperation, type UseFollowRuntimeOperationOptions, useAgentRun, useFollowRuntimeOperation };
|