@ai-matrx/agents 0.22.0 → 0.24.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/content-transfer/index.cjs +33 -33
  3. package/dist/content-transfer/index.cjs.map +1 -1
  4. package/dist/content-transfer/index.d.cts +1 -1
  5. package/dist/content-transfer/index.d.ts +1 -1
  6. package/dist/content-transfer/index.js +33 -33
  7. package/dist/content-transfer/index.js.map +1 -1
  8. package/dist/content-transfer/react/index.cjs +33 -33
  9. package/dist/content-transfer/react/index.cjs.map +1 -1
  10. package/dist/content-transfer/react/index.js +33 -33
  11. package/dist/content-transfer/react/index.js.map +1 -1
  12. package/dist/index.cjs +404 -131
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +404 -131
  17. package/dist/index.js.map +1 -1
  18. package/dist/mandates/index.cjs +2 -2
  19. package/dist/mandates/index.cjs.map +1 -1
  20. package/dist/mandates/index.d.cts +4 -4
  21. package/dist/mandates/index.d.ts +4 -4
  22. package/dist/mandates/index.js +2 -2
  23. package/dist/mandates/index.js.map +1 -1
  24. package/dist/matrx/index.cjs +404 -131
  25. package/dist/matrx/index.cjs.map +1 -1
  26. package/dist/matrx/index.d.cts +242 -4
  27. package/dist/matrx/index.d.ts +242 -4
  28. package/dist/matrx/index.js +404 -131
  29. package/dist/matrx/index.js.map +1 -1
  30. package/dist/react/index.cjs +41 -41
  31. package/dist/react/index.cjs.map +1 -1
  32. package/dist/react/index.js +41 -41
  33. package/dist/react/index.js.map +1 -1
  34. package/mandates/snapshots/keys.0.23.0.json +652 -0
  35. package/mandates/snapshots/keys.0.24.0.json +652 -0
  36. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts","../stream/ndjson.ts","../stream/sse.ts","../presentation/result.ts","../projection/request.ts","../projection/workflow.ts","../matrx/transport.ts","../matrx/client.ts","../matrx/org-context.ts","../matrx/protocol.ts","../matrx/conversation.ts","../matrx/internal.ts","../matrx/run.ts","../matrx/operations.ts","../matrx/tools.ts","../variables/reference-roles.ts","../variables/run-inputs.ts"],"sourcesContent":["export * from \"./stream/ndjson\";\nexport * from \"./stream/sse\";\nexport * from \"./presentation/result\";\nexport * from \"./projection/request\";\nexport * from \"./projection/workflow\";\nexport * from \"./matrx/index\";\nexport * from \"./variables/index\";\n","/**\n * Canonical AI Matrx NDJSON wire kernel.\n *\n * This module is deliberately independent of React, Redux, Next.js, Supabase,\n * and generated application types. Every Matrx client uses it to turn the\n * backend's byte stream into the same normalized `{ event, data }` envelopes.\n * Host runtimes remain responsible for HTTP/auth errors and for deciding what\n * each event means in their state model.\n */\n\nexport interface MatrxStreamEnvelope<TData = unknown> {\n event: string;\n /** Immutable emitter segment; transport sequence is scoped to this id. */\n stream_id?: string;\n data: TData;\n /** Monotonic transport sequence from full envelopes, when supplied. */\n stream_seq?: number;\n}\n\nexport interface MatrxNdjsonIssue {\n line: string;\n error: unknown;\n /** One-based physical NDJSON line number. */\n lineNumber: number;\n /** True when an unterminated trailing fragment was parsed by `finish()`. */\n atCompletion: boolean;\n}\n\nexport interface MatrxStreamEnvelopeObservation {\n /** Exact parsed JSON value before compact/full normalization. */\n raw: unknown;\n envelope: MatrxStreamEnvelope;\n line: string;\n lineNumber: number;\n atCompletion: boolean;\n}\n\nexport interface MatrxNdjsonFramerOptions {\n /** Malformed JSON is non-fatal, but it must never disappear silently. */\n onMalformedLine?: (issue: MatrxNdjsonIssue) => void;\n /** Valid JSON with no recognized Matrx event envelope is also non-fatal. */\n onUnknownEnvelope?: (value: unknown) => void;\n /** Observe every valid envelope without changing or consuming it. */\n onValidEnvelope?: (observation: MatrxStreamEnvelopeObservation) => void;\n}\n\nexport interface ReadMatrxNdjsonOptions extends MatrxNdjsonFramerOptions {\n signal?: AbortSignal;\n /** Maximum normalized events read ahead of the iterator consumer. */\n maxReadAhead?: number;\n}\n\nexport interface MatrxNdjsonFramer {\n /** Push a text fragment. Fragments may split JSON tokens or line endings. */\n pushText(fragment: string): MatrxStreamEnvelope[];\n /** Push a byte fragment. UTF-8 code points may span calls. */\n pushBytes(fragment: Uint8Array): MatrxStreamEnvelope[];\n /** Parse the final unterminated line and flush any pending UTF-8 bytes. */\n finish(): MatrxStreamEnvelope[];\n}\n\ntype QueueItem =\n | { kind: \"event\"; value: MatrxStreamEnvelope }\n | { kind: \"error\"; error: unknown }\n | { kind: \"done\" };\n\nexport const DEFAULT_MATRX_NDJSON_READ_AHEAD = 64;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize both supported Matrx wire shapes:\n *\n * - full: `{ \"event\": \"chunk\", \"data\": { \"text\": \"...\" } }`\n * - compact chunk: `{ \"e\": \"c\", \"t\": \"...\" }`\n * - compact reasoning: `{ \"e\": \"r\", \"t\": \"...\" }`\n */\nexport function normalizeMatrxStreamEnvelope(\n value: unknown,\n): MatrxStreamEnvelope | null {\n if (!isRecord(value)) return null;\n\n if (typeof value.event === \"string\") {\n const streamSeq =\n typeof value.stream_seq === \"number\" && Number.isFinite(value.stream_seq)\n ? value.stream_seq\n : undefined;\n const streamId = typeof value.stream_id === \"string\" ? value.stream_id : undefined;\n return {\n event: value.event,\n data: value.data,\n ...(streamId === undefined ? {} : { stream_id: streamId }),\n ...(streamSeq === undefined ? {} : { stream_seq: streamSeq }),\n };\n }\n if (value.e === \"c\" && typeof value.t === \"string\") {\n const streamId = typeof value.stream_id === \"string\" ? value.stream_id : undefined;\n const streamSeq =\n typeof value.stream_seq === \"number\" && Number.isFinite(value.stream_seq)\n ? value.stream_seq\n : undefined;\n return {\n event: \"chunk\",\n data: { text: value.t },\n ...(streamId === undefined ? {} : { stream_id: streamId }),\n ...(streamSeq === undefined ? {} : { stream_seq: streamSeq }),\n };\n }\n if (value.e === \"r\" && typeof value.t === \"string\") {\n const streamId = typeof value.stream_id === \"string\" ? value.stream_id : undefined;\n const streamSeq =\n typeof value.stream_seq === \"number\" && Number.isFinite(value.stream_seq)\n ? value.stream_seq\n : undefined;\n return {\n event: \"reasoning_chunk\",\n data: { text: value.t },\n ...(streamId === undefined ? {} : { stream_id: streamId }),\n ...(streamSeq === undefined ? {} : { stream_seq: streamSeq }),\n };\n }\n return null;\n}\n\n/**\n * Create the transport-independent NDJSON framer used by the stream reader.\n * Browser extensions, desktop bridges, WebSockets, and tests can feed it\n * fragmented strings or bytes without constructing a `ReadableStream`.\n */\nexport function createMatrxNdjsonFramer(\n options: MatrxNdjsonFramerOptions = {},\n): MatrxNdjsonFramer {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let lineNumber = 0;\n let finished = false;\n\n const assertOpen = (): void => {\n if (finished) throw new Error(\"Matrx NDJSON framer is already finished\");\n };\n\n const parseLine = (\n line: string,\n atCompletion: boolean,\n ): MatrxStreamEnvelope | null => {\n const currentLineNumber = ++lineNumber;\n const trimmed = line.trim();\n if (!trimmed) return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed) as unknown;\n } catch (error) {\n options.onMalformedLine?.({\n line: trimmed,\n error,\n lineNumber: currentLineNumber,\n atCompletion,\n });\n return null;\n }\n\n const envelope = normalizeMatrxStreamEnvelope(parsed);\n if (!envelope) {\n options.onUnknownEnvelope?.(parsed);\n return null;\n }\n options.onValidEnvelope?.({\n raw: parsed,\n envelope,\n line: trimmed,\n lineNumber: currentLineNumber,\n atCompletion,\n });\n return envelope;\n };\n\n const pushDecodedText = (fragment: string): MatrxStreamEnvelope[] => {\n buffer += fragment;\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n const envelopes: MatrxStreamEnvelope[] = [];\n for (const line of lines) {\n const envelope = parseLine(line, false);\n if (envelope) envelopes.push(envelope);\n }\n return envelopes;\n };\n\n return {\n pushText(fragment) {\n assertOpen();\n // Flush any pending byte fragment before switching to explicit text.\n return pushDecodedText(decoder.decode() + fragment);\n },\n pushBytes(fragment) {\n assertOpen();\n return pushDecodedText(decoder.decode(fragment, { stream: true }));\n },\n finish() {\n assertOpen();\n finished = true;\n const envelopes = pushDecodedText(decoder.decode());\n if (buffer.length > 0) {\n const envelope = parseLine(buffer, true);\n buffer = \"\";\n if (envelope) envelopes.push(envelope);\n }\n return envelopes;\n },\n };\n}\n\nfunction readAheadLimit(value: number | undefined): number {\n const limit = value ?? DEFAULT_MATRX_NDJSON_READ_AHEAD;\n if (!Number.isSafeInteger(limit) || limit < 1) {\n throw new RangeError(\"maxReadAhead must be a positive safe integer\");\n }\n return limit;\n}\n\n/**\n * Read and normalize a Matrx NDJSON response body with bounded background\n * read-ahead. Consumer work does not stall the network until `maxReadAhead`\n * complete events are waiting; the bound prevents an abandoned or blocked\n * consumer from growing memory without limit.\n */\nexport async function* readMatrxNdjsonStream(\n body: ReadableStream<Uint8Array>,\n options: ReadMatrxNdjsonOptions = {},\n): AsyncGenerator<MatrxStreamEnvelope, void, undefined> {\n const maxReadAhead = readAheadLimit(options.maxReadAhead);\n const queue: QueueItem[] = [];\n let queuedEventCount = 0;\n let wakeConsumer: (() => void) | null = null;\n let wakeProducer: (() => void) | null = null;\n let readerFinished = false;\n let consumerClosed = false;\n\n const wakeWaitingConsumer = (): void => {\n const wake = wakeConsumer;\n wakeConsumer = null;\n wake?.();\n };\n const wakeWaitingProducer = (): void => {\n const wake = wakeProducer;\n wakeProducer = null;\n wake?.();\n };\n const enqueueTerminal = (item: QueueItem): void => {\n if (consumerClosed) return;\n queue.push(item);\n wakeWaitingConsumer();\n };\n const enqueueEvent = async (value: MatrxStreamEnvelope): Promise<boolean> => {\n while (\n queuedEventCount >= maxReadAhead &&\n !consumerClosed &&\n !options.signal?.aborted\n ) {\n await new Promise<void>((resolve) => {\n wakeProducer = resolve;\n });\n }\n if (consumerClosed || options.signal?.aborted) return false;\n queue.push({ kind: \"event\", value });\n queuedEventCount += 1;\n wakeWaitingConsumer();\n return true;\n };\n const waitForReadCapacity = async (): Promise<boolean> => {\n while (\n queuedEventCount >= maxReadAhead &&\n !consumerClosed &&\n !options.signal?.aborted\n ) {\n await new Promise<void>((resolve) => {\n wakeProducer = resolve;\n });\n }\n return !consumerClosed && !options.signal?.aborted;\n };\n\n const reader = body.getReader();\n const framer = createMatrxNdjsonFramer(options);\n\n const onAbort = (): void => {\n wakeWaitingProducer();\n wakeWaitingConsumer();\n void reader.cancel(options.signal?.reason).catch(() => undefined);\n };\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (options.signal?.aborted) onAbort();\n\n const readerPromise = (async (): Promise<void> => {\n try {\n while (!options.signal?.aborted && !consumerClosed) {\n if (!(await waitForReadCapacity())) return;\n const { value, done } = await reader.read();\n if (done) break;\n for (const envelope of framer.pushBytes(value)) {\n if (!(await enqueueEvent(envelope))) return;\n }\n }\n\n if (!options.signal?.aborted && !consumerClosed) {\n for (const envelope of framer.finish()) {\n if (!(await enqueueEvent(envelope))) return;\n }\n }\n } catch (error) {\n const aborted =\n options.signal?.aborted ||\n consumerClosed ||\n (error instanceof Error && error.name === \"AbortError\");\n if (!aborted) enqueueTerminal({ kind: \"error\", error });\n } finally {\n readerFinished = true;\n reader.releaseLock();\n enqueueTerminal({ kind: \"done\" });\n }\n })();\n\n try {\n while (true) {\n if (queue.length === 0) {\n if (options.signal?.aborted || readerFinished) return;\n await new Promise<void>((resolve) => {\n wakeConsumer = resolve;\n });\n }\n\n const item = queue.shift();\n if (item?.kind === \"event\") queuedEventCount -= 1;\n wakeWaitingProducer();\n if (!item || item.kind === \"done\") return;\n if (item.kind === \"error\") throw item.error;\n yield item.value;\n }\n } finally {\n consumerClosed = true;\n wakeWaitingProducer();\n wakeWaitingConsumer();\n options.signal?.removeEventListener(\"abort\", onAbort);\n if (!readerFinished) {\n await reader.cancel().catch(() => undefined);\n }\n await readerPromise;\n }\n}\n","/**\n * `@ai-matrx/agents/stream/sse` — the Matrx SSE frame kernel.\n *\n * Two Matrx clients hand-rolled the identical `text/event-stream` framing —\n * the same separator regex, the same field parsing, the same CRLF incident —\n * for the durable rejoin endpoints (`/runtime/.../events/stream`,\n * `/runs/.../events/stream`). This module is that framing extracted ONCE, as a\n * pure incremental parser, so a host keeps only what is genuinely host policy:\n * the fetch, the stall timer, the retry budget, and what each event MEANS.\n *\n * Contract, mirroring `stream/ndjson`:\n * - Pure and effect-free: no fetch, no timers, no globals. Importing this\n * module performs no work.\n * - Incremental across arbitrary chunk boundaries: a frame split anywhere —\n * mid-line, mid-separator, mid-UTF-8 when using the byte reader — parses\n * identically to one delivered whole.\n * - All three SSE line terminators (`\\r\\n`, `\\n`, `\\r`) and all three frame\n * separators are handled — the CRLF-vs-LF divergence that bit production is\n * covered by construction and by test.\n * - Comment-only frames (heartbeats, `:` lines) ARE emitted (with\n * `data === null`) because hosts use any parsed frame as liveness proof to\n * reset stall timers and retry budgets. Frames with data join multi-line\n * `data:` fields with `\\n` per the SSE spec.\n * - `id:` is surfaced raw AND, when it is a safe integer, as `seq` — the\n * `Last-Event-ID` cursor both Matrx rejoin endpoints use for durable replay.\n * Cursor ADVANCEMENT (`seq > cursor`) stays host-side, next to the retry.\n */\n\nexport interface MatrxSseFrame {\n /** `event:` field; the SSE default \"message\" when absent. */\n event: string;\n /** `id:` field, raw, when present. */\n id: string | null;\n /**\n * `id:` parsed as a non-negative safe integer, else null. Matrx rejoin\n * streams use integer ids as the `Last-Event-ID` replay cursor.\n */\n seq: number | null;\n /**\n * Joined `data:` lines (`\\n`-separated per spec), or null for a frame with\n * no data field at all (e.g. a comment-only heartbeat). An empty-string\n * data field is `\"\"`, not null.\n */\n data: string | null;\n}\n\nconst FRAME_SEPARATOR = /\\r\\n\\r\\n|\\n\\n|\\r\\r/;\nconst LINE_SEPARATOR = /\\r\\n|\\n|\\r/;\n\n/** Parse ONE complete frame's text (no trailing separator). */\nexport function parseMatrxSseFrame(frame: string): MatrxSseFrame {\n let event = \"message\";\n let id: string | null = null;\n const dataLines: string[] = [];\n let sawData = false;\n\n for (const line of frame.split(LINE_SEPARATOR)) {\n if (line.startsWith(\":\")) continue;\n if (line.startsWith(\"event:\")) event = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) {\n sawData = true;\n dataLines.push(line.slice(5).replace(/^ /, \"\"));\n } else if (line.startsWith(\"id:\")) id = line.slice(3).trim();\n }\n\n const seqCandidate = id !== null && id !== \"\" ? Number(id) : NaN;\n const seq =\n Number.isSafeInteger(seqCandidate) && seqCandidate >= 0\n ? seqCandidate\n : null;\n\n return { event, id, seq, data: sawData ? dataLines.join(\"\\n\") : null };\n}\n\nexport interface MatrxSseFramer {\n /** Feed a decoded text chunk; returns every frame it completed. */\n push(chunk: string): MatrxSseFrame[];\n /**\n * Signal end of input. A non-empty trailing buffer is an UNTERMINATED frame:\n * per the SSE spec it was never dispatched, so it is returned separately for\n * the host to treat as diagnostic, never as a delivered event.\n */\n flush(): { incomplete: string | null };\n}\n\n/** Incremental SSE framer over already-decoded text. */\nexport function createMatrxSseFramer(): MatrxSseFramer {\n let buffer = \"\";\n return {\n push(chunk: string): MatrxSseFrame[] {\n buffer += chunk;\n const frames: MatrxSseFrame[] = [];\n for (;;) {\n const sep = FRAME_SEPARATOR.exec(buffer);\n if (sep === null) break;\n // A lone trailing `\\r` could be the first half of `\\r\\n\\r\\n`'s final\n // newline — but the separator regex only matched what is already\n // complete, so the slice below is always safe.\n const frame = buffer.slice(0, sep.index);\n buffer = buffer.slice(sep.index + sep[0].length);\n frames.push(parseMatrxSseFrame(frame));\n }\n return frames;\n },\n flush() {\n const rest = buffer;\n buffer = \"\";\n return { incomplete: rest.length > 0 ? rest : null };\n },\n };\n}\n\nexport interface ReadMatrxSseOptions {\n /**\n * Called with any unterminated trailing text at stream end (a frame the\n * server never finished — diagnostic, not a delivered event).\n */\n onIncomplete?: (text: string) => void;\n}\n\n/**\n * Async-iterate the frames of a byte stream (e.g. `response.body`), handling\n * split UTF-8 across chunk boundaries. Cancellation follows the reader: abort\n * the fetch and the iterator ends; a transport error after complete frames\n * were yielded surfaces AFTER those frames, with its original cause.\n */\nexport async function* readMatrxSseStream(\n stream: ReadableStream<Uint8Array>,\n options: ReadMatrxSseOptions = {},\n): AsyncGenerator<MatrxSseFrame, void, undefined> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const framer = createMatrxSseFramer();\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n const frames = framer.push(decoder.decode(value, { stream: true }));\n for (const frame of frames) yield frame;\n }\n const tail = framer.push(decoder.decode());\n for (const frame of tail) yield frame;\n const { incomplete } = framer.flush();\n if (incomplete !== null) options.onIncomplete?.(incomplete);\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Creator-facing projection of an agent execution result.\n *\n * Provider reasoning blocks and their signatures are replay material, not\n * workflow data. The execution engine must retain them so a later turn can be\n * continued correctly, but no result renderer, JSON tab, clipboard export, or\n * Content IR classifier should receive them as displayable values.\n *\n * This is a pure copy-on-write projection: values without private material\n * keep their original reference, while affected branches are cloned. Never\n * feed the projected value back into execution or persistence.\n */\n\nconst PRIVATE_REASONING_TYPES: ReadonlySet<string> = new Set([\n \"thinking\",\n \"redacted_thinking\",\n \"reasoning\",\n]);\n\nconst PRIVATE_PROVIDER_KEYS: ReadonlySet<string> = new Set([\n \"thought_signature\",\n \"thoughtSignature\",\n \"google_thought_signature\",\n \"anthropic_signature\",\n \"encrypted_content\",\n \"signature_encoding\",\n]);\n\nconst SIGNATURE_PROVIDERS: ReadonlySet<string> = new Set([\n \"anthropic\",\n \"google\",\n \"openai\",\n]);\n\nconst OPAQUE_SIGNATURE_MIN_LENGTH = 200;\nconst OMIT = Symbol(\"omit-provider-private-value\");\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPrivateReasoningBlock(value: Record<string, unknown>): boolean {\n return (\n typeof value.type === \"string\" &&\n PRIVATE_REASONING_TYPES.has(value.type.toLowerCase())\n );\n}\n\nfunction isPrivateProviderKey(\n key: string,\n value: unknown,\n parent: Record<string, unknown>,\n): boolean {\n if (PRIVATE_PROVIDER_KEYS.has(key)) return true;\n if (key !== \"signature\") return false;\n\n const provider =\n typeof parent.provider === \"string\" ? parent.provider.toLowerCase() : \"\";\n return (\n \"signature_encoding\" in parent ||\n SIGNATURE_PROVIDERS.has(provider) ||\n (typeof value === \"string\" && value.length >= OPAQUE_SIGNATURE_MIN_LENGTH)\n );\n}\n\nfunction project(value: unknown): unknown | typeof OMIT {\n if (Array.isArray(value)) {\n let changed = false;\n const output: unknown[] = [];\n for (const item of value) {\n const projected = project(item);\n if (projected === OMIT) {\n changed = true;\n continue;\n }\n if (projected !== item) changed = true;\n output.push(projected);\n }\n return changed ? output : value;\n }\n\n if (!isRecord(value)) return value;\n if (isPrivateReasoningBlock(value)) return OMIT;\n\n let changed = false;\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n if (isPrivateProviderKey(key, child, value)) {\n changed = true;\n continue;\n }\n const projected = project(child);\n if (projected === OMIT) {\n changed = true;\n continue;\n }\n if (projected !== child) changed = true;\n output[key] = projected;\n }\n return changed ? output : value;\n}\n\n/**\n * Remove provider-private reasoning material from a value crossing a\n * Creator-facing presentation or export boundary.\n */\nexport function projectAgentResultForDisplay(value: unknown): unknown {\n const projected = project(value);\n return projected === OMIT ? null : projected;\n}\n","export type AgentProjectionStatus =\n | \"pending\"\n | \"streaming\"\n | \"awaiting-tools\"\n | \"complete\"\n | \"error\"\n | \"cancelled\";\n\nexport interface AgentProjectionOperation {\n operationId: string;\n operation: string;\n parentOperationId: string | null;\n status: \"active\" | \"success\" | \"failed\" | \"cancelled\";\n metadata: Record<string, unknown> | null;\n result: Record<string, unknown> | null;\n}\n\nexport interface AgentProjectionTool {\n callId: string;\n toolName: string;\n status:\n | \"started\"\n | \"progress\"\n | \"step\"\n | \"preview\"\n | \"completed\"\n | \"error\"\n | \"delegated\";\n message: string | null;\n data: Record<string, unknown> | null;\n}\n\nexport interface AgentProjectionRenderBlock {\n blockId: string;\n blockIndex: number;\n type: string;\n status: \"streaming\" | \"complete\" | \"error\";\n content: string | null;\n data: Record<string, unknown> | null;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface AgentRequestProjection {\n requestId: string;\n conversationId: string | null;\n status: AgentProjectionStatus;\n answer: string;\n reasoning: string;\n reasoningActive: boolean;\n phase: string | null;\n phaseHistory: string[];\n operations: Record<string, AgentProjectionOperation>;\n tools: Record<string, AgentProjectionTool>;\n renderBlocks: Record<string, AgentProjectionRenderBlock>;\n renderBlockOrder: string[];\n completion: Record<string, unknown> | null;\n error: Record<string, unknown> | null;\n lastTransportSeq: number;\n transportStreamId: string | null;\n eventCount: number;\n}\n\nexport interface AgentProjectionEvent {\n event: string;\n data?: unknown;\n stream_seq?: number;\n stream_id?: string;\n}\n\nconst asRecord = (value: unknown): Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n\nconst asString = (value: unknown): string | null =>\n typeof value === \"string\" ? value : null;\n\nconst asNumber = (value: unknown): number | null =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\nexport function createAgentRequestProjection(input: {\n requestId: string;\n conversationId?: string | null;\n}): AgentRequestProjection {\n return {\n requestId: input.requestId,\n conversationId: input.conversationId ?? null,\n status: \"pending\",\n answer: \"\",\n reasoning: \"\",\n reasoningActive: false,\n phase: null,\n phaseHistory: [],\n operations: {},\n tools: {},\n renderBlocks: {},\n renderBlockOrder: [],\n completion: null,\n error: null,\n lastTransportSeq: 0,\n transportStreamId: null,\n eventCount: 0,\n };\n}\n\nfunction toolStatus(event: string): AgentProjectionTool[\"status\"] {\n switch (event) {\n case \"tool_started\":\n return \"started\";\n case \"tool_step\":\n return \"step\";\n case \"tool_result_preview\":\n return \"preview\";\n case \"tool_completed\":\n return \"completed\";\n case \"tool_error\":\n return \"error\";\n case \"tool_delegated\":\n return \"delegated\";\n default:\n return \"progress\";\n }\n}\n\nexport function projectAgentEvent(\n current: AgentRequestProjection,\n event: AgentProjectionEvent,\n): AgentRequestProjection {\n const streamSeq = asNumber(event.stream_seq);\n const streamId = asString(event.stream_id);\n const sameSegment = streamId === null || streamId === current.transportStreamId;\n if (\n sameSegment &&\n streamSeq !== null &&\n streamSeq <= current.lastTransportSeq\n ) {\n return current;\n }\n\n const data = asRecord(event.data);\n const next: AgentRequestProjection = {\n ...current,\n status: current.status === \"pending\" ? \"streaming\" : current.status,\n lastTransportSeq:\n streamSeq === null\n ? current.lastTransportSeq\n : sameSegment\n ? Math.max(current.lastTransportSeq, streamSeq)\n : streamSeq,\n transportStreamId: streamId ?? current.transportStreamId,\n eventCount: current.eventCount + 1,\n };\n\n switch (event.event) {\n case \"chunk\": {\n const text = asString(data.text);\n return text === null ? next : { ...next, answer: current.answer + text };\n }\n case \"reasoning_chunk\": {\n const text = asString(data.text);\n return text === null\n ? next\n : {\n ...next,\n reasoning: current.reasoning + text,\n reasoningActive: true,\n };\n }\n case \"reasoning\":\n return {\n ...next,\n reasoningActive: data.state === \"started\",\n };\n case \"phase\": {\n const phase = asString(data.phase);\n if (phase === null) return next;\n return {\n ...next,\n phase,\n phaseHistory: [...current.phaseHistory, phase],\n };\n }\n case \"init\": {\n const operationId = asString(data.operation_id);\n const operation = asString(data.operation);\n if (operationId === null || operation === null) return next;\n return {\n ...next,\n operations: {\n ...current.operations,\n [operationId]: {\n operationId,\n operation,\n parentOperationId: asString(data.parent_operation_id),\n status: \"active\",\n metadata: Object.keys(asRecord(data.metadata)).length\n ? asRecord(data.metadata)\n : null,\n result: null,\n },\n },\n };\n }\n case \"completion\": {\n const operationId = asString(data.operation_id);\n const operation = asString(data.operation);\n const rawStatus = asString(data.status);\n const status: AgentProjectionOperation[\"status\"] =\n rawStatus === \"failed\" || rawStatus === \"cancelled\"\n ? rawStatus\n : \"success\";\n const result = asRecord(data.result);\n const operations = operationId\n ? {\n ...current.operations,\n [operationId]: {\n ...(current.operations[operationId] ?? {\n operationId,\n operation: operation ?? \"unknown\",\n parentOperationId: null,\n metadata: null,\n }),\n status,\n result,\n },\n }\n : current.operations;\n if (operation === \"user_request\") {\n return {\n ...next,\n operations,\n completion: data,\n status:\n status === \"success\"\n ? \"complete\"\n : status === \"cancelled\"\n ? \"cancelled\"\n : \"error\",\n };\n }\n return { ...next, operations };\n }\n case \"tool_event\": {\n const callId = asString(data.call_id);\n const toolName = asString(data.tool_name);\n const lifecycle = asString(data.event);\n if (callId === null || toolName === null || lifecycle === null) return next;\n const status = toolStatus(lifecycle);\n return {\n ...next,\n status:\n status === \"delegated\"\n ? \"awaiting-tools\"\n : status === \"completed\" || status === \"error\"\n ? \"streaming\"\n : next.status,\n tools: {\n ...current.tools,\n [callId]: {\n callId,\n toolName,\n status,\n message: asString(data.message),\n data: Object.keys(asRecord(data.data)).length ? asRecord(data.data) : null,\n },\n },\n };\n }\n case \"render_block\": {\n const blockId = asString(data.blockId);\n const blockIndex = asNumber(data.blockIndex);\n const type = asString(data.type);\n if (blockId === null || blockIndex === null || type === null) return next;\n const alreadyKnown = Object.hasOwn(current.renderBlocks, blockId);\n return {\n ...next,\n renderBlocks: {\n ...current.renderBlocks,\n [blockId]: {\n blockId,\n blockIndex,\n type,\n status:\n data.status === \"complete\" || data.status === \"error\"\n ? data.status\n : \"streaming\",\n content: asString(data.content),\n data: Object.keys(asRecord(data.data)).length ? asRecord(data.data) : null,\n metadata: Object.keys(asRecord(data.metadata)).length\n ? asRecord(data.metadata)\n : null,\n },\n },\n renderBlockOrder: alreadyKnown\n ? current.renderBlockOrder\n : [...current.renderBlockOrder, blockId],\n };\n }\n case \"error\":\n return { ...next, status: \"error\", error: data };\n case \"end\":\n return {\n ...next,\n status:\n current.status === \"error\" || current.status === \"cancelled\"\n ? current.status\n : \"complete\",\n reasoningActive: false,\n };\n case \"data\": {\n const conversationId =\n data.type === \"conversation_id\" ? asString(data.conversation_id) : null;\n return conversationId === null ? next : { ...next, conversationId };\n }\n default:\n return next;\n }\n}\n\nexport function projectAgentEvents(\n initial: AgentRequestProjection,\n events: readonly AgentProjectionEvent[],\n): AgentRequestProjection {\n return events.reduce(projectAgentEvent, initial);\n}\n","import type { AgentProjectionRenderBlock } from \"./request\";\n\nexport interface WorkflowNodeStreamEvent {\n run_id: string;\n node_id?: string | null;\n kind:\n | \"chunk\"\n | \"reasoning\"\n | \"phase\"\n | \"tool\"\n | \"warning\"\n | \"record_update\"\n | \"resource_changed\"\n | \"render_block\";\n delta: string;\n stream_seq: number;\n ts: string;\n chunks_received: number;\n chars_streamed: number;\n frame_id?: string | null;\n frame_index?: number;\n frame_count?: number;\n block_shadowed?: boolean;\n}\n\nexport interface WorkflowProjectionLimits {\n maxOpenFrameSets: number;\n maxFramesPerBlock: number;\n maxBytesPerBlock: number;\n}\n\nexport const DEFAULT_WORKFLOW_PROJECTION_LIMITS: Readonly<WorkflowProjectionLimits> = {\n maxOpenFrameSets: 32,\n maxFramesPerBlock: 256,\n maxBytesPerBlock: 1_048_576,\n};\n\nexport interface WorkflowRenderFrameSet {\n frameCount: number;\n slices: Record<number, string>;\n byteLength: number;\n}\n\nexport type WorkflowRenderBlockIssueCode =\n | \"invalid_frame_metadata\"\n | \"frame_count_mismatch\"\n | \"open_frame_limit_exceeded\"\n | \"frame_limit_exceeded\"\n | \"byte_limit_exceeded\"\n | \"malformed_json\"\n | \"invalid_render_block\";\n\nexport interface WorkflowRenderBlockIssue {\n code: WorkflowRenderBlockIssueCode;\n frameId: string | null;\n streamSeq: number;\n message: string;\n}\n\nexport interface WorkflowNodeProjection {\n runId: string;\n nodeId: string;\n answer: string;\n reasoning: string;\n blockShadowed: boolean;\n renderBlocks: Record<string, AgentProjectionRenderBlock>;\n renderBlockOrder: string[];\n openFrames: Record<string, WorkflowRenderFrameSet>;\n limits: WorkflowProjectionLimits;\n lastRenderBlockIssue: WorkflowRenderBlockIssue | null;\n chunksReceived: number;\n charsStreamed: number;\n lastStreamingTs: string | null;\n lastPhase: string | null;\n lastTool: string | null;\n lastWarning: string | null;\n lastTransportSeq: number;\n}\n\nfunction positiveSafeInteger(name: string, value: number): number {\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new RangeError(`${name} must be a positive safe integer`);\n }\n return value;\n}\n\nfunction resolveLimits(\n limits: Partial<WorkflowProjectionLimits> | undefined,\n): WorkflowProjectionLimits {\n return {\n maxOpenFrameSets: positiveSafeInteger(\n \"maxOpenFrameSets\",\n limits?.maxOpenFrameSets ??\n DEFAULT_WORKFLOW_PROJECTION_LIMITS.maxOpenFrameSets,\n ),\n maxFramesPerBlock: positiveSafeInteger(\n \"maxFramesPerBlock\",\n limits?.maxFramesPerBlock ??\n DEFAULT_WORKFLOW_PROJECTION_LIMITS.maxFramesPerBlock,\n ),\n maxBytesPerBlock: positiveSafeInteger(\n \"maxBytesPerBlock\",\n limits?.maxBytesPerBlock ??\n DEFAULT_WORKFLOW_PROJECTION_LIMITS.maxBytesPerBlock,\n ),\n };\n}\n\nexport function createWorkflowNodeProjection(input: {\n runId: string;\n nodeId: string;\n limits?: Partial<WorkflowProjectionLimits>;\n}): WorkflowNodeProjection {\n return {\n runId: input.runId,\n nodeId: input.nodeId,\n answer: \"\",\n reasoning: \"\",\n blockShadowed: false,\n renderBlocks: {},\n renderBlockOrder: [],\n openFrames: {},\n limits: resolveLimits(input.limits),\n lastRenderBlockIssue: null,\n chunksReceived: 0,\n charsStreamed: 0,\n lastStreamingTs: null,\n lastPhase: null,\n lastTool: null,\n lastWarning: null,\n lastTransportSeq: 0,\n };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\nfunction asNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction utf8ByteLength(value: string): number {\n return new TextEncoder().encode(value).byteLength;\n}\n\nfunction toRenderBlock(value: unknown): AgentProjectionRenderBlock | null {\n const data = asRecord(value);\n if (!data) return null;\n const blockId = asString(data.blockId);\n const blockIndex = asNumber(data.blockIndex);\n const type = asString(data.type);\n if (blockId === null || blockIndex === null || type === null) return null;\n return {\n blockId,\n blockIndex,\n type,\n status:\n data.status === \"complete\" || data.status === \"error\"\n ? data.status\n : \"streaming\",\n content: asString(data.content),\n data: asRecord(data.data),\n metadata: asRecord(data.metadata),\n };\n}\n\nfunction withIssue(\n next: WorkflowNodeProjection,\n event: WorkflowNodeStreamEvent,\n code: WorkflowRenderBlockIssueCode,\n frameId: string | null,\n message: string,\n openFrames: Record<string, WorkflowRenderFrameSet> = next.openFrames,\n): WorkflowNodeProjection {\n return {\n ...next,\n openFrames,\n lastRenderBlockIssue: {\n code,\n frameId,\n streamSeq: event.stream_seq,\n message,\n },\n };\n}\n\nfunction withoutFrame(\n frames: Record<string, WorkflowRenderFrameSet>,\n frameId: string,\n): Record<string, WorkflowRenderFrameSet> {\n if (!Object.hasOwn(frames, frameId)) return frames;\n const next = { ...frames };\n delete next[frameId];\n return next;\n}\n\nfunction projectRenderFrame(\n current: WorkflowNodeProjection,\n event: WorkflowNodeStreamEvent,\n next: WorkflowNodeProjection,\n): WorkflowNodeProjection {\n const frameId = event.frame_id;\n const frameCount = event.frame_count ?? 1;\n const frameIndex = event.frame_index ?? 0;\n if (\n !frameId ||\n !Number.isSafeInteger(frameCount) ||\n !Number.isSafeInteger(frameIndex) ||\n frameCount < 1 ||\n frameIndex < 0 ||\n frameIndex >= frameCount\n ) {\n return withIssue(\n next,\n event,\n \"invalid_frame_metadata\",\n frameId ?? null,\n \"Render block frame metadata is invalid\",\n );\n }\n if (frameCount > current.limits.maxFramesPerBlock) {\n return withIssue(\n next,\n event,\n \"frame_limit_exceeded\",\n frameId,\n `Render block declares ${frameCount} frames; limit is ${current.limits.maxFramesPerBlock}`,\n withoutFrame(current.openFrames, frameId),\n );\n }\n\n const prior = current.openFrames[frameId];\n if (prior && prior.frameCount !== frameCount) {\n return withIssue(\n next,\n event,\n \"frame_count_mismatch\",\n frameId,\n `Render block frame count changed from ${prior.frameCount} to ${frameCount}`,\n withoutFrame(current.openFrames, frameId),\n );\n }\n\n const priorSlice = prior?.slices[frameIndex];\n const byteLength =\n (prior?.byteLength ?? 0) -\n (priorSlice === undefined ? 0 : utf8ByteLength(priorSlice)) +\n utf8ByteLength(event.delta);\n if (byteLength > current.limits.maxBytesPerBlock) {\n return withIssue(\n next,\n event,\n \"byte_limit_exceeded\",\n frameId,\n `Render block exceeds ${current.limits.maxBytesPerBlock} UTF-8 bytes`,\n withoutFrame(current.openFrames, frameId),\n );\n }\n\n const set: WorkflowRenderFrameSet = {\n frameCount,\n slices: { ...(prior?.slices ?? {}), [frameIndex]: event.delta },\n byteLength,\n };\n const openFrames = { ...current.openFrames };\n let limitIssue: WorkflowRenderBlockIssue | null = null;\n if (!prior && Object.keys(openFrames).length >= current.limits.maxOpenFrameSets) {\n const oldestFrameId = Object.keys(openFrames)[0];\n if (oldestFrameId !== undefined) {\n delete openFrames[oldestFrameId];\n limitIssue = {\n code: \"open_frame_limit_exceeded\",\n frameId: oldestFrameId,\n streamSeq: event.stream_seq,\n message: `Evicted incomplete render block after reaching ${current.limits.maxOpenFrameSets} open frame sets`,\n };\n }\n }\n openFrames[frameId] = set;\n if (Object.keys(set.slices).length !== frameCount) {\n return {\n ...next,\n openFrames,\n lastRenderBlockIssue: limitIssue ?? current.lastRenderBlockIssue,\n };\n }\n\n delete openFrames[frameId];\n const serialized = Array.from(\n { length: frameCount },\n (_, index) => set.slices[index] ?? \"\",\n ).join(\"\");\n let parsed: unknown;\n try {\n parsed = JSON.parse(serialized) as unknown;\n } catch (error) {\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n return withIssue(\n next,\n event,\n \"malformed_json\",\n frameId,\n `Completed render block is not valid JSON${detail}`,\n openFrames,\n );\n }\n const block = toRenderBlock(parsed);\n if (!block) {\n return withIssue(\n next,\n event,\n \"invalid_render_block\",\n frameId,\n \"Completed render block is missing blockId, blockIndex, or type\",\n openFrames,\n );\n }\n return {\n ...next,\n openFrames,\n lastRenderBlockIssue: limitIssue ?? current.lastRenderBlockIssue,\n renderBlocks: { ...current.renderBlocks, [block.blockId]: block },\n renderBlockOrder: Object.hasOwn(current.renderBlocks, block.blockId)\n ? current.renderBlockOrder\n : [...current.renderBlockOrder, block.blockId],\n };\n}\n\nexport function projectWorkflowNodeEvent(\n current: WorkflowNodeProjection,\n event: WorkflowNodeStreamEvent,\n): WorkflowNodeProjection {\n if (\n event.run_id !== current.runId ||\n (event.node_id ?? \"\") !== current.nodeId\n ) {\n return current;\n }\n if (event.stream_seq <= current.lastTransportSeq) return current;\n const next: WorkflowNodeProjection = {\n ...current,\n chunksReceived: event.chunks_received,\n charsStreamed: event.chars_streamed,\n lastStreamingTs: event.ts,\n lastTransportSeq: event.stream_seq,\n blockShadowed: current.blockShadowed || Boolean(event.block_shadowed),\n };\n switch (event.kind) {\n case \"chunk\":\n return { ...next, answer: current.answer + event.delta };\n case \"reasoning\":\n return { ...next, reasoning: current.reasoning + event.delta };\n case \"phase\":\n return { ...next, lastPhase: event.delta };\n case \"tool\":\n return { ...next, lastTool: event.delta };\n case \"warning\":\n return { ...next, lastWarning: event.delta };\n case \"render_block\":\n return projectRenderFrame(current, event, next);\n default:\n return next;\n }\n}\n","/**\n * `@ai-matrx/agents/matrx` — the Matrx transport port.\n *\n * The ONE seam between this package's wire semantics and a host's connection\n * policy. This package owns WHAT is said to the AI Matrx server — paths,\n * methods, JSON bodies, streaming Accept headers, the `Last-Event-ID` cursor\n * header — and the host owns HOW the connection is made:\n *\n * - base-URL / backend-channel resolution (global, sandbox override, local\n * engine, EC2-dedicated — whatever ladder the host runs);\n * - credentials (Supabase JWT `Authorization: Bearer`, guest\n * `X-Fingerprint-ID`, or the API-key lane) — NEVER implemented here;\n * - the `X-Organization-Id` context header;\n * - retry policy, network-level timeouts, and diagnostics capture.\n *\n * A host implements the port in a few lines:\n *\n * ```ts\n * const transport: MatrxTransport = {\n * fetch: (path, init) =>\n * fetch(`${baseUrl}${path}`, {\n * ...init,\n * headers: { ...init.headers, ...authHeaders() },\n * }),\n * };\n * ```\n *\n * The port is deliberately structural and `fetch`-shaped so `@ai-matrx/data`'s\n * `/api` transport can implement it without importing this package.\n */\n\n/**\n * The request this package hands the port. A strict subset of `RequestInit`,\n * so a host can spread it straight into `fetch`.\n */\nexport interface MatrxTransportRequest {\n method: \"GET\" | \"POST\";\n /**\n * Wire-semantic headers the CALL requires (`Content-Type`, `Accept`,\n * `Last-Event-ID`). The host merges its policy headers (auth, org) on top;\n * it must not drop these.\n */\n headers: Record<string, string>;\n /** Pre-serialized JSON body, present on POST calls that carry one. */\n body?: string;\n /** Caller cancellation. The host must wire it to the underlying fetch. */\n signal?: AbortSignal;\n}\n\n/**\n * The transport port. `path` is server-relative and always starts with `/`\n * (`/ai/...`, `/runtime/...`); the host prepends its resolved base URL.\n */\nexport interface MatrxTransport {\n fetch(path: string, init: MatrxTransportRequest): Promise<Response>;\n}\n\n/**\n * A non-2xx response from the Matrx API, with the server's structured error\n * body preserved and its richest human-readable message extracted.\n */\nexport class MatrxApiError extends Error {\n override readonly name = \"MatrxApiError\";\n /** HTTP status of the failed response. */\n readonly status: number;\n /** Machine code from the server body (`code`, or `detail.code`), when present. */\n readonly code: string | null;\n /** The parsed server error body, verbatim (undefined when unparsable). */\n readonly serverDetail: unknown;\n /** The request path the failure came from (server-relative). */\n readonly path: string;\n\n constructor(args: {\n status: number;\n path: string;\n serverDetail?: unknown;\n message?: string;\n }) {\n super(\n args.message ??\n extractMatrxErrorMessage(args.serverDetail) ??\n `HTTP ${args.status}`,\n );\n this.status = args.status;\n this.path = args.path;\n this.serverDetail = args.serverDetail;\n this.code = extractMatrxErrorCode(args.serverDetail);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonBlankString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\n/**\n * Extract the richest human-readable message from a Matrx/FastAPI error body.\n *\n * aidream 4xx validation errors look like\n * `{ error, user_message, details: [{ field, message, help }] }`; hand-raised\n * HTTPExceptions carry `{ detail: { code, message } }`; FastAPI's defaults are\n * `{ detail: string | [{ msg }] }`. Preference order: `user_message` →\n * `message` → joined `details[].message` → `detail.message` →\n * `detail` string → joined `detail[].msg`. Returns undefined for\n * unrecognized bodies so callers fall back to the bare status line.\n */\nexport function extractMatrxErrorMessage(\n serverDetail: unknown,\n): string | undefined {\n if (!isRecord(serverDetail)) return undefined;\n\n const userMessage = nonBlankString(serverDetail.user_message);\n if (userMessage) return userMessage;\n const message = nonBlankString(serverDetail.message);\n if (message) return message;\n\n if (Array.isArray(serverDetail.details)) {\n const messages = serverDetail.details\n .map((entry: unknown) => {\n if (!isRecord(entry)) return undefined;\n const detailMessage = nonBlankString(entry.message);\n if (!detailMessage) return undefined;\n const field = nonBlankString(entry.field);\n return field ? `${field}: ${detailMessage}` : detailMessage;\n })\n .filter((m): m is string => typeof m === \"string\");\n if (messages.length > 0) return messages.join(\"; \");\n }\n\n const detail = serverDetail.detail;\n if (isRecord(detail)) {\n const detailMessage =\n nonBlankString(detail.message) ?? nonBlankString(detail.user_message);\n if (detailMessage) return detailMessage;\n }\n if (typeof detail === \"string\" && detail.trim()) return detail;\n if (Array.isArray(detail)) {\n const messages = detail\n .map((entry: unknown) =>\n isRecord(entry) ? nonBlankString(entry.msg) : undefined,\n )\n .filter((m): m is string => typeof m === \"string\");\n if (messages.length > 0) return messages.join(\"; \");\n }\n return undefined;\n}\n\n/**\n * Extract the machine error code from a Matrx error body: top-level `code`,\n * else `detail.code` (the hand-raised HTTPException shape). Null when absent.\n */\nexport function extractMatrxErrorCode(serverDetail: unknown): string | null {\n if (!isRecord(serverDetail)) return null;\n const topLevel = nonBlankString(serverDetail.code);\n if (topLevel) return topLevel;\n const detail = serverDetail.detail;\n if (isRecord(detail)) {\n const nested = nonBlankString(detail.code);\n if (nested) return nested;\n }\n return null;\n}\n","/**\n * The PRODUCTION `MatrxTransport` — the full connection pipeline every Matrx\n * host used to hand-roll, moved in under C22 (THE HARD PARTS LIVE IN THE\n * PACKAGE). A host constructs it from identity alone:\n *\n * ```ts\n * const transport = createMatrxTransport({\n * baseUrl: \"https://server.app.matrxserver.com\",\n * credentials, // CredentialsPort (@ai-matrx/data)\n * organizationId: () => activeOrgId, // omit for conversation-lane calls\n * });\n * ```\n *\n * Everything else is defaulted to the proven production values:\n *\n * - **timeouts** — connect 15s (for a non-streaming FastAPI handler this is\n * effectively time-to-response), total UNCAPPED (the port cannot tell a JSON\n * call from a long-lived NDJSON/SSE stream; the connect timeout is the JSON\n * guard), via `@ai-matrx/data/net`'s `resilientFetch`;\n * - **protocol** — the AI API version transform (`applyAiApiVersion`, default\n * v2) + the loud v2 → v1 transport fallback (`./protocol`);\n * - **credentials** — read fresh from the injected `CredentialsPort` on EVERY\n * call, so a token refresh mid-run is picked up; mapped to headers by the\n * ONE `credentialToHeaders`;\n * - **org context** — the fail-closed `X-Organization-Id` binding\n * (`./org-context`): configured lanes REQUIRE an org and refuse before the\n * wire; unconfigured lanes (conversation-scoped calls, which carry org in\n * the body) send none;\n * - **error classification** — every failure normalizes through\n * `normalizeMatrxError` into the ONE `MatrxCallError` envelope;\n * - **diagnostics** — a typed sink the host wires to its capture/telemetry\n * (`onRequest`, `onError`, `onProtocolDowngrade`); wiring it is optional,\n * the transport works silently without it.\n *\n * Header merge order is part of the port contract: wire headers first\n * (`Content-Type` / `Accept` / `Last-Event-ID` — the package's), then\n * credentials, then resolver policy headers, then the org header. Policy\n * headers never carry `Content-Type` — the wire owns it, and a policy\n * `Content-Type` merged over a GET SSE call would corrupt the wire, so the\n * factory strips it defensively.\n */\n\nimport { isNetError, type CredentialsPort } from \"@ai-matrx/data\";\nimport { credentialToHeaders } from \"@ai-matrx/data\";\nimport {\n applyOrganizationContextHeader,\n OrganizationContextError,\n requireOrganizationContext,\n} from \"./org-context\";\nimport {\n applyAiApiVersion,\n fetchWithMatrxProtocolFallback,\n MATRX_AI_API_VERSION_DEFAULT,\n type MatrxAiApiVersion,\n type MatrxProtocolDowngrade,\n} from \"./protocol\";\nimport {\n extractMatrxErrorCode,\n extractMatrxErrorMessage,\n MatrxApiError,\n type MatrxTransport,\n type MatrxTransportRequest,\n} from \"./transport\";\n\n// ─── The normalized error envelope ──────────────────────────────────────────\n\n/**\n * The ONE classified error shape for Matrx client calls — the envelope hosts\n * branch on instead of string-matching exceptions. Structurally compatible\n * with matrx-frontend's `ApiCallError` by design.\n */\nexport interface MatrxCallError {\n type:\n | \"auth_error\"\n | \"network_error\"\n | \"http_error\"\n | \"validation_error\"\n | \"abort_error\"\n | \"unknown\";\n message: string;\n /** HTTP status code, if applicable. */\n status?: number;\n /** Raw error detail from the server (the parsed error body). */\n serverDetail?: unknown;\n /** Machine code preserved through normalization (server `code`, org-context code, …). */\n code?: string;\n /** Original exception identity for diagnostics. */\n name?: string;\n /** Original exception stack. */\n stack?: string;\n}\n\nfunction classifyStatus(status: number): \"validation_error\" | \"http_error\" {\n return status >= 400 && status < 500 ? \"validation_error\" : \"http_error\";\n}\n\n/**\n * Classify any failure thrown by a package client call — `MatrxApiError`,\n * a `NetError` from the resilience layer, an org-context refusal, an abort —\n * into the `MatrxCallError` envelope. Never throws.\n */\nexport function normalizeMatrxError(err: unknown): MatrxCallError {\n if (err instanceof MatrxApiError) {\n return {\n type: classifyStatus(err.status),\n message: err.message,\n status: err.status,\n serverDetail: err.serverDetail,\n ...(err.code ? { code: err.code } : {}),\n name: err.name,\n };\n }\n\n if (err instanceof OrganizationContextError) {\n return {\n type: \"validation_error\",\n message: err.message,\n code: err.code,\n name: err.name,\n ...(err.stack !== undefined ? { stack: err.stack } : {}),\n };\n }\n\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return { type: \"abort_error\", message: \"Request was cancelled.\" };\n }\n\n if (isNetError(err)) {\n if (err.code === \"aborted\") {\n return { type: \"abort_error\", message: err.message };\n }\n if (err.code === \"http\") {\n const status = err.status ?? 0;\n return { type: classifyStatus(status), message: err.message, status };\n }\n // connect-timeout / total-timeout / heartbeat-timeout / network / offline\n return { type: \"network_error\", message: err.message };\n }\n\n if (err instanceof Error) {\n const httpMatch = err.message.match(/HTTP (\\d+):\\s*(.*)/);\n if (httpMatch) {\n const status = parseInt(httpMatch[1] as string, 10);\n return {\n type: classifyStatus(status),\n message: httpMatch[2] ?? err.message,\n status,\n };\n }\n return { type: \"network_error\", message: err.message };\n }\n\n return { type: \"unknown\", message: String(err ?? \"Unknown error\") };\n}\n\n// ─── The factory ────────────────────────────────────────────────────────────\n\n/**\n * A fully-resolved connection target for one call: where to send it and which\n * policy headers ride ON TOP of the wire + credential headers.\n */\nexport interface MatrxTransportTarget {\n /** Fully-qualified base URL, no trailing slash. */\n baseUrl: string;\n /**\n * Extra policy headers for this target (e.g. a resolver that carries its own\n * credential headers). `Content-Type` is stripped — the wire owns it.\n */\n policyHeaders?: Record<string, string>;\n /** Routing channel label surfaced to `onRequest` telemetry. */\n channel?: string;\n}\n\n/** Context handed to every diagnostics callback. */\nexport interface MatrxRequestInfo {\n /** The final URL (base + version-transformed path). */\n url: string;\n method: \"GET\" | \"POST\";\n /** The server-relative path as the package requested it. */\n path: string;\n /** The resolved routing channel (default \"default\"). */\n channel: string;\n /** The transport's call-site label (default \"matrxTransport\"). */\n source: string;\n}\n\n/**\n * The typed diagnostics sink — the host wires these to its telemetry/capture\n * systems; all optional, and the transport is fully functional without them.\n */\nexport interface MatrxTransportDiagnostics {\n /** Fired at the last pre-fetch moment of every call. */\n onRequest?: (info: MatrxRequestInfo) => void;\n /**\n * Fired for every thrown network failure and every non-2xx response not\n * listed in `expectedErrorStatuses`, with the classified envelope.\n */\n onError?: (error: MatrxCallError, info: MatrxRequestInfo) => void;\n /** Fired on every v2 → v1 protocol downgrade. */\n onProtocolDowngrade?: (downgrade: MatrxProtocolDowngrade) => void;\n}\n\nexport interface CreateMatrxTransportOptions {\n /** Fixed base URL, no trailing slash. Exactly one of `baseUrl` / `resolveTarget`. */\n baseUrl?: string;\n /**\n * Per-call target resolver — for hosts whose base URL / policy headers are\n * dynamic (server toggles, sandbox overrides, conversation channels).\n * Resolution runs fresh on EVERY call. May throw to refuse a call loudly.\n */\n resolveTarget?: () => MatrxTransportTarget;\n /**\n * The credential source (`@ai-matrx/data`), read fresh per call so token\n * refreshes are picked up mid-run. Omit only when the resolver's\n * `policyHeaders` already carry the credentials.\n */\n credentials?: CredentialsPort;\n /**\n * The org-context binding. When configured, every call REQUIRES a valid org\n * (fail-closed `organization_context_required` before the wire) and carries\n * `X-Organization-Id`. Omit for conversation-lane transports, which send the\n * org in the body only.\n */\n organizationId?: string | (() => string | null | undefined);\n /** AI API protocol version (value or per-call getter). Default `\"v2\"`. */\n aiApiVersion?: MatrxAiApiVersion | (() => MatrxAiApiVersion);\n /** Max ms request start → response headers. Default 15_000. */\n connectTimeoutMs?: number;\n /**\n * Max ms for the whole handshake. Default `null` (uncapped) — the port\n * cannot tell a JSON call from a long-lived stream, and capping would kill\n * long streams; the connect timeout is the real JSON guard.\n */\n totalTimeoutMs?: number | null;\n /**\n * HTTP failures this transport's call class fully handles as expected\n * domain outcomes (e.g. 404 on runtime-operation identify). They still\n * reach the package client (which maps them to typed results) but are not\n * reported through `onError`.\n */\n expectedErrorStatuses?: readonly number[];\n /** Short call-site label surfaced on `MatrxRequestInfo` (default \"matrxTransport\"). */\n source?: string;\n diagnostics?: MatrxTransportDiagnostics;\n}\n\nconst PRODUCTION_CONNECT_TIMEOUT_MS = 15_000;\n\nfunction stripContentType(\n headers: Record<string, string>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([name]) => name.toLowerCase() !== \"content-type\",\n ),\n );\n}\n\n/**\n * Build the production `MatrxTransport`. See the module doc for the pipeline;\n * every knob defaults to the proven production value.\n */\nexport function createMatrxTransport(\n options: CreateMatrxTransportOptions,\n): MatrxTransport {\n const {\n baseUrl,\n resolveTarget,\n credentials,\n organizationId,\n aiApiVersion,\n connectTimeoutMs = PRODUCTION_CONNECT_TIMEOUT_MS,\n totalTimeoutMs = null,\n expectedErrorStatuses,\n diagnostics,\n source = \"matrxTransport\",\n } = options;\n\n if ((baseUrl === undefined) === (resolveTarget === undefined)) {\n throw new Error(\n \"createMatrxTransport: provide exactly one of `baseUrl` or `resolveTarget`.\",\n );\n }\n\n const resolve: () => MatrxTransportTarget =\n resolveTarget ?? (() => ({ baseUrl: baseUrl as string }));\n\n const resolveVersion = (): MatrxAiApiVersion => {\n if (aiApiVersion === undefined) return MATRX_AI_API_VERSION_DEFAULT;\n return typeof aiApiVersion === \"function\" ? aiApiVersion() : aiApiVersion;\n };\n\n const resolveOrganizationId = (): string | null => {\n if (organizationId === undefined) return null;\n const candidate =\n typeof organizationId === \"function\" ? organizationId() : organizationId;\n // Fail closed: a configured org lane with no org refuses before the wire.\n return requireOrganizationContext(candidate);\n };\n\n return {\n async fetch(path: string, init: MatrxTransportRequest): Promise<Response> {\n const target = resolve();\n\n // `path` is already interpolated (`/ai/agents/<uuid>`), so the version\n // transform is the concrete-path bridge, not a template registry.\n const versionedPath = applyAiApiVersion(path, resolveVersion());\n const url = `${target.baseUrl}${versionedPath}`;\n\n // Wire headers FIRST; credentials, then resolver policy headers, then\n // the org header on top — none of them may carry Content-Type.\n const credentialHeaders = credentials\n ? credentialToHeaders(await credentials.get())\n : {};\n let headers: Record<string, string> = {\n ...init.headers,\n ...stripContentType(credentialHeaders),\n ...stripContentType(target.policyHeaders ?? {}),\n };\n const orgId = resolveOrganizationId();\n if (orgId !== null) {\n headers = applyOrganizationContextHeader(headers, orgId);\n }\n\n const info: MatrxRequestInfo = {\n url,\n method: init.method,\n path,\n channel: target.channel ?? \"default\",\n source,\n };\n diagnostics?.onRequest?.(info);\n\n let response: Response;\n try {\n ({ response } = await fetchWithMatrxProtocolFallback(\n url,\n {\n method: init.method,\n headers,\n ...(init.body !== undefined ? { body: init.body } : {}),\n },\n {\n ...(init.signal ? { signal: init.signal } : {}),\n connectTimeoutMs,\n totalTimeoutMs,\n throwOnHttpError: false,\n ...(diagnostics?.onProtocolDowngrade\n ? { onDowngrade: diagnostics.onProtocolDowngrade }\n : {}),\n },\n ));\n } catch (err) {\n diagnostics?.onError?.(normalizeMatrxError(err), info);\n throw err;\n }\n\n if (!response.ok && !expectedErrorStatuses?.includes(response.status)) {\n // The package client consumes the original body for its\n // MatrxApiError; read the diagnostics copy from a clone so the two\n // never fight.\n const serverDetail: unknown = await response\n .clone()\n .json()\n .catch(() => undefined);\n const code = extractMatrxErrorCode(serverDetail);\n diagnostics?.onError?.(\n {\n type: classifyStatus(response.status),\n message:\n extractMatrxErrorMessage(serverDetail) ??\n `HTTP ${response.status}`,\n status: response.status,\n serverDetail,\n ...(code ? { code } : {}),\n },\n info,\n );\n }\n\n return response;\n },\n };\n}\n","import { isUuidShape } from \"@ai-matrx/kit/uuid\";\n\n/**\n * The fail-closed organization-context kernel — ONE implementation for every\n * Matrx client transport (moved in from matrx-frontend\n * `lib/api/organization-context.ts` verbatim under C22; the host module is now\n * a re-export of this one).\n *\n * Transports resolve their authoritative organization first, then use these\n * functions to bind that exact value without guessing or defaulting. The\n * server never manufactures an org (it 422s a blank one), so the client\n * refuses before the wire: a missing or malformed org id throws\n * `OrganizationContextError` instead of sending a request that cannot succeed.\n */\n\nexport type OrganizationContextErrorCode =\n | \"organization_context_required\"\n | \"organization_context_invalid\"\n | \"organization_context_mismatch\";\n\nexport class OrganizationContextError extends Error {\n readonly code: OrganizationContextErrorCode;\n\n constructor(code: OrganizationContextErrorCode, message: string) {\n super(message);\n this.name = \"OrganizationContextError\";\n this.code = code;\n }\n}\n\ndeclare const organizationOperationBrand: unique symbol;\n\n/** A validated organization operation; construct only through the factory. */\nexport type OrganizationOperation = Readonly<{\n organization_id: string;\n readonly [organizationOperationBrand]: true;\n}>;\n\nexport function createOrganizationOperation(\n organizationId: string,\n): OrganizationOperation {\n const organization_id = requireOrganizationContext(organizationId);\n return Object.freeze({ organization_id }) as OrganizationOperation;\n}\n\nexport function assertOrganizationMatchesOperation(\n operation: OrganizationOperation,\n organizationId: string,\n): void {\n if (operation.organization_id !== requireOrganizationContext(organizationId)) {\n throw new OrganizationContextError(\n \"organization_context_mismatch\",\n \"Organization ID must match the request operation.\",\n );\n }\n}\n\n/**\n * Normalize and validate the effective organization id for a request. The\n * override (an explicit per-call value) beats the selected context value.\n * Throws `organization_context_required` when neither is present and\n * `organization_context_invalid` when the candidate is not a UUID.\n */\nexport function requireOrganizationContext(\n selectedOrganizationId: string | null | undefined,\n overrideOrganizationId?: string,\n): string {\n const candidate = overrideOrganizationId ?? selectedOrganizationId;\n if (typeof candidate !== \"string\" || candidate.trim().length === 0) {\n throw new OrganizationContextError(\n \"organization_context_required\",\n \"Select an organization before sending this request.\",\n );\n }\n\n const normalized = candidate.trim();\n if (!isUuidShape(normalized)) {\n throw new OrganizationContextError(\n \"organization_context_invalid\",\n \"The selected organization ID is invalid.\",\n );\n }\n return normalized.toLowerCase();\n}\n\n/**\n * Bind `X-Organization-Id` onto a header bag. A pre-existing org header that\n * disagrees with the context org is a `organization_context_mismatch` error —\n * never silently overwritten in either direction.\n */\nexport function applyOrganizationContextHeader(\n headers: Record<string, string>,\n organizationId: string,\n): Record<string, string> {\n const normalizedOrganizationId = requireOrganizationContext(organizationId);\n for (const [name, value] of Object.entries(headers)) {\n if (\n name.toLowerCase() === \"x-organization-id\" &&\n value.trim().toLowerCase() !== normalizedOrganizationId\n ) {\n throw new OrganizationContextError(\n \"organization_context_mismatch\",\n \"X-Organization-Id must match the request context organization.\",\n );\n }\n }\n const withoutOrganizationHeader = Object.fromEntries(\n Object.entries(headers).filter(\n ([name]) => name.toLowerCase() !== \"x-organization-id\",\n ),\n );\n return {\n ...withoutOrganizationHeader,\n \"X-Organization-Id\": normalizedOrganizationId,\n };\n}\n\n/**\n * Assert that an `organization_id` query parameter (when present) matches the\n * request context organization — the query string must never smuggle a\n * different org past the header binding.\n */\nexport function assertQueryOrganizationMatchesContext(\n queryParams: Record<string, string | number | boolean> | undefined,\n organizationId: string,\n): void {\n if (!queryParams || queryParams.organization_id === undefined) return;\n const queryOrganizationId = requireOrganizationContext(\n String(queryParams.organization_id),\n );\n if (queryOrganizationId !== requireOrganizationContext(organizationId)) {\n throw new OrganizationContextError(\n \"organization_context_mismatch\",\n \"Query organization_id must match the request context organization.\",\n );\n }\n}\n","/**\n * The AI API protocol-version policy — which version of the AI runtime a\n * Matrx client talks to, and the v2 → v1 transport fallback (moved in from\n * matrx-frontend `lib/api/ai-api-version.ts` + `call-api.ts::\n * fetchWithV2Fallback` under C22; server truth\n * `aidream/docs/runtime/V2_FRONTEND_MIGRATION.md`).\n *\n * Background: the Python backend exposes a `/v2` runtime-spine namespace that\n * wraps the core AI request surfaces in a request-tracking envelope. Body,\n * headers, and streaming response are BYTE-IDENTICAL to v1 — only the URL\n * differs.\n *\n * ─── The one rule that keeps burning us ─────────────────────────────────────\n * `/v2` is inserted at the FRONT of the in-app path, right before `/ai`:\n *\n * /ai/agents/{id} → /v2/ai/agents/{id} ✅ correct\n * /ai/v2/agents/… ❌ WRONG (nested) — 404s\n *\n * `toV2Path` below is the ONLY place this transform is spelled out.\n *\n * ─── Scope: ONLY the covered surfaces have a v2 form ────────────────────────\n * chat, manual, agents/{id}, conversations/{id} (+ singular aliases),\n * prompts/{id}, mandates/{key}. EVERYTHING ELSE — cancel, warm, resume,\n * fork-and-run, runtime operations, files … — has NO v2 route, and the server\n * does NOT auto-downgrade (a `/v2` request to an uncovered surface is a plain\n * 404). So the transform is a scoped allowlist, never a blanket prefix.\n */\n\nimport {\n isNetError,\n resilientFetch,\n type ResilientFetchOptions,\n} from \"@ai-matrx/data/net\";\n\nexport type MatrxAiApiVersion = \"v1\" | \"v2\";\n\n/**\n * The package-wide default AI API version — the production value every Matrx\n * client runs unless its host deliberately overrides\n * (`createMatrxTransport({ aiApiVersion })`).\n */\nexport const MATRX_AI_API_VERSION_DEFAULT: MatrxAiApiVersion = \"v2\";\n\n/**\n * The canonical v1 path TEMPLATES the v2 spine covers, `{param}` placeholders\n * intact — for hosts that route through a template registry.\n */\nexport const V2_COVERED_AI_PATH_TEMPLATES = [\n \"/ai/manual\",\n \"/ai/chat\",\n \"/ai/agents/{agent_id}\",\n \"/ai/agent/{agent_id}\", // singular alias — behaves identically\n \"/ai/conversations/{conversation_id}\",\n \"/ai/conversation/{conversation_id}\", // singular alias\n \"/ai/prompts/{prompt_id}\", // saved-prompt execution\n \"/ai/mandates/{mandate_key}\", // THE MANDATE DOOR — `/v2` sibling exists (routers/v2.py)\n] as const;\n\n/**\n * Insert `/v2` at the front of an in-app path. Idempotent, and prefix-aware:\n * a legacy `/api/` compatibility prefix (stripped server-side) is preserved so\n * `/api/ai/chat` → `/api/v2/ai/chat`.\n */\nexport function toV2Path(path: string): string {\n const withLead = path.startsWith(\"/\") ? path : `/${path}`;\n if (withLead.startsWith(\"/api/\")) {\n const rest = withLead.slice(\"/api\".length); // \"/ai/chat\"\n return rest.startsWith(\"/v2/\") ? withLead : `/api/v2${rest}`;\n }\n return withLead.startsWith(\"/v2/\") ? withLead : `/v2${withLead}`;\n}\n\n// Interpolated (concrete) forms of the covered surfaces — used to guard\n// callers that pass a real path (id already substituted). Anchored so ONLY the\n// exact shapes match: sub-paths like `/ai/agents/{id}/warm`,\n// `/ai/conversations/{id}/resume`, and `/ai/cancel/{id}` deliberately do NOT\n// match and stay on v1. The optional `/api` prefix mirrors `toV2Path`.\nconst COVERED_INTERPOLATED_PATH = [\n /^(?:\\/api)?\\/ai\\/manual$/,\n /^(?:\\/api)?\\/ai\\/chat$/,\n /^(?:\\/api)?\\/ai\\/agents\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/agent\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/conversations\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/conversation\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/prompts\\/[^/]+$/, // `/warm` etc. deliberately don't match\n /^(?:\\/api)?\\/ai\\/mandates\\/[^/]+$/, // the mandate door\n];\n\n/** Whether `path` (already interpolated) is one of the covered surfaces. */\nexport function isCoveredAiPath(path: string): boolean {\n return COVERED_INTERPOLATED_PATH.some((re) => re.test(path));\n}\n\n/**\n * Whether an in-app path (or a full URL whose path was built by `toV2Path`)\n * targets the v2 namespace — the guard the downgrade fallback keys off.\n */\nexport function isV2Path(pathOrUrl: string): boolean {\n return /\\/v2\\/ai\\//.test(pathOrUrl);\n}\n\n/**\n * The inverse of `toV2Path` — strip the `/v2` version segment so a transport\n * failure of the v2 endpoint (network error, 404/405, 5xx BEFORE any stream\n * content) can retry the identical request on the v1 route. Works on a bare\n * path, an `/api`-prefixed path, or a full URL (the `/v2/ai/` shape is unique\n * to the version namespace). Idempotent on non-v2 input.\n */\nexport function toV1FallbackUrl(url: string): string {\n return url.replace(/\\/v2\\/ai\\//, \"/ai/\");\n}\n\n/**\n * Apply the active AI API version to an ALREADY-INTERPOLATED in-app path.\n *\n * - Covered surface + v2 → `/v2` prefix inserted.\n * - Anything else (or v1) → returned unchanged.\n *\n * Pass the in-app PATH only (no scheme/host); prepend the base URL afterward.\n */\nexport function applyAiApiVersion(\n path: string,\n version: MatrxAiApiVersion,\n): string {\n if (version !== \"v2\") return path;\n return isCoveredAiPath(path) ? toV2Path(path) : path;\n}\n\n/** One v2 → v1 downgrade, surfaced to the host's diagnostics sink. */\nexport interface MatrxProtocolDowngrade {\n /** The failed v2 URL. */\n url: string;\n /** Why the downgrade fired (thrown error text, or `HTTP <status>`). */\n reason: string;\n /** HTTP status when the trigger was a response (404/405/5xx). */\n status?: number;\n}\n\nexport interface MatrxProtocolFallbackOptions extends ResilientFetchOptions {\n /**\n * Fired on every downgrade — a sustained stream of these means a v2 surface\n * is unhealthy. The fallback also `console.warn`s unconditionally (parity\n * with the original host pipeline) so the signal never disappears silently.\n */\n onDowngrade?: (downgrade: MatrxProtocolDowngrade) => void;\n}\n\n/**\n * `resilientFetch` with the v2 → v1 transport fallback. Fires ONLY when a\n * `/v2/ai/...` ENDPOINT itself fails — a network-layer throw (non-abort), a\n * 404/405 (surface not on v2), or a 5xx — always BEFORE any stream content is\n * consumed. Never on an application error (those fail identically on v1), and\n * never on a caller abort (a user cancel must not be logged as a downgrade —\n * that poisons the exact telemetry the rollout reads to judge v2 health).\n */\nexport async function fetchWithMatrxProtocolFallback(\n url: string,\n init: RequestInit,\n opts: MatrxProtocolFallbackOptions = {},\n): Promise<{ response: Response }> {\n const { onDowngrade, ...fetchOpts } = opts;\n const logDowngrade = (reason: string, status?: number) => {\n console.warn(\n `[matrx] ai_v2_downgrade → retrying on v1. v2=${url} reason=${reason}`,\n );\n onDowngrade?.({ url, reason, ...(status !== undefined ? { status } : {}) });\n };\n if (!isV2Path(url)) return resilientFetch(url, init, fetchOpts);\n let result: { response: Response };\n try {\n result = await resilientFetch(url, init, fetchOpts);\n } catch (err) {\n // resilientFetch normalizes a caller-signal abort to NetError code\n // \"aborted\" (AbortedError); a raw AbortError is checked too for safety.\n const isAbort =\n (isNetError(err) && err.code === \"aborted\") ||\n (err instanceof Error && err.name === \"AbortError\");\n if (isAbort) throw err;\n logDowngrade(String(err));\n return resilientFetch(toV1FallbackUrl(url), init, fetchOpts);\n }\n const status = result.response.status;\n if (status === 404 || status === 405 || status >= 500) {\n logDowngrade(`HTTP ${status}`, status);\n return resilientFetch(toV1FallbackUrl(url), init, fetchOpts);\n }\n return result;\n}\n","/**\n * The conversation-start contract — client-minted `conversation_id`, `is_new`,\n * `store` — typed exactly per the cross-repo System of Record\n * (`common-docs/systems/agents/conversation-start-contract/FEATURE.md`;\n * server truth `aidream/services/conversation_context/scope.py::\n * ConversationStartRequest`).\n *\n * Every request that STARTS a conversation sends all three fields, no\n * defaults:\n *\n * | `is_new` | `store` | Result |\n * |----------|---------|----------------------------------------------------------|\n * | true | true | Create the row with the caller's id — 409 if it exists |\n * | true | false | No row. The id is correlation only (ephemeral run) |\n * | false | true | Continue it — 404 if the caller doesn't own it |\n * | false | false | Ephemeral run on a known id; nothing read, nothing written |\n *\n * `store` is the ONLY ephemeral signal; `is_new` is the caller's assertion\n * about the id, never a persistence switch. `prior_messages` (the client-owned\n * transcript of an ephemeral multi-turn run) is only valid with\n * `store: false` — the union below makes the invalid combination\n * unrepresentable, mirroring the server's 422.\n *\n * Continue routes (`POST /ai/conversations/{id}`) take the id from the path\n * and do not carry this triple.\n */\n\n/** Recursive JSON value — the package's honest type for free-form wire bags. */\nexport type MatrxJsonValue =\n | string\n | number\n | boolean\n | null\n | MatrxJsonValue[]\n | { [key: string]: MatrxJsonValue };\n\n/** A JSON object on the wire. */\nexport type MatrxJsonObject = { [key: string]: MatrxJsonValue };\n\n/**\n * One LLM message on the request wire — `prior_messages` entries for\n * stateless multi-turn runs. Mirrors aidream's `ChatMessageInput`\n * (`aidream/schemas/messages.py`, `extra=\"allow\"` — additional provider\n * fields round-trip untouched).\n */\nexport interface MatrxChatMessage {\n role: string;\n content?: string | MatrxJsonValue[] | null;\n name?: string | null;\n tool_call_id?: string | null;\n tool_calls?: MatrxJsonObject[] | null;\n [extra: string]: MatrxJsonValue | undefined;\n}\n\n/** `is_new: true, store: true` — create the row with the caller's id. */\nexport interface MatrxStoredConversationCreate {\n conversation_id: string;\n is_new: true;\n store: true;\n}\n\n/** `is_new: false, store: true` — continue an owned stored conversation via a start route. */\nexport interface MatrxStoredConversationContinue {\n conversation_id: string;\n is_new: false;\n store: true;\n}\n\n/**\n * `store: false` — ephemeral: nothing read, nothing written; the id is the\n * caller's correlation handle. This is the ONLY member that may carry\n * `prior_messages` (the server 422s a client transcript on a stored run).\n */\nexport interface MatrxEphemeralConversation {\n conversation_id: string;\n is_new: boolean;\n store: false;\n prior_messages?: MatrxChatMessage[];\n}\n\n/** The full conversation-start triple, one member per contract cell. */\nexport type MatrxConversationStart =\n | MatrxStoredConversationCreate\n | MatrxStoredConversationContinue\n | MatrxEphemeralConversation;\n\n/** Mint a fresh client-side conversation id (the contract requires the CLIENT to mint it). */\nexport function mintMatrxConversationId(): string {\n return crypto.randomUUID();\n}\n\n/** Start a NEW stored conversation (`is_new: true, store: true`). */\nexport function newStoredConversationStart(\n conversationId?: string,\n): MatrxStoredConversationCreate {\n return {\n conversation_id: conversationId ?? mintMatrxConversationId(),\n is_new: true,\n store: true,\n };\n}\n\n/**\n * Continue an EXISTING stored conversation through a start route\n * (`is_new: false, store: true` — 404 when the caller doesn't own the id).\n * Prefer `continueAgentConversation` (the dedicated continue route) for\n * ordinary follow-up turns.\n */\nexport function continueStoredConversationStart(\n conversationId: string,\n): MatrxStoredConversationContinue {\n return { conversation_id: conversationId, is_new: false, store: true };\n}\n\n/**\n * Start a NEW ephemeral run (`is_new: true, store: false`) — a freshly minted\n * correlation id, nothing persisted.\n */\nexport function newEphemeralConversationStart(\n conversationId?: string,\n): MatrxEphemeralConversation {\n return {\n conversation_id: conversationId ?? mintMatrxConversationId(),\n is_new: true,\n store: false,\n };\n}\n\n/**\n * Continue an ephemeral multi-turn run (`is_new: false, store: false`): the\n * CLIENT owns the transcript and replays it as `prior_messages` (ordered\n * oldest-first) because the server wrote no rows to rebuild from. The server\n * still owns the agent definition, model, tools, and system prompt.\n */\nexport function continueEphemeralConversationStart(\n conversationId: string,\n priorMessages: MatrxChatMessage[],\n): MatrxEphemeralConversation {\n return {\n conversation_id: conversationId,\n is_new: false,\n store: false,\n prior_messages: priorMessages,\n };\n}\n","/**\n * Internal request plumbing for `@ai-matrx/agents/matrx`. Not part of the\n * public surface — `matrx/index.ts` deliberately does not re-export this\n * module. Everything here is pure: no globals, no work at import time.\n */\n\nimport {\n readMatrxNdjsonStream,\n type MatrxNdjsonIssue,\n type MatrxStreamEnvelope,\n type MatrxStreamEnvelopeObservation,\n} from \"../stream/ndjson\";\nimport { MatrxApiError, type MatrxTransport } from \"./transport\";\n\n/** Encode one path segment (an id) safely into a server-relative path. */\nexport function encodePathSegment(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | readonly string[]\n | undefined;\n\n/**\n * Build a query string. Array values repeat the key (`kind=a&kind=b` — the\n * FastAPI repeatable-parameter convention); undefined values are omitted.\n * Returns \"\" or a string starting with \"?\".\n */\nexport function buildQuery(params: Record<string, QueryValue>): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const entry of value) search.append(key, entry);\n } else {\n search.append(key, String(value));\n }\n }\n const encoded = search.toString();\n return encoded ? `?${encoded}` : \"\";\n}\n\nasync function readServerDetail(response: Response): Promise<unknown> {\n try {\n return (await response.json()) as unknown;\n } catch {\n return undefined;\n }\n}\n\nasync function throwApiError(path: string, response: Response): Promise<never> {\n throw new MatrxApiError({\n status: response.status,\n path,\n serverDetail: await readServerDetail(response),\n });\n}\n\nexport interface JsonRequestOptions {\n method: \"GET\" | \"POST\";\n body?: unknown;\n signal?: AbortSignal;\n}\n\n/**\n * Execute a JSON request through the transport. Throws `MatrxApiError` on a\n * non-2xx response; resolves with the parsed JSON body otherwise.\n */\nexport async function requestJson<T>(\n transport: MatrxTransport,\n path: string,\n options: JsonRequestOptions,\n): Promise<T> {\n const hasBody = options.method !== \"GET\" && options.body !== undefined;\n const response = await transport.fetch(path, {\n method: options.method,\n headers: hasBody ? { \"Content-Type\": \"application/json\" } : {},\n ...(hasBody ? { body: JSON.stringify(options.body) } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (!response.ok) return throwApiError(path, response);\n return (await response.json()) as T;\n}\n\n/**\n * Options for every streaming call, riding the NDJSON kernel's contract.\n * Public via `./run`'s re-export.\n */\nexport interface MatrxStreamCallOptions {\n /** Abort the fetch and end the events iterator. */\n signal?: AbortSignal;\n /** Bounded background read-ahead (see `stream/ndjson`). */\n maxReadAhead?: number;\n /** Malformed NDJSON is non-fatal but must never disappear silently. */\n onMalformedLine?: (issue: MatrxNdjsonIssue) => void;\n /** Valid JSON with no recognized Matrx envelope. */\n onUnknownEnvelope?: (value: unknown) => void;\n /** Observe every valid envelope in its exact wire form. */\n onValidEnvelope?: (observation: MatrxStreamEnvelopeObservation) => void;\n}\n\n/**\n * A live agent run: the server-assigned ids (from response headers, available\n * BEFORE any event) and the normalized event stream. Public via `./run`.\n */\nexport interface MatrxRunHandle {\n /** `X-Request-ID` — the ONLY id `POST /ai/cancel/{request_id}` accepts. */\n requestId: string | null;\n /** `X-Conversation-ID` — the server's conversation identity. */\n conversationId: string | null;\n /** Normalized `{event, data}` envelopes through the ONE wire kernel. */\n events: AsyncGenerator<MatrxStreamEnvelope, void, undefined>;\n /** The raw response, for hosts that need headers/status beyond the ids. */\n response: Response;\n}\n\n/**\n * Wrap a validated streaming Response into the run handle — the ONE place\n * the id headers are read and the NDJSON kernel is attached (`./run` and\n * `./operations`' rejoin share it).\n */\nexport function toRunHandle(\n response: Response,\n options: MatrxStreamCallOptions,\n): MatrxRunHandle {\n return {\n requestId: response.headers.get(\"X-Request-ID\"),\n conversationId: response.headers.get(\"X-Conversation-ID\"),\n events: readMatrxNdjsonStream(response.body as ReadableStream<Uint8Array>, {\n ...(options.signal ? { signal: options.signal } : {}),\n ...(options.maxReadAhead !== undefined\n ? { maxReadAhead: options.maxReadAhead }\n : {}),\n ...(options.onMalformedLine\n ? { onMalformedLine: options.onMalformedLine }\n : {}),\n ...(options.onUnknownEnvelope\n ? { onUnknownEnvelope: options.onUnknownEnvelope }\n : {}),\n ...(options.onValidEnvelope\n ? { onValidEnvelope: options.onValidEnvelope }\n : {}),\n }),\n response,\n };\n}\n\nexport interface StreamRequestOptions {\n method: \"GET\" | \"POST\";\n body?: unknown;\n /** Extra wire-semantic headers (`Accept`, `Last-Event-ID`). */\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\n/**\n * Execute a streaming request. Throws `MatrxApiError` on a non-2xx response\n * (reading the error body as JSON when possible) or when a 2xx response\n * carries no body; resolves with the validated `Response` otherwise.\n */\nexport async function requestStream(\n transport: MatrxTransport,\n path: string,\n options: StreamRequestOptions,\n): Promise<Response> {\n const hasBody = options.method !== \"GET\" && options.body !== undefined;\n const response = await transport.fetch(path, {\n method: options.method,\n headers: {\n ...(hasBody ? { \"Content-Type\": \"application/json\" } : {}),\n ...options.headers,\n },\n ...(hasBody ? { body: JSON.stringify(options.body) } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (!response.ok) return throwApiError(path, response);\n if (!response.body) {\n throw new MatrxApiError({\n status: response.status,\n path,\n serverDetail: { code: \"missing_response_body\" },\n message: \"The streaming response carried no body.\",\n });\n }\n return response;\n}\n","/**\n * Agent run lifecycle against the AI Matrx API — start, continue, resume,\n * cancel — over the `MatrxTransport` port, with every streaming response\n * parsed through the package's ONE NDJSON wire kernel (`stream/ndjson`).\n *\n * Server truth (verified against aidream source):\n * - `POST /ai/agents/{agent_id}` — start (`aidream/api/routers/agents.py`)\n * - `POST /ai/conversations/{conversation_id}` — continue (`aidream/api/routers/conversations.py`)\n * - `POST /ai/conversations/{conversation_id}/resume` — resume after\n * client-delegated tool suspension (same router)\n * - `POST /ai/cancel/{request_id}?mode=interrupt` — cancel (`aidream/api/routers/cancel.py`)\n *\n * Response headers arrive before the body: `X-Conversation-ID` and\n * `X-Request-ID` are surfaced on the run handle immediately. `X-Request-ID`\n * is the ONLY id the server accepts for cancel — a client-local id means\n * nothing to it.\n *\n * Host policy stays out: no retry, no store, no timeouts, no persistence\n * (C10: no-persistence). Cancellation is the caller's `AbortSignal`; a client\n * disconnect never stops server work (`detach_on_disconnect`).\n */\n\nimport type { MatrxStreamEnvelope } from \"../stream/ndjson\";\nimport type {\n MatrxConversationStart,\n MatrxJsonObject,\n MatrxJsonValue,\n} from \"./conversation\";\nimport {\n encodePathSegment,\n buildQuery,\n requestJson,\n requestStream,\n toRunHandle,\n type MatrxRunHandle,\n type MatrxStreamCallOptions,\n} from \"./internal\";\nimport type { MatrxTransport } from \"./transport\";\n\nexport type { MatrxRunHandle, MatrxStreamCallOptions } from \"./internal\";\n\n// ─── Request shapes (mirroring the server's Pydantic models) ────────────────\n\n/**\n * Stable identity of the durable entity whose saved context owns a run —\n * the server reloads the row and uses ITS scope (`ContextAnchor`,\n * `aidream/services/conversation_context/scope.py`).\n */\nexport interface MatrxContextAnchor {\n resource_type: string;\n resource_id: string;\n}\n\n/**\n * Scope and source fields shared by every scoped request\n * (`ScopedRequest` / `AcceptsInjectedScope` server-side). All optional here;\n * the start request narrows `organization_id` to required.\n */\nexport interface MatrxRequestScope {\n organization_id?: string;\n project_id?: string | null;\n task_id?: string | null;\n /** Active context-scope ids from the client's global picker (membership-validated server-side). */\n scope_ids?: string[] | null;\n /** Active scope-TYPE ids — a type-level selection with no specific scope chosen. */\n active_scope_type_ids?: string[] | null;\n context_anchor?: MatrxContextAnchor | null;\n /** Stable application slug that initiated the request. */\n source_app?: string | null;\n /** Stable feature slug within the source application. */\n source_feature?: string | null;\n /** \"user\" = a person directly triggered this; \"auto\" = client automation; omit for API callers. */\n initiation?: \"user\" | \"auto\" | null;\n /** Specific connected desktop instance allowed to claim delegated local tools. */\n target_instance_id?: string | null;\n}\n\n/**\n * Fields shared by start/continue turn requests (tool injection, client\n * capability envelope, context object). The complex bags (`tools`, `client`,\n * `user`, `config_overrides`) are typed as JSON objects — their authoritative\n * schemas are the server's Pydantic models and the generated API types;\n * this package stays payload-agnostic about them by design.\n */\nexport interface MatrxTurnFields {\n /** What the human typed (string), or structured input parts. Never smuggle machine content here. */\n user_input?: string | MatrxJsonValue[] | null;\n /** Per-run model/config overrides (LLMParams shape). */\n config_overrides?: MatrxJsonObject | null;\n debug?: boolean;\n /** Additive tool specs merged into the agent's resolved tool set. */\n tools?: MatrxJsonObject[];\n /** When set, becomes the agent's ENTIRE tool set for the turn. */\n tools_replace?: MatrxJsonObject[] | null;\n /** Client capability envelope (`ClientContext`). */\n client?: MatrxJsonObject | null;\n /** Per-request user-level tool inclusion/exclusion overrides. */\n user?: MatrxJsonObject | null;\n /** Per-route context object, free-form by design. */\n context?: MatrxJsonObject;\n writable_variables?: string[];\n allow_context_create?: boolean;\n /** Request-snapshot capture override (tri-state; omit for the platform default). */\n snapshot?: boolean | null;\n}\n\n/**\n * `POST /ai/agents/{agent_id}` body (`AgentStartRequest` server-side).\n * The conversation-start triple is required by construction; `organization_id`\n * is required (the server 422s a blank one — it never manufactures an org).\n * `stream` is not accepted here: this client is the streaming path and always\n * sends `stream: true`.\n */\nexport type MatrxAgentStartRequest = MatrxConversationStart &\n Omit<MatrxRequestScope, \"organization_id\"> &\n MatrxTurnFields & {\n organization_id: string;\n /** Variable name → value map filling the agent's declared variables. */\n variables?: MatrxJsonObject | null;\n /** Run the versions table row instead of the live agent row. */\n is_version?: boolean;\n max_iterations?: number;\n max_retries_per_iteration?: number;\n };\n\n/**\n * `POST /ai/mandates/{mandate_key}` uses the exact saved-agent start body.\n * The server resolves the mandate's holder, binding, and configuration; a\n * client must offer only the declared variables and human input here.\n */\nexport type MatrxMandateStartRequest = MatrxAgentStartRequest;\n\n/** `POST /ai/conversations/{id}` body (`ConversationContinueRequest` server-side). */\nexport type MatrxConversationContinueRequest = MatrxRequestScope &\n MatrxTurnFields & {\n /** Re-run the conversation's current persisted state (recovery after a failed turn); omit `user_input`. */\n retry?: boolean;\n };\n\n/**\n * `POST /ai/conversations/{id}/resume` body (`ResumeRequest` server-side) —\n * the shipped durable continuation after client-delegated tool calls were\n * answered via `POST /tool_results` while the original stream was gone.\n * `user_request_id` is optional: when omitted the server resolves the turn\n * from the conversation's newest answered client-delegated tool call.\n * Re-send fresh `context` here — a resumed loop is otherwise context-blind.\n */\nexport type MatrxConversationResumeRequest = MatrxRequestScope & {\n user_request_id?: string | null;\n config_overrides?: MatrxJsonObject | null;\n debug?: boolean;\n tools?: MatrxJsonObject[];\n tools_replace?: MatrxJsonObject[] | null;\n client?: MatrxJsonObject | null;\n user?: MatrxJsonObject | null;\n context?: MatrxJsonObject;\n writable_variables?: string[];\n allow_context_create?: boolean;\n};\n\n/** `POST /ai/cancel/{request_id}` response (`CancelResponse` server-side). */\nexport interface MatrxCancelResponse {\n status: string;\n request_id: string;\n spine_executions_signalled: string[];\n}\n\n// ─── The run handle ─────────────────────────────────────────────────────────\n// `MatrxStreamCallOptions`, `MatrxRunHandle`, and the handle constructor live\n// in ./internal so `./operations`' rejoin shares the exact same construction.\n\nasync function streamCall(\n transport: MatrxTransport,\n path: string,\n body: object,\n options: MatrxStreamCallOptions,\n): Promise<MatrxRunHandle> {\n const response = await requestStream(transport, path, {\n method: \"POST\",\n // This client IS the streaming path — `stream: true` always, last so a\n // caller-supplied value can never flip the response off NDJSON.\n body: { ...body, stream: true },\n ...(options.signal ? { signal: options.signal } : {}),\n });\n return toRunHandle(response, options);\n}\n\n// ─── Lifecycle calls ────────────────────────────────────────────────────────\n\n/** Start an agent run: `POST /ai/agents/{agent_id}` (NDJSON stream). */\nexport function startAgentRun(\n transport: MatrxTransport,\n agentId: string,\n request: MatrxAgentStartRequest,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/agents/${encodePathSegment(agentId)}`,\n request,\n options,\n );\n}\n\n/**\n * Start a declared mandate: `POST /ai/mandates/{mandate_key}` (NDJSON\n * stream). This is deliberately separate from `startAgentRun`: callers name\n * the mandate and never resolve or echo its holder/configuration themselves.\n */\nexport function startMandateRun(\n transport: MatrxTransport,\n mandateKey: string,\n request: MatrxMandateStartRequest,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/mandates/${encodePathSegment(mandateKey)}`,\n request,\n options,\n );\n}\n\n/** Continue a stored conversation: `POST /ai/conversations/{id}` (NDJSON stream). */\nexport function continueAgentConversation(\n transport: MatrxTransport,\n conversationId: string,\n request: MatrxConversationContinueRequest,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}`,\n request,\n options,\n );\n}\n\n/**\n * Resume a suspended loop after delegated tool answers landed:\n * `POST /ai/conversations/{id}/resume` (NDJSON stream). A 409\n * (`resume_conflict`) means another resume holds the run claim — retrying is\n * host policy.\n */\nexport function resumeAgentConversation(\n transport: MatrxTransport,\n conversationId: string,\n request: MatrxConversationResumeRequest = {},\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}/resume`,\n request,\n options,\n );\n}\n\n/**\n * Stop a running request at its next iteration boundary:\n * `POST /ai/cancel/{request_id}`. Cooperative and best-effort — the in-flight\n * provider call finishes by design, and everything already streamed persists.\n * `mode: \"interrupt\"` = stop-and-fork: the tail after the last clean boundary\n * persists hidden so the user's follow-up replies to what they actually saw.\n * The id must be the server's `X-Request-ID`.\n */\nexport function cancelAgentRun(\n transport: MatrxTransport,\n requestId: string,\n options: { mode?: \"cancel\" | \"interrupt\"; signal?: AbortSignal } = {},\n): Promise<MatrxCancelResponse> {\n const query = buildQuery(\n options.mode === \"interrupt\" ? { mode: \"interrupt\" } : {},\n );\n return requestJson<MatrxCancelResponse>(\n transport,\n `/ai/cancel/${encodePathSegment(requestId)}${query}`,\n {\n method: \"POST\",\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n\n// ─── End-to-end convenience: run to completion ──────────────────────────────\n\n/**\n * A run that terminated unsuccessfully: the server emitted a fatal `error`\n * event, or the `user_request` completion settled `failed`/`cancelled`.\n */\nexport class MatrxRunError extends Error {\n override readonly name = \"MatrxRunError\";\n /** The verbatim `error` event payload, when one fired. */\n readonly errorPayload: Record<string, unknown> | null;\n /** The `user_request` completion status (`\"failed\"` | `\"cancelled\"`), when that was the trigger. */\n readonly completionStatus: string | null;\n /** Text streamed before the failure — partial content never vanishes. */\n readonly partialText: string;\n\n constructor(args: {\n message: string;\n errorPayload?: Record<string, unknown> | null;\n completionStatus?: string | null;\n partialText?: string;\n }) {\n super(args.message);\n this.errorPayload = args.errorPayload ?? null;\n this.completionStatus = args.completionStatus ?? null;\n this.partialText = args.partialText ?? \"\";\n }\n}\n\nexport interface MatrxCompletedRun {\n /** Accumulated `chunk` text (falls back to the completion's `result.output`). */\n text: string;\n requestId: string | null;\n conversationId: string | null;\n /** The `user_request` completion payload, verbatim, when one arrived. */\n completion: Record<string, unknown> | null;\n}\n\nexport interface RunAgentToCompletionOptions extends MatrxStreamCallOptions {\n /** Live progress: the full accumulated text after each chunk. */\n onChunk?: (fullText: string) => void;\n /** Every normalized envelope, before this helper interprets it. */\n onEvent?: (envelope: MatrxStreamEnvelope) => void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringField(value: unknown, key: string): string | null {\n if (!isRecord(value)) return null;\n const field = value[key];\n return typeof field === \"string\" && field ? field : null;\n}\n\n/**\n * Run an agent end-to-end and resolve with its full text output — the\n * package-level equivalent of the simplest existing host path\n * (`useRunAgent`): accumulate `chunk` text, treat a fatal `error` event or a\n * `failed`/`cancelled` `user_request` completion as a thrown `MatrxRunError`,\n * and fall back to the completion's `result.output` when no text streamed.\n *\n * The caller still owns the conversation-start triple on `request` — a\n * one-shot run typically uses `newEphemeralConversationStart()`.\n */\nexport async function runAgentToCompletion(\n transport: MatrxTransport,\n agentId: string,\n request: MatrxAgentStartRequest,\n options: RunAgentToCompletionOptions = {},\n): Promise<MatrxCompletedRun> {\n const handle = await startAgentRun(transport, agentId, request, options);\n\n let text = \"\";\n let completion: Record<string, unknown> | null = null;\n let failure: MatrxRunError | null = null;\n\n for await (const envelope of handle.events) {\n options.onEvent?.(envelope);\n\n if (envelope.event === \"chunk\") {\n const chunk = stringField(envelope.data, \"text\");\n if (chunk !== null) {\n text += chunk;\n options.onChunk?.(text);\n }\n continue;\n }\n\n if (envelope.event === \"error\" && failure === null) {\n const payload = isRecord(envelope.data) ? envelope.data : null;\n failure = new MatrxRunError({\n message:\n stringField(payload, \"user_message\") ??\n stringField(payload, \"message\") ??\n \"The agent run failed\",\n errorPayload: payload,\n partialText: text,\n });\n continue;\n }\n\n if (envelope.event !== \"completion\" || !isRecord(envelope.data)) continue;\n // `init`/`completion` pairs exist for five operations; the terminal\n // outcome of the run is the `user_request` completion (STREAM-CONTRACT\n // §3.2 — always present, always last).\n if (envelope.data.operation !== \"user_request\") continue;\n\n completion = envelope.data;\n const status = envelope.data.status;\n if ((status === \"failed\" || status === \"cancelled\") && failure === null) {\n const result = isRecord(envelope.data.result) ? envelope.data.result : null;\n failure = new MatrxRunError({\n message:\n stringField(result, \"error\") ??\n stringField(result, \"user_message\") ??\n `The agent run ${status}`,\n completionStatus: status,\n partialText: text,\n });\n }\n }\n\n if (failure) throw failure;\n\n if (!text && completion) {\n const result = completion.result;\n const output = stringField(result, \"output\");\n if (output !== null) text = output;\n }\n\n return {\n text,\n requestId: handle.requestId,\n conversationId: handle.conversationId,\n completion,\n };\n}\n","/**\n * Runtime operations — the canonical reconnect & resume read surface of the\n * execution spine, over the `MatrxTransport` port.\n *\n * Server truth (verified against aidream source,\n * `aidream/api/routers/runtime_operations.py` + `aidream/services/runtime/\n * reconnect.py`; mounted at bare `/runtime`):\n * - `GET /runtime/operations/{request_id}` — identify by `X-Request-ID`\n * - `GET /runtime/operations/by-link/{kind}/{id}` — identify by feature record\n * - `GET /runtime/executions/{id}/events` — durable seq-cursored page\n * - `GET /runtime/executions/{id}/events/stream` — SSE replay-then-follow,\n * `id:` = per-tree seq, reconnect with `Last-Event-ID`\n * - `POST /runtime/operations/{request_id}/rejoin` — replay + follow the\n * ORIGINAL NDJSON response while its detached task is alive (409 when live\n * delivery is unavailable — fall back to the durable lifecycle stream)\n *\n * The contract: identify → recover durable progress → follow live → re-query\n * the final result from the feature's own record. Token text is deliberately\n * never replayed on the lifecycle stream — that is what `/rejoin` is for.\n *\n * The SSE wire rides the package's own `stream/sse` kernel. This module owns\n * ONE connection's semantics (frames → typed events, cursor advancement,\n * terminal `end`); stall timers, retry budgets, and reconnect loops stay host\n * policy — every yielded item carries the cursor the next attempt resumes from.\n */\n\nimport { readMatrxSseStream, type MatrxSseFrame } from \"../stream/sse\";\nimport type { MatrxJsonObject } from \"./conversation\";\nimport {\n encodePathSegment,\n buildQuery,\n requestJson,\n requestStream,\n toRunHandle,\n type MatrxRunHandle,\n type MatrxStreamCallOptions,\n} from \"./internal\";\nimport { MatrxApiError, type MatrxTransport } from \"./transport\";\n\n// ─── Wire types (mirroring `aidream/services/runtime/reconnect.py`) ─────────\n\n/** `matrx_runtime.models.ExecutionStatus` — the only progress column. */\nexport type MatrxRuntimeExecutionStatus =\n | \"pending\"\n | \"running\"\n | \"paused\"\n | \"waiting_input\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\nexport const TERMINAL_MATRX_RUNTIME_STATUSES: ReadonlySet<MatrxRuntimeExecutionStatus> =\n new Set([\"completed\", \"failed\", \"cancelled\"]);\n\nconst RUNTIME_STATUSES: ReadonlySet<string> = new Set([\n \"pending\",\n \"running\",\n \"paused\",\n \"waiting_input\",\n \"completed\",\n \"failed\",\n \"cancelled\",\n]);\n\n/** One durable spine event on the wire (`OperationEvent`) — `seq` is the reconnect cursor. */\nexport interface MatrxRuntimeOperationEvent {\n seq: number | null;\n /** Lifecycle vocabulary: created | started | paused | resumed | waiting_input | completed | failed | cancelled | checkpoint_saved | note. */\n kind: string;\n execution_id: string;\n root_execution_id: string | null;\n detail: MatrxJsonObject | null;\n created_at: string | null;\n}\n\n/** One root execution as a reconnecting client sees it (`OperationView`). */\nexport interface MatrxRuntimeOperationView {\n execution_id: string;\n /** Durable request identity — feeds `/rejoin` and no-prompt resume recovery. */\n request_id: string | null;\n type: string;\n status: MatrxRuntimeExecutionStatus;\n is_terminal: boolean;\n waiting_input: boolean;\n /** Decimal on the wire — may arrive as number or string; display-only. */\n cost: number | string;\n meters: Record<string, number | string>;\n link_kind: string | null;\n link_id: string | null;\n error: MatrxJsonObject | null;\n created_at: string | null;\n started_at: string | null;\n ended_at: string | null;\n last_event_seq: number;\n events_path: string;\n stream_path: string;\n}\n\nexport interface MatrxOperationStatusResponse {\n request_id: string;\n operation_count: number;\n operations: MatrxRuntimeOperationView[];\n}\n\nexport interface MatrxOperationsByLinkResponse {\n link_kind: string;\n link_id: string;\n operation_count: number;\n operations: MatrxRuntimeOperationView[];\n}\n\nexport interface MatrxOperationEventsPage {\n execution_id: string;\n root_execution_id: string;\n events: MatrxRuntimeOperationEvent[];\n /** Feeds the next page or the SSE `Last-Event-ID` — polling and push share ONE cursor. */\n next_after_seq: number;\n has_more: boolean;\n root_status: MatrxRuntimeExecutionStatus;\n root_is_terminal: boolean;\n}\n\n// ─── Identify + durable progress ────────────────────────────────────────────\n\n/**\n * Where is my operation? Resolves an `X-Request-ID` to its root execution(s).\n * Returns null on 404 — missing and unowned share one shape by design\n * (existence is never leaked).\n */\nexport async function getRuntimeOperationStatus(\n transport: MatrxTransport,\n requestId: string,\n options: { signal?: AbortSignal } = {},\n): Promise<MatrxOperationStatusResponse | null> {\n try {\n return await requestJson<MatrxOperationStatusResponse>(\n transport,\n `/runtime/operations/${encodePathSegment(requestId)}`,\n { method: \"GET\", ...(options.signal ? { signal: options.signal } : {}) },\n );\n } catch (error) {\n if (error instanceof MatrxApiError && error.status === 404) return null;\n throw error;\n }\n}\n\n/**\n * Operations for a feature record — e.g. `(\"conversation\", conversationId)`,\n * `(\"workflow\", runId)`, `(\"agent_run\", runId)`. Newest first; unowned trees\n * omitted. Returns null on 404 (surface absent, or the caller owns nothing —\n * one shape by design).\n */\nexport async function getRuntimeOperationsByLink(\n transport: MatrxTransport,\n linkKind: string,\n linkId: string,\n options: { limit?: number; signal?: AbortSignal } = {},\n): Promise<MatrxOperationsByLinkResponse | null> {\n const query = buildQuery(\n options.limit !== undefined ? { limit: options.limit } : {},\n );\n try {\n return await requestJson<MatrxOperationsByLinkResponse>(\n transport,\n `/runtime/operations/by-link/${encodePathSegment(linkKind)}/${encodePathSegment(linkId)}${query}`,\n { method: \"GET\", ...(options.signal ? { signal: options.signal } : {}) },\n );\n } catch (error) {\n if (error instanceof MatrxApiError && error.status === 404) return null;\n throw error;\n }\n}\n\n/**\n * Durable progress page for the whole operation TREE:\n * `GET /runtime/executions/{id}/events?after_seq=…`. Pass any node id — it\n * resolves to the root.\n */\nexport function listRuntimeOperationEvents(\n transport: MatrxTransport,\n executionId: string,\n options: {\n afterSeq?: number;\n limit?: number;\n /** Repeatable event-kind filter. */\n kinds?: readonly string[];\n signal?: AbortSignal;\n } = {},\n): Promise<MatrxOperationEventsPage> {\n const query = buildQuery({\n ...(options.afterSeq !== undefined ? { after_seq: options.afterSeq } : {}),\n ...(options.limit !== undefined ? { limit: options.limit } : {}),\n ...(options.kinds !== undefined ? { kind: options.kinds } : {}),\n });\n return requestJson<MatrxOperationEventsPage>(\n transport,\n `/runtime/executions/${encodePathSegment(executionId)}/events${query}`,\n { method: \"GET\", ...(options.signal ? { signal: options.signal } : {}) },\n );\n}\n\n// ─── SSE follow (replay-then-follow with Last-Event-ID) ─────────────────────\n\n/**\n * One item from the follow stream. Every item carries `cursor` — the highest\n * event seq seen so far, which is exactly the `Last-Event-ID` a reconnect\n * resumes from (host retry policy owns the reconnect loop).\n */\nexport type MatrxOperationFollowEvent =\n | {\n /** A parsed durable spine event. */\n type: \"event\";\n event: MatrxRuntimeOperationEvent;\n /** The frame's SSE `id:` as an integer, when it carried one. */\n seq: number | null;\n cursor: number;\n }\n | {\n /**\n * A frame that carried no deliverable event — a comment heartbeat, an\n * unknown event name, or a malformed payload (also surfaced through\n * `onMalformedFrame`). ANY parsed frame proves the wire is alive: hosts\n * reset stall timers and retry budgets on it.\n */\n type: \"liveness\";\n cursor: number;\n }\n | {\n /** The server's terminal frame — the root settled; the stream is over. */\n type: \"end\";\n status: MatrxRuntimeExecutionStatus | null;\n cursor: number;\n };\n\nexport interface FollowRuntimeOperationOptions {\n /** Resume cursor — the operation view's `last_event_seq` (0 = from start). */\n lastEventSeq?: number;\n /** Abort the follow — the generator simply ends. */\n signal?: AbortSignal;\n /** A frame whose payload failed to parse — never silently dropped. */\n onMalformedFrame?: (frame: MatrxSseFrame, error: unknown) => void;\n /** Unterminated trailing SSE text at stream end (diagnostic, never an event). */\n onIncomplete?: (text: string) => void;\n}\n\nfunction parseEndStatus(data: string | null): MatrxRuntimeExecutionStatus | null {\n if (data === null) return null;\n try {\n const parsed = JSON.parse(data) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n typeof (parsed as { status?: unknown }).status === \"string\"\n ) {\n const status = (parsed as { status: string }).status;\n return RUNTIME_STATUSES.has(status)\n ? (status as MatrxRuntimeExecutionStatus)\n : null;\n }\n } catch {\n // malformed end payload — still terminal\n }\n return null;\n}\n\n/**\n * Follow ONE SSE connection of an operation's lifecycle stream:\n * `GET /runtime/executions/{id}/events/stream` with `Last-Event-ID` when\n * resuming past 0. Replays from the cursor, then follows live; a\n * WAITING_INPUT park keeps it open (a resume re-attaches to the same\n * execution and its events continue here). Ends after yielding\n * `{type: \"end\"}` when the root settles; a server close WITHOUT an end frame\n * simply ends the generator — reconnect from the last yielded `cursor` (host\n * retry policy).\n */\nexport async function* followRuntimeOperationEvents(\n transport: MatrxTransport,\n executionId: string,\n options: FollowRuntimeOperationOptions = {},\n): AsyncGenerator<MatrxOperationFollowEvent, void, undefined> {\n let cursor = options.lastEventSeq ?? 0;\n\n const headers: Record<string, string> = { Accept: \"text/event-stream\" };\n if (cursor > 0) headers[\"Last-Event-ID\"] = String(cursor);\n\n const response = await requestStream(\n transport,\n `/runtime/executions/${encodePathSegment(executionId)}/events/stream`,\n {\n method: \"GET\",\n headers,\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n\n const frames = readMatrxSseStream(\n response.body as ReadableStream<Uint8Array>,\n options.onIncomplete ? { onIncomplete: options.onIncomplete } : {},\n );\n\n for await (const frame of frames) {\n if (frame.event === \"end\") {\n yield { type: \"end\", status: parseEndStatus(frame.data), cursor };\n return;\n }\n if (frame.event === \"execution_event\" && frame.data !== null) {\n let event: MatrxRuntimeOperationEvent;\n try {\n event = JSON.parse(frame.data) as MatrxRuntimeOperationEvent;\n } catch (error) {\n options.onMalformedFrame?.(frame, error);\n yield { type: \"liveness\", cursor };\n continue;\n }\n if (frame.seq !== null && frame.seq > cursor) cursor = frame.seq;\n yield { type: \"event\", event, seq: frame.seq, cursor };\n continue;\n }\n // Comment heartbeats, unknown event names, data-less frames: liveness.\n yield { type: \"liveness\", cursor };\n }\n}\n\n// ─── Follow to end (the production reconnect policy) ────────────────────────\n\nexport interface FollowRuntimeOperationToEndOptions {\n /** Resume cursor — the operation view's `last_event_seq` (0 = from start). */\n lastEventSeq?: number;\n /** Caller teardown — aborting resolves with `ended: false`. */\n signal?: AbortSignal;\n /**\n * The server pings every ~15s, so a wire that is open but silent past this\n * is dead (buffering proxy, idle-killed connection) — abort the attempt and\n * retry rather than hanging forever. Default 45_000.\n */\n stallTimeoutMs?: number;\n /**\n * Consecutive failed attempts before giving up. A single-server deployment\n * deliberately drains for 60s, then starts a new container — the default\n * budget (60 × 2s) keeps following for ~three minutes so the runtime ledger\n * can bridge that handoff. ANY parsed frame resets the budget. Default 60.\n */\n reconnectLimit?: number;\n /** Delay between attempts. Default 2_000. */\n reconnectDelayMs?: number;\n /** Fired per durable spine event (lifecycle transitions + notes). */\n onEvent: (event: MatrxRuntimeOperationEvent, seq: number | null) => void;\n /** A failed attempt (never silently swallowed when provided). */\n onAttemptError?: (error: unknown) => void;\n /** A frame whose payload failed to parse (the ledger heals gaps on reconnect). */\n onMalformedFrame?: (frame: MatrxSseFrame, error: unknown) => void;\n}\n\nexport interface FollowRuntimeOperationToEndResult {\n /** True when the server sent the terminal `end` frame. */\n ended: boolean;\n /** The root status carried on the `end` frame (when `ended`). */\n status: MatrxRuntimeExecutionStatus | null;\n}\n\n/**\n * Follow an operation's lifecycle stream TO ITS END — the full production\n * reconnect policy over `followRuntimeOperationEvents`: replay-then-follow\n * with bounded reconnects, a stall watchdog, and durable `Last-Event-ID`\n * cursor advancement across attempts.\n *\n * Resolves `{ended: true, status}` on the server's `end` frame (the operation\n * settled); `{ended: false}` when the caller aborted or every reconnect\n * attempt failed. A WAITING_INPUT park keeps the stream open by design — a\n * resume re-attaches to the same execution and its events continue arriving\n * on the same cursor. Any parsed frame — comment heartbeats included —\n * proves the wire is alive and resets both the stall timer and the retry\n * budget.\n */\nexport async function followRuntimeOperationToEnd(\n transport: MatrxTransport,\n executionId: string,\n options: FollowRuntimeOperationToEndOptions,\n): Promise<FollowRuntimeOperationToEndResult> {\n const stallTimeoutMs = options.stallTimeoutMs ?? 45_000;\n const reconnectLimit = options.reconnectLimit ?? 60;\n const reconnectDelayMs = options.reconnectDelayMs ?? 2_000;\n const outer = options.signal;\n\n let cursor = options.lastEventSeq ?? 0;\n let failures = 0;\n\n while (!outer?.aborted && failures < reconnectLimit) {\n const attempt = new AbortController();\n const onOuterAbort = () => attempt.abort();\n outer?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\n let stallTimer: ReturnType<typeof setTimeout> | null = null;\n const armStall = () => {\n if (stallTimer !== null) clearTimeout(stallTimer);\n stallTimer = setTimeout(() => attempt.abort(), stallTimeoutMs);\n };\n\n try {\n const items = followRuntimeOperationEvents(transport, executionId, {\n lastEventSeq: cursor,\n signal: attempt.signal,\n ...(options.onMalformedFrame\n ? { onMalformedFrame: options.onMalformedFrame }\n : {}),\n });\n\n armStall();\n for await (const item of items) {\n armStall();\n failures = 0;\n cursor = item.cursor;\n if (item.type === \"end\") {\n return { ended: true, status: item.status };\n }\n if (item.type === \"event\") {\n options.onEvent(item.event, item.seq);\n }\n }\n // Server closed without an `end` frame (e.g. process restart). Retry —\n // `Last-Event-ID` replays anything missed from the durable ledger.\n failures += 1;\n } catch (error) {\n if (outer?.aborted) break;\n failures += 1;\n options.onAttemptError?.(error);\n } finally {\n if (stallTimer !== null) clearTimeout(stallTimer);\n outer?.removeEventListener(\"abort\", onOuterAbort);\n }\n\n if (!outer?.aborted && failures < reconnectLimit) {\n await new Promise((r) => setTimeout(r, reconnectDelayMs));\n }\n }\n\n return { ended: false, status: null };\n}\n\n// ─── NDJSON rejoin (replay the original response) ───────────────────────────\n\n/**\n * Rejoin the ORIGINAL NDJSON response while its detached task is still alive:\n * `POST /runtime/operations/{request_id}/rejoin`. Replays the response from\n * frame one, then continues live — every frame is sequence-stamped\n * (`stream_seq`), so a same-page reconnect can drop frames it already\n * rendered. Throws `MatrxApiError` with status 409 when live delivery is\n * unavailable — fall back to `followRuntimeOperationEvents` + a final record\n * re-query. The `requestId` must be the server's `X-Request-ID`.\n */\nexport async function rejoinRuntimeOperation(\n transport: MatrxTransport,\n requestId: string,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n const response = await requestStream(\n transport,\n `/runtime/operations/${encodePathSegment(requestId)}/rejoin`,\n {\n method: \"POST\",\n // The route takes no body model; the reference client posts an empty\n // JSON object. Match it so proxies see an ordinary JSON POST.\n body: {},\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n return toRunHandle(response, options);\n}\n","/**\n * Delegated client tools — submit results and discover pending calls.\n *\n * Server truth (verified against aidream source,\n * `aidream/api/routers/conversations.py` + `aidream/services/ai_execution/\n * tool_results.py`):\n * - `POST /ai/conversations/{id}/tool_results` — durable, idempotent submit.\n * A delegated tool call HARD-SUSPENDS the loop; when the last outstanding\n * delegated row for the user_request resolves, the response carries\n * `continuation_needed: true` and the owning `user_request_id` — the signal\n * to open `resumeAgentConversation`. `continuation_needed` is best-effort:\n * parallel submits can both see `true`; `/resume` takes an atomic run claim\n * and the loser gets a 409.\n * - `GET /ai/conversations/{id}/pending_calls` — delegated calls awaiting the\n * user in one conversation (rows survive disconnects and reloads).\n * - `GET /ai/user/pending_calls` — every pending call for this user; an\n * optional `instance_id` atomically claims them for a desktop instance.\n *\n * A 404 from the submit means EVERY call_id was unknown (duplicate/expired);\n * partial success returns 200 with `not_found` populated. Batching, retries,\n * and the resume handoff are host policy — this module is the wire.\n */\n\nimport type { MatrxJsonObject, MatrxJsonValue } from \"./conversation\";\nimport { encodePathSegment, buildQuery, requestJson } from \"./internal\";\nimport type { MatrxTransport } from \"./transport\";\n\n/** One client tool answer (`ClientToolResult` server-side). */\nexport interface MatrxClientToolResult {\n call_id: string;\n tool_name: string;\n /** Tool output — inherently polymorphic; recursive JSON by design. */\n output?: MatrxJsonValue | null;\n is_error?: boolean;\n error_message?: string | null;\n /** Client-measured execution time in ms. */\n duration_ms?: number | null;\n}\n\n/** `POST /tool_results` response (`ToolResultsResponse` server-side). */\nexport interface MatrxToolResultsResponse {\n resolved: string[];\n already_resolved: string[];\n not_found: string[];\n /** True when the original stream is gone and no delegated calls remain — open `/resume`. */\n continuation_needed: boolean;\n user_request_id: string | null;\n conversation_id: string;\n}\n\n/** One delegated call awaiting an answer (`PendingCallSummary` server-side). */\nexport interface MatrxPendingCallSummary {\n id: string;\n call_id: string;\n conversation_id: string;\n user_request_id: string | null;\n message_id: string | null;\n tool_name: string;\n /** Tool-call argument bag — schema is per-tool (its input_schema). */\n arguments: MatrxJsonObject;\n iteration: number;\n created_at: string | null;\n expires_at: string | null;\n target_instance_id: string | null;\n claimed_by_instance_id: string | null;\n claim_expires_at: string | null;\n execution_authorization: MatrxJsonObject | null;\n}\n\n/**\n * Submit client tool results: `POST /ai/conversations/{id}/tool_results`.\n * Idempotent — duplicate submits return 200 with the ids in\n * `already_resolved`. Throws `MatrxApiError` (status 404) when every call_id\n * was unknown or expired; the stream stays alive in that case.\n */\nexport function submitAgentToolResults(\n transport: MatrxTransport,\n conversationId: string,\n results: MatrxClientToolResult[],\n options: { instanceId?: string; signal?: AbortSignal } = {},\n): Promise<MatrxToolResultsResponse> {\n return requestJson<MatrxToolResultsResponse>(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}/tool_results`,\n {\n method: \"POST\",\n body: {\n results,\n ...(options.instanceId !== undefined\n ? { instance_id: options.instanceId }\n : {}),\n },\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n\n/**\n * Discover delegated calls awaiting the user in one conversation:\n * `GET /ai/conversations/{id}/pending_calls`. Safe to call on every\n * conversation load; a non-empty list should be surfaced exactly as if the\n * original stream had delivered the `tool_delegated` events live.\n */\nexport function listConversationPendingToolCalls(\n transport: MatrxTransport,\n conversationId: string,\n options: { signal?: AbortSignal } = {},\n): Promise<MatrxPendingCallSummary[]> {\n return requestJson<MatrxPendingCallSummary[]>(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}/pending_calls`,\n {\n method: \"GET\",\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n\n/**\n * Discover every delegated call awaiting this user across all conversations:\n * `GET /ai/user/pending_calls`. Passing `instanceId` atomically CLAIMS the\n * calls for that desktop instance — only pass it from a client that will\n * actually execute them.\n */\nexport function listUserPendingToolCalls(\n transport: MatrxTransport,\n options: { instanceId?: string; signal?: AbortSignal } = {},\n): Promise<MatrxPendingCallSummary[]> {\n const query = buildQuery(\n options.instanceId !== undefined ? { instance_id: options.instanceId } : {},\n );\n return requestJson<MatrxPendingCallSummary[]>(\n transport,\n `/ai/user/pending_calls${query}`,\n {\n method: \"GET\",\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n","/**\n * Media reference roles — the builder's side of the one vocabulary.\n *\n * Image generation reads an image as subject / character / style / mask /\n * edit target / composition. Video generation reads an image as first frame /\n * last frame / asset / style, a video as extend / restyle, and an audio clip as\n * lip sync; an asset/style image or a reference video may carry a `name` the\n * prompt addresses as `@name` (server: `matrx_ai/media/video_reference_roles.py`).\n *\n * A reference image in an image-generation request says what it controls.\n * The role rides on the image block itself (`role` on the image part); absent\n * = a plain image the model sees. The server owns the wire mapping and the\n * refusal gate (aidream `matrx_ai/media/image_reference_roles.py`); this module\n * mirrors its vocabulary and limits so the builder can tell the truth BEFORE a\n * run: a role the selected model cannot take is shown greyed with the reason.\n *\n * Limits come from the catalog: the routing offering's\n * `capabilities_override.image_reference_roles` (`{role: max, total: n}`).\n * Law: `common-docs/systems/agents/typed-messages/FEATURE.md` (Image generation).\n * Home: `@ai-matrx/agents` (moved from matrx-frontend `features/agents/image-roles/roles.ts`).\n */\n\n/** The roles an IMAGE-generating model reads an image as (vocabulary order). */\nexport const IMAGE_REFERENCE_ROLES = [\n \"subject\",\n \"character\",\n \"style\",\n \"mask\",\n \"edit_target\",\n \"composition_control\",\n] as const;\n\n/** The roles a VIDEO-generating model reads an image as (`style` is shared). */\nexport const VIDEO_IMAGE_ROLES = [\n \"first_frame\",\n \"last_frame\",\n \"asset\",\n \"style\",\n] as const;\n\n/** Roles on a video part beside a video prompt. */\nexport const VIDEO_REFERENCE_ROLES = [\"extend\", \"restyle\"] as const;\n\n/** Roles on an audio part beside a video prompt. */\nexport const AUDIO_REFERENCE_ROLES = [\"lip_sync\"] as const;\n\nexport type ImageReferenceRole =\n | (typeof IMAGE_REFERENCE_ROLES)[number]\n | (typeof VIDEO_IMAGE_ROLES)[number];\nexport type VideoReferenceRole = (typeof VIDEO_REFERENCE_ROLES)[number];\nexport type AudioReferenceRole = (typeof AUDIO_REFERENCE_ROLES)[number];\n/** Any role a media part can carry — one union, one metadata table. */\nexport type ReferenceRole =\n | ImageReferenceRole\n | VideoReferenceRole\n | AudioReferenceRole;\n\nconst ALL_IMAGE_ROLES: readonly string[] = [\n ...IMAGE_REFERENCE_ROLES,\n ...VIDEO_IMAGE_ROLES,\n];\n\nexport interface ImageRoleMeta {\n /** Segment label — plain words, never the wire token. */\n label: string;\n /** What the run form asks for when a variable fills this role. */\n ask: string;\n /** One line: what the model does with an image in this role. */\n explanation: string;\n}\n\nexport const IMAGE_ROLE_META: Record<ReferenceRole, ImageRoleMeta> = {\n subject: {\n label: \"Subject\",\n ask: \"Subject reference\",\n explanation:\n \"Keeps this exact product or object recognisable: shape, materials, labels.\",\n },\n character: {\n label: \"Character\",\n ask: \"Character reference\",\n explanation: \"Keeps this person or character looking the same.\",\n },\n style: {\n label: \"Style\",\n ask: \"Style reference\",\n explanation:\n \"Borrows only the look (colours, lighting, medium), never the content.\",\n },\n mask: {\n label: \"Mask\",\n ask: \"Mask\",\n explanation:\n \"Marks the only area of the edited image that is allowed to change.\",\n },\n edit_target: {\n label: \"Edit this\",\n ask: \"Image to edit\",\n explanation: \"The image being edited; everything not asked for stays the same.\",\n },\n composition_control: {\n label: \"Composition\",\n ask: \"Composition reference\",\n explanation: \"Follows its layout, pose and geometry, not its appearance.\",\n },\n first_frame: {\n label: \"First frame\",\n ask: \"First frame\",\n explanation: \"The video starts on exactly this image.\",\n },\n last_frame: {\n label: \"Last frame\",\n ask: \"Last frame\",\n explanation: \"The video ends on exactly this image (needs a first frame).\",\n },\n asset: {\n label: \"Asset\",\n ask: \"Asset reference\",\n explanation:\n \"Keeps this product, object or character recognisable throughout the clip.\",\n },\n extend: {\n label: \"Extend\",\n ask: \"Video to extend\",\n explanation: \"The new clip continues this video from its last frame.\",\n },\n restyle: {\n label: \"Restyle\",\n ask: \"Reference video\",\n explanation: \"Re-renders this video: same motion and timing, a new look.\",\n },\n lip_sync: {\n label: \"Lip sync\",\n ask: \"Lip-sync audio\",\n explanation: \"The speech the on-screen face mouths, word for word.\",\n },\n};\n\n/** Which roles a block of this kind offers for this output modality. */\nexport function rolesFor(\n blockKind: \"image\" | \"video\" | \"audio\",\n output: \"image\" | \"video\",\n): readonly ReferenceRole[] {\n if (output === \"image\") return blockKind === \"image\" ? IMAGE_REFERENCE_ROLES : [];\n if (blockKind === \"image\") return VIDEO_IMAGE_ROLES;\n if (blockKind === \"video\") return VIDEO_REFERENCE_ROLES;\n return AUDIO_REFERENCE_ROLES;\n}\n\n/** Roles whose reference may carry a name the prompt addresses as `@name`. */\nexport function roleTakesName(role: ReferenceRole | null | undefined): boolean {\n return role === \"asset\" || role === \"style\" || role === \"restyle\" || role === \"extend\";\n}\n\n/** `@name` rule shared with the server (media/video_reference_roles.py). */\nexport function normalizeReferenceName(raw: string): string | null {\n const candidate = raw.trim().replace(/^@/, \"\");\n if (!candidate) return null;\n return /^[A-Za-z][A-Za-z0-9_-]{0,31}$/.test(candidate) ? candidate : null;\n}\n\nexport function isReferenceRole(value: unknown): value is ReferenceRole {\n return typeof value === \"string\" && value in IMAGE_ROLE_META;\n}\n\nexport function isImageReferenceRole(value: unknown): value is ImageReferenceRole {\n return typeof value === \"string\" && ALL_IMAGE_ROLES.includes(value);\n}\n\n/**\n * `{role: max, total: n, named: n}` — image roles from\n * `capabilities_override.image_reference_roles`, video/audio roles and the\n * named-reference cap from `capabilities_override.video_reference_roles`.\n * Empty = the model takes no roled reference.\n */\nexport type ImageRoleLimits = Partial<Record<ReferenceRole | \"total\" | \"named\", number>>;\n\nfunction readLimitMap(\n source: unknown,\n accept: (key: string) => boolean,\n out: ImageRoleLimits,\n): void {\n if (typeof source !== \"object\" || source === null || Array.isArray(source)) return;\n for (const [key, value] of Object.entries(source)) {\n if (\n accept(key) &&\n typeof value === \"number\" &&\n Number.isInteger(value) &&\n value >= 0\n ) {\n out[key as keyof ImageRoleLimits] = value;\n }\n }\n}\n\n/** Read the offering's role limits (image + video maps) defensively. */\nexport function readImageRoleLimits(raw: unknown): ImageRoleLimits {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return {};\n const record = raw as Record<string, unknown>;\n const out: ImageRoleLimits = {};\n readLimitMap(\n record.image_reference_roles,\n (k) => isImageReferenceRole(k) || k === \"total\",\n out,\n );\n readLimitMap(\n record.video_reference_roles,\n (k) =>\n (VIDEO_REFERENCE_ROLES as readonly string[]).includes(k) ||\n (AUDIO_REFERENCE_ROLES as readonly string[]).includes(k) ||\n k === \"named\",\n out,\n );\n return out;\n}\n\nexport type ImageRoleVerdict =\n | { verdict: \"ok\" }\n | { verdict: \"refused\"; reason: string };\n\n/**\n * Can this model take an image in this role? The reason is a sentence a\n * person can act on; it names the role and the model, like the server's\n * refusal does.\n */\nexport function imageRoleVerdict(\n role: ReferenceRole,\n limits: ImageRoleLimits,\n modelLabel: string,\n countOfRole = 1,\n): ImageRoleVerdict {\n const label = IMAGE_ROLE_META[role].label;\n const noun = (VIDEO_REFERENCE_ROLES as readonly string[]).includes(role)\n ? \"video\"\n : role === \"lip_sync\"\n ? \"audio clip\"\n : ALL_IMAGE_ROLES.includes(role) &&\n !(IMAGE_REFERENCE_ROLES as readonly string[]).includes(role)\n ? \"image\"\n : \"reference image\";\n const allowed = limits[role] ?? 0;\n if (allowed <= 0) {\n return {\n verdict: \"refused\",\n reason: `${modelLabel} cannot take a ${label} ${noun}. Pick another role or another model.`,\n };\n }\n if (countOfRole > allowed) {\n return {\n verdict: \"refused\",\n reason: `${modelLabel} takes at most ${allowed} ${label} ${noun}${allowed === 1 ? \"\" : \"s\"}; this message has ${countOfRole}.`,\n };\n }\n return { verdict: \"ok\" };\n}\n\n/** Can this model take a named (`@name`) reference at all? */\nexport function namedReferenceVerdict(\n limits: ImageRoleLimits,\n modelLabel: string,\n): ImageRoleVerdict {\n return (limits.named ?? 0) > 0\n ? { verdict: \"ok\" }\n : {\n verdict: \"refused\",\n reason: `${modelLabel} cannot take named references. Clear the name, or pick a model with named elements.`,\n };\n}\n\n/** The variable an image block is filled by, when its url is exactly `{{name}}`. */\nexport function variableNameOfImageUrl(url: unknown): string | null {\n return variableNameOfMediaUrl(url);\n}\n\n/** The variable any media block (image, video, audio) is filled by. */\nexport function variableNameOfMediaUrl(url: unknown): string | null {\n if (typeof url !== \"string\") return null;\n const match = /^\\s*\\{\\{\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}\\s*$/.exec(url);\n return match?.[1] ?? null;\n}\n\n/**\n * The one-line caption a REDISPLAYED reference shows — \"Subject reference\",\n * \"Style reference · @brand\". Shared by the attachment chip and the inline\n * image/video block so a role set in the builder is never lost on reload. An\n * unrecognised role string is shown as-is (honest) rather than dropped.\n */\nexport function referenceRoleCaption(role: unknown, name: unknown): string | null {\n const roleLabel =\n typeof role === \"string\" && role\n ? isReferenceRole(role)\n ? IMAGE_ROLE_META[role].ask\n : role\n : null;\n const refName = typeof name === \"string\" ? normalizeReferenceName(name) : null;\n if (!roleLabel && !refName) return null;\n return [roleLabel, refName ? `@${refName}` : null].filter(Boolean).join(\" · \");\n}\n","/**\n * Run inputs — the ONE derivation from an agent's variable definitions to the\n * inputs a run surface asks for.\n *\n * Every surface that runs an agent (the run page and chat composer, Agent\n * Battle's shared request, a Workflow Studio Step node) asks the same\n * questions in the same order: content inputs first, then bound model\n * controls in a \"Settings\" group; a media variable that fills a reference role\n * is asked for BY that role (\"Style reference\"); a control keeps the catalog\n * component the builder stamped on it. A speech-script variable is an ordinary\n * content variable — its `{{name}}` lives in a turn's text.\n *\n * Canonical doc: common-docs/systems/agents/typed-messages/FEATURE.md.\n */\n\nimport {\n IMAGE_ROLE_META,\n isReferenceRole,\n type ReferenceRole,\n} from \"./reference-roles\";\n\n/** The minimum variable shape this derivation reads (a superset is fine). */\nexport interface RunInputVariable {\n name: string;\n defaultValue?: unknown;\n helpText?: string | null;\n required?: boolean | null;\n customComponent?: {\n type?: string | null;\n options?: readonly string[] | null;\n imageRole?: unknown;\n min?: number | null;\n max?: number | null;\n step?: number | null;\n toggleValues?: readonly [string, string] | readonly string[] | null;\n } | null;\n control?: { key?: string | null } | null;\n}\n\nexport type RunInputGroup = \"content\" | \"settings\";\n\nexport type RunInputMediaKind = \"image\" | \"video\" | \"audio\" | \"document\" | \"youtube\";\n\nconst MEDIA_KINDS: readonly string[] = [\"image\", \"video\", \"audio\", \"document\", \"youtube\"];\n\nexport interface RunInput<V extends RunInputVariable = RunInputVariable> {\n name: string;\n /** What the form asks: the role's ask for a roled media input, else the formatted name. */\n label: string;\n /** The variable's help text, else the role's one-line explanation. */\n hint: string | undefined;\n group: RunInputGroup;\n required: boolean;\n /** The component type the builder chose (`textarea` when none). */\n component: string;\n options: readonly string[] | undefined;\n /** Set when this input takes a file / media reference. */\n mediaKind: RunInputMediaKind | null;\n /** The reference role a media input fills (subject, style, first_frame, …). */\n role: ReferenceRole | null;\n /** The model control this input IS (aspect_ratio, quality, voice, …). */\n controlKey: string | null;\n variable: V;\n}\n\nexport function isControlVariable(def: RunInputVariable): boolean {\n return typeof def.control?.key === \"string\" && def.control.key.length > 0;\n}\n\n/** Content inputs first, bound controls after — stable within each group. */\nexport function partitionControlVariables<T extends RunInputVariable>(\n defs: readonly T[],\n): { content: T[]; settings: T[] } {\n const content: T[] = [];\n const settings: T[] = [];\n for (const d of defs) (isControlVariable(d) ? settings : content).push(d);\n return { content, settings };\n}\n\n/** The order every variable form renders in. Returns the same array when already ordered. */\nexport function orderVariablesForForm<T extends RunInputVariable>(defs: T[]): T[] {\n const { content, settings } = partitionControlVariables(defs);\n if (settings.length === 0) return defs;\n const ordered = [...content, ...settings];\n return ordered.every((d, i) => d === defs[i]) ? defs : ordered;\n}\n\nfunction roleOf(variable: RunInputVariable): ReferenceRole | null {\n const type = variable.customComponent?.type;\n const role = variable.customComponent?.imageRole;\n const roled = type === \"image\" || type === \"video\" || type === \"audio\";\n return roled && isReferenceRole(role) ? role : null;\n}\n\n/**\n * The label a run form shows for a variable: a media variable that fills a\n * reference role is asked for BY that role (\"Style reference\"); every other\n * variable keeps its formatted name.\n */\nexport function variableRunLabel(\n variable: RunInputVariable,\n formatName: (name: string) => string,\n): string {\n const role = roleOf(variable);\n return role ? IMAGE_ROLE_META[role].ask : formatName(variable.name);\n}\n\n/** The hint under / beside a variable: its own help text, else the role's line. */\nexport function variableRunHint(variable: RunInputVariable): string | undefined {\n if (variable.helpText) return variable.helpText;\n const role = roleOf(variable);\n return role ? IMAGE_ROLE_META[role].explanation : undefined;\n}\n\n/** Derive the ordered, grouped, labelled run inputs for an agent's variables. */\nexport function deriveRunInputs<V extends RunInputVariable>(\n defs: readonly V[] | null | undefined,\n formatName: (name: string) => string,\n): RunInput<V>[] {\n return orderVariablesForForm([...(defs ?? [])]).map((variable) => {\n const type = variable.customComponent?.type ?? \"textarea\";\n const options = variable.customComponent?.options ?? undefined;\n return {\n name: variable.name,\n label: variableRunLabel(variable, formatName),\n hint: variableRunHint(variable),\n group: isControlVariable(variable) ? \"settings\" : \"content\",\n required: Boolean(variable.required),\n component: type,\n options: options && options.length > 0 ? options : undefined,\n mediaKind: MEDIA_KINDS.includes(type) ? (type as RunInputMediaKind) : null,\n role: roleOf(variable),\n controlKey: isControlVariable(variable) ? (variable.control?.key ?? null) : null,\n variable,\n };\n });\n}\n"],"mappings":"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","names":["isRecord","changed","output","asRecord","asString","asNumber","isRecord","import_data","status","isRecord"]}
1
+ {"version":3,"sources":["../index.ts","../stream/ndjson.ts","../stream/sse.ts","../presentation/result.ts","../projection/request.ts","../projection/workflow.ts","../matrx/transport.ts","../matrx/client.ts","../matrx/org-context.ts","../matrx/protocol.ts","../matrx/conversation.ts","../matrx/internal.ts","../matrx/operations.ts","../matrx/rejoin.ts","../matrx/run.ts","../matrx/provider-failures.ts","../matrx/tools.ts","../variables/reference-roles.ts","../variables/run-inputs.ts"],"sourcesContent":["export * from \"./stream/ndjson\";\nexport * from \"./stream/sse\";\nexport * from \"./presentation/result\";\nexport * from \"./projection/request\";\nexport * from \"./projection/workflow\";\nexport * from \"./matrx/index\";\nexport * from \"./variables/index\";\n","/**\n * Canonical AI Matrx NDJSON wire kernel.\n *\n * This module is deliberately independent of React, Redux, Next.js, Supabase,\n * and generated application types. Every Matrx client uses it to turn the\n * backend's byte stream into the same normalized `{ event, data }` envelopes.\n * Host runtimes remain responsible for HTTP/auth errors and for deciding what\n * each event means in their state model.\n */\n\nexport interface MatrxStreamEnvelope<TData = unknown> {\n event: string;\n /** Immutable emitter segment; transport sequence is scoped to this id. */\n stream_id?: string;\n data: TData;\n /** Monotonic transport sequence from full envelopes, when supplied. */\n stream_seq?: number;\n}\n\nexport interface MatrxNdjsonIssue {\n line: string;\n error: unknown;\n /** One-based physical NDJSON line number. */\n lineNumber: number;\n /** True when an unterminated trailing fragment was parsed by `finish()`. */\n atCompletion: boolean;\n}\n\nexport interface MatrxStreamEnvelopeObservation {\n /** Exact parsed JSON value before compact/full normalization. */\n raw: unknown;\n envelope: MatrxStreamEnvelope;\n line: string;\n lineNumber: number;\n atCompletion: boolean;\n}\n\nexport interface MatrxNdjsonFramerOptions {\n /** Malformed JSON is non-fatal, but it must never disappear silently. */\n onMalformedLine?: (issue: MatrxNdjsonIssue) => void;\n /** Valid JSON with no recognized Matrx event envelope is also non-fatal. */\n onUnknownEnvelope?: (value: unknown) => void;\n /** Observe every valid envelope without changing or consuming it. */\n onValidEnvelope?: (observation: MatrxStreamEnvelopeObservation) => void;\n}\n\nexport interface ReadMatrxNdjsonOptions extends MatrxNdjsonFramerOptions {\n signal?: AbortSignal;\n /** Maximum normalized events read ahead of the iterator consumer. */\n maxReadAhead?: number;\n}\n\nexport interface MatrxNdjsonFramer {\n /** Push a text fragment. Fragments may split JSON tokens or line endings. */\n pushText(fragment: string): MatrxStreamEnvelope[];\n /** Push a byte fragment. UTF-8 code points may span calls. */\n pushBytes(fragment: Uint8Array): MatrxStreamEnvelope[];\n /** Parse the final unterminated line and flush any pending UTF-8 bytes. */\n finish(): MatrxStreamEnvelope[];\n}\n\ntype QueueItem =\n | { kind: \"event\"; value: MatrxStreamEnvelope }\n | { kind: \"error\"; error: unknown }\n | { kind: \"done\" };\n\nexport const DEFAULT_MATRX_NDJSON_READ_AHEAD = 64;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize both supported Matrx wire shapes:\n *\n * - full: `{ \"event\": \"chunk\", \"data\": { \"text\": \"...\" } }`\n * - compact chunk: `{ \"e\": \"c\", \"t\": \"...\" }`\n * - compact reasoning: `{ \"e\": \"r\", \"t\": \"...\" }`\n */\nexport function normalizeMatrxStreamEnvelope(\n value: unknown,\n): MatrxStreamEnvelope | null {\n if (!isRecord(value)) return null;\n\n if (typeof value.event === \"string\") {\n const streamSeq =\n typeof value.stream_seq === \"number\" && Number.isFinite(value.stream_seq)\n ? value.stream_seq\n : undefined;\n const streamId = typeof value.stream_id === \"string\" ? value.stream_id : undefined;\n return {\n event: value.event,\n data: value.data,\n ...(streamId === undefined ? {} : { stream_id: streamId }),\n ...(streamSeq === undefined ? {} : { stream_seq: streamSeq }),\n };\n }\n if (value.e === \"c\" && typeof value.t === \"string\") {\n const streamId = typeof value.stream_id === \"string\" ? value.stream_id : undefined;\n const streamSeq =\n typeof value.stream_seq === \"number\" && Number.isFinite(value.stream_seq)\n ? value.stream_seq\n : undefined;\n return {\n event: \"chunk\",\n data: { text: value.t },\n ...(streamId === undefined ? {} : { stream_id: streamId }),\n ...(streamSeq === undefined ? {} : { stream_seq: streamSeq }),\n };\n }\n if (value.e === \"r\" && typeof value.t === \"string\") {\n const streamId = typeof value.stream_id === \"string\" ? value.stream_id : undefined;\n const streamSeq =\n typeof value.stream_seq === \"number\" && Number.isFinite(value.stream_seq)\n ? value.stream_seq\n : undefined;\n return {\n event: \"reasoning_chunk\",\n data: { text: value.t },\n ...(streamId === undefined ? {} : { stream_id: streamId }),\n ...(streamSeq === undefined ? {} : { stream_seq: streamSeq }),\n };\n }\n return null;\n}\n\n/**\n * Create the transport-independent NDJSON framer used by the stream reader.\n * Browser extensions, desktop bridges, WebSockets, and tests can feed it\n * fragmented strings or bytes without constructing a `ReadableStream`.\n */\nexport function createMatrxNdjsonFramer(\n options: MatrxNdjsonFramerOptions = {},\n): MatrxNdjsonFramer {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let lineNumber = 0;\n let finished = false;\n\n const assertOpen = (): void => {\n if (finished) throw new Error(\"Matrx NDJSON framer is already finished\");\n };\n\n const parseLine = (\n line: string,\n atCompletion: boolean,\n ): MatrxStreamEnvelope | null => {\n const currentLineNumber = ++lineNumber;\n const trimmed = line.trim();\n if (!trimmed) return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed) as unknown;\n } catch (error) {\n options.onMalformedLine?.({\n line: trimmed,\n error,\n lineNumber: currentLineNumber,\n atCompletion,\n });\n return null;\n }\n\n const envelope = normalizeMatrxStreamEnvelope(parsed);\n if (!envelope) {\n options.onUnknownEnvelope?.(parsed);\n return null;\n }\n options.onValidEnvelope?.({\n raw: parsed,\n envelope,\n line: trimmed,\n lineNumber: currentLineNumber,\n atCompletion,\n });\n return envelope;\n };\n\n const pushDecodedText = (fragment: string): MatrxStreamEnvelope[] => {\n buffer += fragment;\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n const envelopes: MatrxStreamEnvelope[] = [];\n for (const line of lines) {\n const envelope = parseLine(line, false);\n if (envelope) envelopes.push(envelope);\n }\n return envelopes;\n };\n\n return {\n pushText(fragment) {\n assertOpen();\n // Flush any pending byte fragment before switching to explicit text.\n return pushDecodedText(decoder.decode() + fragment);\n },\n pushBytes(fragment) {\n assertOpen();\n return pushDecodedText(decoder.decode(fragment, { stream: true }));\n },\n finish() {\n assertOpen();\n finished = true;\n const envelopes = pushDecodedText(decoder.decode());\n if (buffer.length > 0) {\n const envelope = parseLine(buffer, true);\n buffer = \"\";\n if (envelope) envelopes.push(envelope);\n }\n return envelopes;\n },\n };\n}\n\nfunction readAheadLimit(value: number | undefined): number {\n const limit = value ?? DEFAULT_MATRX_NDJSON_READ_AHEAD;\n if (!Number.isSafeInteger(limit) || limit < 1) {\n throw new RangeError(\"maxReadAhead must be a positive safe integer\");\n }\n return limit;\n}\n\n/**\n * Read and normalize a Matrx NDJSON response body with bounded background\n * read-ahead. Consumer work does not stall the network until `maxReadAhead`\n * complete events are waiting; the bound prevents an abandoned or blocked\n * consumer from growing memory without limit.\n */\nexport async function* readMatrxNdjsonStream(\n body: ReadableStream<Uint8Array>,\n options: ReadMatrxNdjsonOptions = {},\n): AsyncGenerator<MatrxStreamEnvelope, void, undefined> {\n const maxReadAhead = readAheadLimit(options.maxReadAhead);\n const queue: QueueItem[] = [];\n let queuedEventCount = 0;\n let wakeConsumer: (() => void) | null = null;\n let wakeProducer: (() => void) | null = null;\n let readerFinished = false;\n let consumerClosed = false;\n\n const wakeWaitingConsumer = (): void => {\n const wake = wakeConsumer;\n wakeConsumer = null;\n wake?.();\n };\n const wakeWaitingProducer = (): void => {\n const wake = wakeProducer;\n wakeProducer = null;\n wake?.();\n };\n const enqueueTerminal = (item: QueueItem): void => {\n if (consumerClosed) return;\n queue.push(item);\n wakeWaitingConsumer();\n };\n const enqueueEvent = async (value: MatrxStreamEnvelope): Promise<boolean> => {\n while (\n queuedEventCount >= maxReadAhead &&\n !consumerClosed &&\n !options.signal?.aborted\n ) {\n await new Promise<void>((resolve) => {\n wakeProducer = resolve;\n });\n }\n if (consumerClosed || options.signal?.aborted) return false;\n queue.push({ kind: \"event\", value });\n queuedEventCount += 1;\n wakeWaitingConsumer();\n return true;\n };\n const waitForReadCapacity = async (): Promise<boolean> => {\n while (\n queuedEventCount >= maxReadAhead &&\n !consumerClosed &&\n !options.signal?.aborted\n ) {\n await new Promise<void>((resolve) => {\n wakeProducer = resolve;\n });\n }\n return !consumerClosed && !options.signal?.aborted;\n };\n\n const reader = body.getReader();\n const framer = createMatrxNdjsonFramer(options);\n\n const onAbort = (): void => {\n wakeWaitingProducer();\n wakeWaitingConsumer();\n void reader.cancel(options.signal?.reason).catch(() => undefined);\n };\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (options.signal?.aborted) onAbort();\n\n const readerPromise = (async (): Promise<void> => {\n try {\n while (!options.signal?.aborted && !consumerClosed) {\n if (!(await waitForReadCapacity())) return;\n const { value, done } = await reader.read();\n if (done) break;\n for (const envelope of framer.pushBytes(value)) {\n if (!(await enqueueEvent(envelope))) return;\n }\n }\n\n if (!options.signal?.aborted && !consumerClosed) {\n for (const envelope of framer.finish()) {\n if (!(await enqueueEvent(envelope))) return;\n }\n }\n } catch (error) {\n const aborted =\n options.signal?.aborted ||\n consumerClosed ||\n (error instanceof Error && error.name === \"AbortError\");\n if (!aborted) enqueueTerminal({ kind: \"error\", error });\n } finally {\n readerFinished = true;\n reader.releaseLock();\n enqueueTerminal({ kind: \"done\" });\n }\n })();\n\n try {\n while (true) {\n if (queue.length === 0) {\n if (options.signal?.aborted || readerFinished) return;\n await new Promise<void>((resolve) => {\n wakeConsumer = resolve;\n });\n }\n\n const item = queue.shift();\n if (item?.kind === \"event\") queuedEventCount -= 1;\n wakeWaitingProducer();\n if (!item || item.kind === \"done\") return;\n if (item.kind === \"error\") throw item.error;\n yield item.value;\n }\n } finally {\n consumerClosed = true;\n wakeWaitingProducer();\n wakeWaitingConsumer();\n options.signal?.removeEventListener(\"abort\", onAbort);\n if (!readerFinished) {\n await reader.cancel().catch(() => undefined);\n }\n await readerPromise;\n }\n}\n","/**\n * `@ai-matrx/agents/stream/sse` — the Matrx SSE frame kernel.\n *\n * Two Matrx clients hand-rolled the identical `text/event-stream` framing —\n * the same separator regex, the same field parsing, the same CRLF incident —\n * for the durable rejoin endpoints (`/runtime/.../events/stream`,\n * `/runs/.../events/stream`). This module is that framing extracted ONCE, as a\n * pure incremental parser, so a host keeps only what is genuinely host policy:\n * the fetch, the stall timer, the retry budget, and what each event MEANS.\n *\n * Contract, mirroring `stream/ndjson`:\n * - Pure and effect-free: no fetch, no timers, no globals. Importing this\n * module performs no work.\n * - Incremental across arbitrary chunk boundaries: a frame split anywhere —\n * mid-line, mid-separator, mid-UTF-8 when using the byte reader — parses\n * identically to one delivered whole.\n * - All three SSE line terminators (`\\r\\n`, `\\n`, `\\r`) and all three frame\n * separators are handled — the CRLF-vs-LF divergence that bit production is\n * covered by construction and by test.\n * - Comment-only frames (heartbeats, `:` lines) ARE emitted (with\n * `data === null`) because hosts use any parsed frame as liveness proof to\n * reset stall timers and retry budgets. Frames with data join multi-line\n * `data:` fields with `\\n` per the SSE spec.\n * - `id:` is surfaced raw AND, when it is a safe integer, as `seq` — the\n * `Last-Event-ID` cursor both Matrx rejoin endpoints use for durable replay.\n * Cursor ADVANCEMENT (`seq > cursor`) stays host-side, next to the retry.\n */\n\nexport interface MatrxSseFrame {\n /** `event:` field; the SSE default \"message\" when absent. */\n event: string;\n /** `id:` field, raw, when present. */\n id: string | null;\n /**\n * `id:` parsed as a non-negative safe integer, else null. Matrx rejoin\n * streams use integer ids as the `Last-Event-ID` replay cursor.\n */\n seq: number | null;\n /**\n * Joined `data:` lines (`\\n`-separated per spec), or null for a frame with\n * no data field at all (e.g. a comment-only heartbeat). An empty-string\n * data field is `\"\"`, not null.\n */\n data: string | null;\n}\n\nconst FRAME_SEPARATOR = /\\r\\n\\r\\n|\\n\\n|\\r\\r/;\nconst LINE_SEPARATOR = /\\r\\n|\\n|\\r/;\n\n/** Parse ONE complete frame's text (no trailing separator). */\nexport function parseMatrxSseFrame(frame: string): MatrxSseFrame {\n let event = \"message\";\n let id: string | null = null;\n const dataLines: string[] = [];\n let sawData = false;\n\n for (const line of frame.split(LINE_SEPARATOR)) {\n if (line.startsWith(\":\")) continue;\n if (line.startsWith(\"event:\")) event = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) {\n sawData = true;\n dataLines.push(line.slice(5).replace(/^ /, \"\"));\n } else if (line.startsWith(\"id:\")) id = line.slice(3).trim();\n }\n\n const seqCandidate = id !== null && id !== \"\" ? Number(id) : NaN;\n const seq =\n Number.isSafeInteger(seqCandidate) && seqCandidate >= 0\n ? seqCandidate\n : null;\n\n return { event, id, seq, data: sawData ? dataLines.join(\"\\n\") : null };\n}\n\nexport interface MatrxSseFramer {\n /** Feed a decoded text chunk; returns every frame it completed. */\n push(chunk: string): MatrxSseFrame[];\n /**\n * Signal end of input. A non-empty trailing buffer is an UNTERMINATED frame:\n * per the SSE spec it was never dispatched, so it is returned separately for\n * the host to treat as diagnostic, never as a delivered event.\n */\n flush(): { incomplete: string | null };\n}\n\n/** Incremental SSE framer over already-decoded text. */\nexport function createMatrxSseFramer(): MatrxSseFramer {\n let buffer = \"\";\n return {\n push(chunk: string): MatrxSseFrame[] {\n buffer += chunk;\n const frames: MatrxSseFrame[] = [];\n for (;;) {\n const sep = FRAME_SEPARATOR.exec(buffer);\n if (sep === null) break;\n // A lone trailing `\\r` could be the first half of `\\r\\n\\r\\n`'s final\n // newline — but the separator regex only matched what is already\n // complete, so the slice below is always safe.\n const frame = buffer.slice(0, sep.index);\n buffer = buffer.slice(sep.index + sep[0].length);\n frames.push(parseMatrxSseFrame(frame));\n }\n return frames;\n },\n flush() {\n const rest = buffer;\n buffer = \"\";\n return { incomplete: rest.length > 0 ? rest : null };\n },\n };\n}\n\nexport interface ReadMatrxSseOptions {\n /**\n * Called with any unterminated trailing text at stream end (a frame the\n * server never finished — diagnostic, not a delivered event).\n */\n onIncomplete?: (text: string) => void;\n}\n\n/**\n * Async-iterate the frames of a byte stream (e.g. `response.body`), handling\n * split UTF-8 across chunk boundaries. Cancellation follows the reader: abort\n * the fetch and the iterator ends; a transport error after complete frames\n * were yielded surfaces AFTER those frames, with its original cause.\n */\nexport async function* readMatrxSseStream(\n stream: ReadableStream<Uint8Array>,\n options: ReadMatrxSseOptions = {},\n): AsyncGenerator<MatrxSseFrame, void, undefined> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const framer = createMatrxSseFramer();\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n const frames = framer.push(decoder.decode(value, { stream: true }));\n for (const frame of frames) yield frame;\n }\n const tail = framer.push(decoder.decode());\n for (const frame of tail) yield frame;\n const { incomplete } = framer.flush();\n if (incomplete !== null) options.onIncomplete?.(incomplete);\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Creator-facing projection of an agent execution result.\n *\n * Provider reasoning blocks and their signatures are replay material, not\n * workflow data. The execution engine must retain them so a later turn can be\n * continued correctly, but no result renderer, JSON tab, clipboard export, or\n * Content IR classifier should receive them as displayable values.\n *\n * This is a pure copy-on-write projection: values without private material\n * keep their original reference, while affected branches are cloned. Never\n * feed the projected value back into execution or persistence.\n */\n\nconst PRIVATE_REASONING_TYPES: ReadonlySet<string> = new Set([\n \"thinking\",\n \"redacted_thinking\",\n \"reasoning\",\n]);\n\nconst PRIVATE_PROVIDER_KEYS: ReadonlySet<string> = new Set([\n \"thought_signature\",\n \"thoughtSignature\",\n \"google_thought_signature\",\n \"anthropic_signature\",\n \"encrypted_content\",\n \"signature_encoding\",\n]);\n\nconst SIGNATURE_PROVIDERS: ReadonlySet<string> = new Set([\n \"anthropic\",\n \"google\",\n \"openai\",\n]);\n\nconst OPAQUE_SIGNATURE_MIN_LENGTH = 200;\nconst OMIT = Symbol(\"omit-provider-private-value\");\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPrivateReasoningBlock(value: Record<string, unknown>): boolean {\n return (\n typeof value.type === \"string\" &&\n PRIVATE_REASONING_TYPES.has(value.type.toLowerCase())\n );\n}\n\nfunction isPrivateProviderKey(\n key: string,\n value: unknown,\n parent: Record<string, unknown>,\n): boolean {\n if (PRIVATE_PROVIDER_KEYS.has(key)) return true;\n if (key !== \"signature\") return false;\n\n const provider =\n typeof parent.provider === \"string\" ? parent.provider.toLowerCase() : \"\";\n return (\n \"signature_encoding\" in parent ||\n SIGNATURE_PROVIDERS.has(provider) ||\n (typeof value === \"string\" && value.length >= OPAQUE_SIGNATURE_MIN_LENGTH)\n );\n}\n\nfunction project(value: unknown): unknown | typeof OMIT {\n if (Array.isArray(value)) {\n let changed = false;\n const output: unknown[] = [];\n for (const item of value) {\n const projected = project(item);\n if (projected === OMIT) {\n changed = true;\n continue;\n }\n if (projected !== item) changed = true;\n output.push(projected);\n }\n return changed ? output : value;\n }\n\n if (!isRecord(value)) return value;\n if (isPrivateReasoningBlock(value)) return OMIT;\n\n let changed = false;\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n if (isPrivateProviderKey(key, child, value)) {\n changed = true;\n continue;\n }\n const projected = project(child);\n if (projected === OMIT) {\n changed = true;\n continue;\n }\n if (projected !== child) changed = true;\n output[key] = projected;\n }\n return changed ? output : value;\n}\n\n/**\n * Remove provider-private reasoning material from a value crossing a\n * Creator-facing presentation or export boundary.\n */\nexport function projectAgentResultForDisplay(value: unknown): unknown {\n const projected = project(value);\n return projected === OMIT ? null : projected;\n}\n","export type AgentProjectionStatus =\n | \"pending\"\n | \"streaming\"\n | \"awaiting-tools\"\n | \"complete\"\n | \"error\"\n | \"cancelled\";\n\nexport interface AgentProjectionOperation {\n operationId: string;\n operation: string;\n parentOperationId: string | null;\n status: \"active\" | \"success\" | \"failed\" | \"cancelled\";\n metadata: Record<string, unknown> | null;\n result: Record<string, unknown> | null;\n}\n\nexport interface AgentProjectionTool {\n callId: string;\n toolName: string;\n status:\n | \"started\"\n | \"progress\"\n | \"step\"\n | \"preview\"\n | \"completed\"\n | \"error\"\n | \"delegated\";\n message: string | null;\n data: Record<string, unknown> | null;\n}\n\nexport interface AgentProjectionRenderBlock {\n blockId: string;\n blockIndex: number;\n type: string;\n status: \"streaming\" | \"complete\" | \"error\";\n content: string | null;\n data: Record<string, unknown> | null;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface AgentRequestProjection {\n requestId: string;\n conversationId: string | null;\n status: AgentProjectionStatus;\n answer: string;\n reasoning: string;\n reasoningActive: boolean;\n phase: string | null;\n phaseHistory: string[];\n operations: Record<string, AgentProjectionOperation>;\n tools: Record<string, AgentProjectionTool>;\n renderBlocks: Record<string, AgentProjectionRenderBlock>;\n renderBlockOrder: string[];\n completion: Record<string, unknown> | null;\n error: Record<string, unknown> | null;\n lastTransportSeq: number;\n transportStreamId: string | null;\n eventCount: number;\n}\n\nexport interface AgentProjectionEvent {\n event: string;\n data?: unknown;\n stream_seq?: number;\n stream_id?: string;\n}\n\nconst asRecord = (value: unknown): Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n\nconst asString = (value: unknown): string | null =>\n typeof value === \"string\" ? value : null;\n\nconst asNumber = (value: unknown): number | null =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\nexport function createAgentRequestProjection(input: {\n requestId: string;\n conversationId?: string | null;\n}): AgentRequestProjection {\n return {\n requestId: input.requestId,\n conversationId: input.conversationId ?? null,\n status: \"pending\",\n answer: \"\",\n reasoning: \"\",\n reasoningActive: false,\n phase: null,\n phaseHistory: [],\n operations: {},\n tools: {},\n renderBlocks: {},\n renderBlockOrder: [],\n completion: null,\n error: null,\n lastTransportSeq: 0,\n transportStreamId: null,\n eventCount: 0,\n };\n}\n\nfunction toolStatus(event: string): AgentProjectionTool[\"status\"] {\n switch (event) {\n case \"tool_started\":\n return \"started\";\n case \"tool_step\":\n return \"step\";\n case \"tool_result_preview\":\n return \"preview\";\n case \"tool_completed\":\n return \"completed\";\n case \"tool_error\":\n return \"error\";\n case \"tool_delegated\":\n return \"delegated\";\n default:\n return \"progress\";\n }\n}\n\nexport function projectAgentEvent(\n current: AgentRequestProjection,\n event: AgentProjectionEvent,\n): AgentRequestProjection {\n const streamSeq = asNumber(event.stream_seq);\n const streamId = asString(event.stream_id);\n const sameSegment = streamId === null || streamId === current.transportStreamId;\n if (\n sameSegment &&\n streamSeq !== null &&\n streamSeq <= current.lastTransportSeq\n ) {\n return current;\n }\n\n const data = asRecord(event.data);\n const next: AgentRequestProjection = {\n ...current,\n status: current.status === \"pending\" ? \"streaming\" : current.status,\n lastTransportSeq:\n streamSeq === null\n ? current.lastTransportSeq\n : sameSegment\n ? Math.max(current.lastTransportSeq, streamSeq)\n : streamSeq,\n transportStreamId: streamId ?? current.transportStreamId,\n eventCount: current.eventCount + 1,\n };\n\n switch (event.event) {\n case \"chunk\": {\n const text = asString(data.text);\n return text === null ? next : { ...next, answer: current.answer + text };\n }\n case \"reasoning_chunk\": {\n const text = asString(data.text);\n return text === null\n ? next\n : {\n ...next,\n reasoning: current.reasoning + text,\n reasoningActive: true,\n };\n }\n case \"reasoning\":\n return {\n ...next,\n reasoningActive: data.state === \"started\",\n };\n case \"phase\": {\n const phase = asString(data.phase);\n if (phase === null) return next;\n return {\n ...next,\n phase,\n phaseHistory: [...current.phaseHistory, phase],\n };\n }\n case \"init\": {\n const operationId = asString(data.operation_id);\n const operation = asString(data.operation);\n if (operationId === null || operation === null) return next;\n return {\n ...next,\n operations: {\n ...current.operations,\n [operationId]: {\n operationId,\n operation,\n parentOperationId: asString(data.parent_operation_id),\n status: \"active\",\n metadata: Object.keys(asRecord(data.metadata)).length\n ? asRecord(data.metadata)\n : null,\n result: null,\n },\n },\n };\n }\n case \"completion\": {\n const operationId = asString(data.operation_id);\n const operation = asString(data.operation);\n const rawStatus = asString(data.status);\n const status: AgentProjectionOperation[\"status\"] =\n rawStatus === \"failed\" || rawStatus === \"cancelled\"\n ? rawStatus\n : \"success\";\n const result = asRecord(data.result);\n const operations = operationId\n ? {\n ...current.operations,\n [operationId]: {\n ...(current.operations[operationId] ?? {\n operationId,\n operation: operation ?? \"unknown\",\n parentOperationId: null,\n metadata: null,\n }),\n status,\n result,\n },\n }\n : current.operations;\n if (operation === \"user_request\") {\n return {\n ...next,\n operations,\n completion: data,\n status:\n status === \"success\"\n ? \"complete\"\n : status === \"cancelled\"\n ? \"cancelled\"\n : \"error\",\n };\n }\n return { ...next, operations };\n }\n case \"tool_event\": {\n const callId = asString(data.call_id);\n const toolName = asString(data.tool_name);\n const lifecycle = asString(data.event);\n if (callId === null || toolName === null || lifecycle === null) return next;\n const status = toolStatus(lifecycle);\n return {\n ...next,\n status:\n status === \"delegated\"\n ? \"awaiting-tools\"\n : status === \"completed\" || status === \"error\"\n ? \"streaming\"\n : next.status,\n tools: {\n ...current.tools,\n [callId]: {\n callId,\n toolName,\n status,\n message: asString(data.message),\n data: Object.keys(asRecord(data.data)).length ? asRecord(data.data) : null,\n },\n },\n };\n }\n case \"render_block\": {\n const blockId = asString(data.blockId);\n const blockIndex = asNumber(data.blockIndex);\n const type = asString(data.type);\n if (blockId === null || blockIndex === null || type === null) return next;\n const alreadyKnown = Object.hasOwn(current.renderBlocks, blockId);\n return {\n ...next,\n renderBlocks: {\n ...current.renderBlocks,\n [blockId]: {\n blockId,\n blockIndex,\n type,\n status:\n data.status === \"complete\" || data.status === \"error\"\n ? data.status\n : \"streaming\",\n content: asString(data.content),\n data: Object.keys(asRecord(data.data)).length ? asRecord(data.data) : null,\n metadata: Object.keys(asRecord(data.metadata)).length\n ? asRecord(data.metadata)\n : null,\n },\n },\n renderBlockOrder: alreadyKnown\n ? current.renderBlockOrder\n : [...current.renderBlockOrder, blockId],\n };\n }\n case \"error\":\n return { ...next, status: \"error\", error: data };\n case \"end\":\n return {\n ...next,\n status:\n current.status === \"error\" || current.status === \"cancelled\"\n ? current.status\n : \"complete\",\n reasoningActive: false,\n };\n case \"data\": {\n const conversationId =\n data.type === \"conversation_id\" ? asString(data.conversation_id) : null;\n return conversationId === null ? next : { ...next, conversationId };\n }\n default:\n return next;\n }\n}\n\nexport function projectAgentEvents(\n initial: AgentRequestProjection,\n events: readonly AgentProjectionEvent[],\n): AgentRequestProjection {\n return events.reduce(projectAgentEvent, initial);\n}\n","import type { AgentProjectionRenderBlock } from \"./request\";\n\nexport interface WorkflowNodeStreamEvent {\n run_id: string;\n node_id?: string | null;\n kind:\n | \"chunk\"\n | \"reasoning\"\n | \"phase\"\n | \"tool\"\n | \"warning\"\n | \"record_update\"\n | \"resource_changed\"\n | \"render_block\";\n delta: string;\n stream_seq: number;\n ts: string;\n chunks_received: number;\n chars_streamed: number;\n frame_id?: string | null;\n frame_index?: number;\n frame_count?: number;\n block_shadowed?: boolean;\n}\n\nexport interface WorkflowProjectionLimits {\n maxOpenFrameSets: number;\n maxFramesPerBlock: number;\n maxBytesPerBlock: number;\n}\n\nexport const DEFAULT_WORKFLOW_PROJECTION_LIMITS: Readonly<WorkflowProjectionLimits> = {\n maxOpenFrameSets: 32,\n maxFramesPerBlock: 256,\n maxBytesPerBlock: 1_048_576,\n};\n\nexport interface WorkflowRenderFrameSet {\n frameCount: number;\n slices: Record<number, string>;\n byteLength: number;\n}\n\nexport type WorkflowRenderBlockIssueCode =\n | \"invalid_frame_metadata\"\n | \"frame_count_mismatch\"\n | \"open_frame_limit_exceeded\"\n | \"frame_limit_exceeded\"\n | \"byte_limit_exceeded\"\n | \"malformed_json\"\n | \"invalid_render_block\";\n\nexport interface WorkflowRenderBlockIssue {\n code: WorkflowRenderBlockIssueCode;\n frameId: string | null;\n streamSeq: number;\n message: string;\n}\n\nexport interface WorkflowNodeProjection {\n runId: string;\n nodeId: string;\n answer: string;\n reasoning: string;\n blockShadowed: boolean;\n renderBlocks: Record<string, AgentProjectionRenderBlock>;\n renderBlockOrder: string[];\n openFrames: Record<string, WorkflowRenderFrameSet>;\n limits: WorkflowProjectionLimits;\n lastRenderBlockIssue: WorkflowRenderBlockIssue | null;\n chunksReceived: number;\n charsStreamed: number;\n lastStreamingTs: string | null;\n lastPhase: string | null;\n lastTool: string | null;\n lastWarning: string | null;\n lastTransportSeq: number;\n}\n\nfunction positiveSafeInteger(name: string, value: number): number {\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new RangeError(`${name} must be a positive safe integer`);\n }\n return value;\n}\n\nfunction resolveLimits(\n limits: Partial<WorkflowProjectionLimits> | undefined,\n): WorkflowProjectionLimits {\n return {\n maxOpenFrameSets: positiveSafeInteger(\n \"maxOpenFrameSets\",\n limits?.maxOpenFrameSets ??\n DEFAULT_WORKFLOW_PROJECTION_LIMITS.maxOpenFrameSets,\n ),\n maxFramesPerBlock: positiveSafeInteger(\n \"maxFramesPerBlock\",\n limits?.maxFramesPerBlock ??\n DEFAULT_WORKFLOW_PROJECTION_LIMITS.maxFramesPerBlock,\n ),\n maxBytesPerBlock: positiveSafeInteger(\n \"maxBytesPerBlock\",\n limits?.maxBytesPerBlock ??\n DEFAULT_WORKFLOW_PROJECTION_LIMITS.maxBytesPerBlock,\n ),\n };\n}\n\nexport function createWorkflowNodeProjection(input: {\n runId: string;\n nodeId: string;\n limits?: Partial<WorkflowProjectionLimits>;\n}): WorkflowNodeProjection {\n return {\n runId: input.runId,\n nodeId: input.nodeId,\n answer: \"\",\n reasoning: \"\",\n blockShadowed: false,\n renderBlocks: {},\n renderBlockOrder: [],\n openFrames: {},\n limits: resolveLimits(input.limits),\n lastRenderBlockIssue: null,\n chunksReceived: 0,\n charsStreamed: 0,\n lastStreamingTs: null,\n lastPhase: null,\n lastTool: null,\n lastWarning: null,\n lastTransportSeq: 0,\n };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\nfunction asNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction utf8ByteLength(value: string): number {\n return new TextEncoder().encode(value).byteLength;\n}\n\nfunction toRenderBlock(value: unknown): AgentProjectionRenderBlock | null {\n const data = asRecord(value);\n if (!data) return null;\n const blockId = asString(data.blockId);\n const blockIndex = asNumber(data.blockIndex);\n const type = asString(data.type);\n if (blockId === null || blockIndex === null || type === null) return null;\n return {\n blockId,\n blockIndex,\n type,\n status:\n data.status === \"complete\" || data.status === \"error\"\n ? data.status\n : \"streaming\",\n content: asString(data.content),\n data: asRecord(data.data),\n metadata: asRecord(data.metadata),\n };\n}\n\nfunction withIssue(\n next: WorkflowNodeProjection,\n event: WorkflowNodeStreamEvent,\n code: WorkflowRenderBlockIssueCode,\n frameId: string | null,\n message: string,\n openFrames: Record<string, WorkflowRenderFrameSet> = next.openFrames,\n): WorkflowNodeProjection {\n return {\n ...next,\n openFrames,\n lastRenderBlockIssue: {\n code,\n frameId,\n streamSeq: event.stream_seq,\n message,\n },\n };\n}\n\nfunction withoutFrame(\n frames: Record<string, WorkflowRenderFrameSet>,\n frameId: string,\n): Record<string, WorkflowRenderFrameSet> {\n if (!Object.hasOwn(frames, frameId)) return frames;\n const next = { ...frames };\n delete next[frameId];\n return next;\n}\n\nfunction projectRenderFrame(\n current: WorkflowNodeProjection,\n event: WorkflowNodeStreamEvent,\n next: WorkflowNodeProjection,\n): WorkflowNodeProjection {\n const frameId = event.frame_id;\n const frameCount = event.frame_count ?? 1;\n const frameIndex = event.frame_index ?? 0;\n if (\n !frameId ||\n !Number.isSafeInteger(frameCount) ||\n !Number.isSafeInteger(frameIndex) ||\n frameCount < 1 ||\n frameIndex < 0 ||\n frameIndex >= frameCount\n ) {\n return withIssue(\n next,\n event,\n \"invalid_frame_metadata\",\n frameId ?? null,\n \"Render block frame metadata is invalid\",\n );\n }\n if (frameCount > current.limits.maxFramesPerBlock) {\n return withIssue(\n next,\n event,\n \"frame_limit_exceeded\",\n frameId,\n `Render block declares ${frameCount} frames; limit is ${current.limits.maxFramesPerBlock}`,\n withoutFrame(current.openFrames, frameId),\n );\n }\n\n const prior = current.openFrames[frameId];\n if (prior && prior.frameCount !== frameCount) {\n return withIssue(\n next,\n event,\n \"frame_count_mismatch\",\n frameId,\n `Render block frame count changed from ${prior.frameCount} to ${frameCount}`,\n withoutFrame(current.openFrames, frameId),\n );\n }\n\n const priorSlice = prior?.slices[frameIndex];\n const byteLength =\n (prior?.byteLength ?? 0) -\n (priorSlice === undefined ? 0 : utf8ByteLength(priorSlice)) +\n utf8ByteLength(event.delta);\n if (byteLength > current.limits.maxBytesPerBlock) {\n return withIssue(\n next,\n event,\n \"byte_limit_exceeded\",\n frameId,\n `Render block exceeds ${current.limits.maxBytesPerBlock} UTF-8 bytes`,\n withoutFrame(current.openFrames, frameId),\n );\n }\n\n const set: WorkflowRenderFrameSet = {\n frameCount,\n slices: { ...(prior?.slices ?? {}), [frameIndex]: event.delta },\n byteLength,\n };\n const openFrames = { ...current.openFrames };\n let limitIssue: WorkflowRenderBlockIssue | null = null;\n if (!prior && Object.keys(openFrames).length >= current.limits.maxOpenFrameSets) {\n const oldestFrameId = Object.keys(openFrames)[0];\n if (oldestFrameId !== undefined) {\n delete openFrames[oldestFrameId];\n limitIssue = {\n code: \"open_frame_limit_exceeded\",\n frameId: oldestFrameId,\n streamSeq: event.stream_seq,\n message: `Evicted incomplete render block after reaching ${current.limits.maxOpenFrameSets} open frame sets`,\n };\n }\n }\n openFrames[frameId] = set;\n if (Object.keys(set.slices).length !== frameCount) {\n return {\n ...next,\n openFrames,\n lastRenderBlockIssue: limitIssue ?? current.lastRenderBlockIssue,\n };\n }\n\n delete openFrames[frameId];\n const serialized = Array.from(\n { length: frameCount },\n (_, index) => set.slices[index] ?? \"\",\n ).join(\"\");\n let parsed: unknown;\n try {\n parsed = JSON.parse(serialized) as unknown;\n } catch (error) {\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n return withIssue(\n next,\n event,\n \"malformed_json\",\n frameId,\n `Completed render block is not valid JSON${detail}`,\n openFrames,\n );\n }\n const block = toRenderBlock(parsed);\n if (!block) {\n return withIssue(\n next,\n event,\n \"invalid_render_block\",\n frameId,\n \"Completed render block is missing blockId, blockIndex, or type\",\n openFrames,\n );\n }\n return {\n ...next,\n openFrames,\n lastRenderBlockIssue: limitIssue ?? current.lastRenderBlockIssue,\n renderBlocks: { ...current.renderBlocks, [block.blockId]: block },\n renderBlockOrder: Object.hasOwn(current.renderBlocks, block.blockId)\n ? current.renderBlockOrder\n : [...current.renderBlockOrder, block.blockId],\n };\n}\n\nexport function projectWorkflowNodeEvent(\n current: WorkflowNodeProjection,\n event: WorkflowNodeStreamEvent,\n): WorkflowNodeProjection {\n if (\n event.run_id !== current.runId ||\n (event.node_id ?? \"\") !== current.nodeId\n ) {\n return current;\n }\n if (event.stream_seq <= current.lastTransportSeq) return current;\n const next: WorkflowNodeProjection = {\n ...current,\n chunksReceived: event.chunks_received,\n charsStreamed: event.chars_streamed,\n lastStreamingTs: event.ts,\n lastTransportSeq: event.stream_seq,\n blockShadowed: current.blockShadowed || Boolean(event.block_shadowed),\n };\n switch (event.kind) {\n case \"chunk\":\n return { ...next, answer: current.answer + event.delta };\n case \"reasoning\":\n return { ...next, reasoning: current.reasoning + event.delta };\n case \"phase\":\n return { ...next, lastPhase: event.delta };\n case \"tool\":\n return { ...next, lastTool: event.delta };\n case \"warning\":\n return { ...next, lastWarning: event.delta };\n case \"render_block\":\n return projectRenderFrame(current, event, next);\n default:\n return next;\n }\n}\n","/**\n * `@ai-matrx/agents/matrx` — the Matrx transport port.\n *\n * The ONE seam between this package's wire semantics and a host's connection\n * policy. This package owns WHAT is said to the AI Matrx server — paths,\n * methods, JSON bodies, streaming Accept headers, the `Last-Event-ID` cursor\n * header — and the host owns HOW the connection is made:\n *\n * - base-URL / backend-channel resolution (global, sandbox override, local\n * engine, EC2-dedicated — whatever ladder the host runs);\n * - credentials (Supabase JWT `Authorization: Bearer`, guest\n * `X-Fingerprint-ID`, or the API-key lane) — NEVER implemented here;\n * - the `X-Organization-Id` context header;\n * - retry policy, network-level timeouts, and diagnostics capture.\n *\n * A host implements the port in a few lines:\n *\n * ```ts\n * const transport: MatrxTransport = {\n * fetch: (path, init) =>\n * fetch(`${baseUrl}${path}`, {\n * ...init,\n * headers: { ...init.headers, ...authHeaders() },\n * }),\n * };\n * ```\n *\n * The port is deliberately structural and `fetch`-shaped so `@ai-matrx/data`'s\n * `/api` transport can implement it without importing this package.\n */\n\n/**\n * The request this package hands the port. A strict subset of `RequestInit`,\n * so a host can spread it straight into `fetch`.\n */\nexport interface MatrxTransportRequest {\n method: \"GET\" | \"POST\";\n /**\n * Wire-semantic headers the CALL requires (`Content-Type`, `Accept`,\n * `Last-Event-ID`). The host merges its policy headers (auth, org) on top;\n * it must not drop these.\n */\n headers: Record<string, string>;\n /** Pre-serialized JSON body, present on POST calls that carry one. */\n body?: string;\n /** Caller cancellation. The host must wire it to the underlying fetch. */\n signal?: AbortSignal;\n}\n\n/**\n * The transport port. `path` is server-relative and always starts with `/`\n * (`/ai/...`, `/runtime/...`); the host prepends its resolved base URL.\n */\nexport interface MatrxTransport {\n fetch(path: string, init: MatrxTransportRequest): Promise<Response>;\n}\n\n/**\n * A non-2xx response from the Matrx API, with the server's structured error\n * body preserved and its richest human-readable message extracted.\n */\nexport class MatrxApiError extends Error {\n override readonly name = \"MatrxApiError\";\n /** HTTP status of the failed response. */\n readonly status: number;\n /** Machine code from the server body (`code`, or `detail.code`), when present. */\n readonly code: string | null;\n /** The parsed server error body, verbatim (undefined when unparsable). */\n readonly serverDetail: unknown;\n /** The request path the failure came from (server-relative). */\n readonly path: string;\n\n constructor(args: {\n status: number;\n path: string;\n serverDetail?: unknown;\n message?: string;\n }) {\n super(\n args.message ??\n extractMatrxErrorMessage(args.serverDetail) ??\n `HTTP ${args.status}`,\n );\n this.status = args.status;\n this.path = args.path;\n this.serverDetail = args.serverDetail;\n this.code = extractMatrxErrorCode(args.serverDetail);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonBlankString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\n/**\n * Extract the richest human-readable message from a Matrx/FastAPI error body.\n *\n * aidream 4xx validation errors look like\n * `{ error, user_message, details: [{ field, message, help }] }`; hand-raised\n * HTTPExceptions carry `{ detail: { code, message } }`; FastAPI's defaults are\n * `{ detail: string | [{ msg }] }`. Preference order: `user_message` →\n * `message` → joined `details[].message` → `detail.message` →\n * `detail` string → joined `detail[].msg`. Returns undefined for\n * unrecognized bodies so callers fall back to the bare status line.\n */\nexport function extractMatrxErrorMessage(\n serverDetail: unknown,\n): string | undefined {\n if (!isRecord(serverDetail)) return undefined;\n\n const userMessage = nonBlankString(serverDetail.user_message);\n if (userMessage) return userMessage;\n const message = nonBlankString(serverDetail.message);\n if (message) return message;\n\n if (Array.isArray(serverDetail.details)) {\n const messages = serverDetail.details\n .map((entry: unknown) => {\n if (!isRecord(entry)) return undefined;\n const detailMessage = nonBlankString(entry.message);\n if (!detailMessage) return undefined;\n const field = nonBlankString(entry.field);\n return field ? `${field}: ${detailMessage}` : detailMessage;\n })\n .filter((m): m is string => typeof m === \"string\");\n if (messages.length > 0) return messages.join(\"; \");\n }\n\n const detail = serverDetail.detail;\n if (isRecord(detail)) {\n const detailMessage =\n nonBlankString(detail.message) ?? nonBlankString(detail.user_message);\n if (detailMessage) return detailMessage;\n }\n if (typeof detail === \"string\" && detail.trim()) return detail;\n if (Array.isArray(detail)) {\n const messages = detail\n .map((entry: unknown) =>\n isRecord(entry) ? nonBlankString(entry.msg) : undefined,\n )\n .filter((m): m is string => typeof m === \"string\");\n if (messages.length > 0) return messages.join(\"; \");\n }\n return undefined;\n}\n\n/**\n * Extract the machine error code from a Matrx error body: top-level `code`,\n * else `detail.code` (the hand-raised HTTPException shape). Null when absent.\n */\nexport function extractMatrxErrorCode(serverDetail: unknown): string | null {\n if (!isRecord(serverDetail)) return null;\n const topLevel = nonBlankString(serverDetail.code);\n if (topLevel) return topLevel;\n const detail = serverDetail.detail;\n if (isRecord(detail)) {\n const nested = nonBlankString(detail.code);\n if (nested) return nested;\n }\n return null;\n}\n","/**\n * The PRODUCTION `MatrxTransport` — the full connection pipeline every Matrx\n * host used to hand-roll, moved in under C22 (THE HARD PARTS LIVE IN THE\n * PACKAGE). A host constructs it from identity alone:\n *\n * ```ts\n * const transport = createMatrxTransport({\n * baseUrl: \"https://server.app.matrxserver.com\",\n * credentials, // CredentialsPort (@ai-matrx/data)\n * organizationId: () => activeOrgId, // omit for conversation-lane calls\n * });\n * ```\n *\n * Everything else is defaulted to the proven production values:\n *\n * - **timeouts** — connect 15s (for a non-streaming FastAPI handler this is\n * effectively time-to-response), total UNCAPPED (the port cannot tell a JSON\n * call from a long-lived NDJSON/SSE stream; the connect timeout is the JSON\n * guard), via `@ai-matrx/data/net`'s `resilientFetch`;\n * - **protocol** — the AI API version transform (`applyAiApiVersion`, default\n * v2) + the loud v2 → v1 transport fallback (`./protocol`);\n * - **credentials** — read fresh from the injected `CredentialsPort` on EVERY\n * call, so a token refresh mid-run is picked up; mapped to headers by the\n * ONE `credentialToHeaders`;\n * - **org context** — the fail-closed `X-Organization-Id` binding\n * (`./org-context`): configured lanes REQUIRE an org and refuse before the\n * wire; unconfigured lanes (conversation-scoped calls, which carry org in\n * the body) send none;\n * - **error classification** — every failure normalizes through\n * `normalizeMatrxError` into the ONE `MatrxCallError` envelope;\n * - **diagnostics** — a typed sink the host wires to its capture/telemetry\n * (`onRequest`, `onError`, `onProtocolDowngrade`); wiring it is optional,\n * the transport works silently without it.\n *\n * Header merge order is part of the port contract: wire headers first\n * (`Content-Type` / `Accept` / `Last-Event-ID` — the package's), then\n * credentials, then resolver policy headers, then the org header. Policy\n * headers never carry `Content-Type` — the wire owns it, and a policy\n * `Content-Type` merged over a GET SSE call would corrupt the wire, so the\n * factory strips it defensively.\n */\n\nimport { isNetError, type CredentialsPort } from \"@ai-matrx/data\";\nimport { credentialToHeaders } from \"@ai-matrx/data\";\nimport {\n applyOrganizationContextHeader,\n OrganizationContextError,\n requireOrganizationContext,\n} from \"./org-context\";\nimport {\n applyAiApiVersion,\n fetchWithMatrxProtocolFallback,\n MATRX_AI_API_VERSION_DEFAULT,\n type MatrxAiApiVersion,\n type MatrxProtocolDowngrade,\n} from \"./protocol\";\nimport {\n extractMatrxErrorCode,\n extractMatrxErrorMessage,\n MatrxApiError,\n type MatrxTransport,\n type MatrxTransportRequest,\n} from \"./transport\";\n\n// ─── The normalized error envelope ──────────────────────────────────────────\n\n/**\n * The ONE classified error shape for Matrx client calls — the envelope hosts\n * branch on instead of string-matching exceptions. Structurally compatible\n * with matrx-frontend's `ApiCallError` by design.\n */\nexport interface MatrxCallError {\n type:\n | \"auth_error\"\n | \"network_error\"\n | \"http_error\"\n | \"validation_error\"\n | \"abort_error\"\n | \"unknown\";\n message: string;\n /** HTTP status code, if applicable. */\n status?: number;\n /** Raw error detail from the server (the parsed error body). */\n serverDetail?: unknown;\n /** Machine code preserved through normalization (server `code`, org-context code, …). */\n code?: string;\n /** Original exception identity for diagnostics. */\n name?: string;\n /** Original exception stack. */\n stack?: string;\n}\n\nfunction classifyStatus(status: number): \"validation_error\" | \"http_error\" {\n return status >= 400 && status < 500 ? \"validation_error\" : \"http_error\";\n}\n\n/**\n * Classify any failure thrown by a package client call — `MatrxApiError`,\n * a `NetError` from the resilience layer, an org-context refusal, an abort —\n * into the `MatrxCallError` envelope. Never throws.\n */\nexport function normalizeMatrxError(err: unknown): MatrxCallError {\n if (err instanceof MatrxApiError) {\n return {\n type: classifyStatus(err.status),\n message: err.message,\n status: err.status,\n serverDetail: err.serverDetail,\n ...(err.code ? { code: err.code } : {}),\n name: err.name,\n };\n }\n\n if (err instanceof OrganizationContextError) {\n return {\n type: \"validation_error\",\n message: err.message,\n code: err.code,\n name: err.name,\n ...(err.stack !== undefined ? { stack: err.stack } : {}),\n };\n }\n\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return { type: \"abort_error\", message: \"Request was cancelled.\" };\n }\n\n if (isNetError(err)) {\n if (err.code === \"aborted\") {\n return { type: \"abort_error\", message: err.message };\n }\n if (err.code === \"http\") {\n const status = err.status ?? 0;\n return { type: classifyStatus(status), message: err.message, status };\n }\n // connect-timeout / total-timeout / heartbeat-timeout / network / offline\n return { type: \"network_error\", message: err.message };\n }\n\n if (err instanceof Error) {\n const httpMatch = err.message.match(/HTTP (\\d+):\\s*(.*)/);\n if (httpMatch) {\n const status = parseInt(httpMatch[1] as string, 10);\n return {\n type: classifyStatus(status),\n message: httpMatch[2] ?? err.message,\n status,\n };\n }\n return { type: \"network_error\", message: err.message };\n }\n\n return { type: \"unknown\", message: String(err ?? \"Unknown error\") };\n}\n\n// ─── The factory ────────────────────────────────────────────────────────────\n\n/**\n * A fully-resolved connection target for one call: where to send it and which\n * policy headers ride ON TOP of the wire + credential headers.\n */\nexport interface MatrxTransportTarget {\n /** Fully-qualified base URL, no trailing slash. */\n baseUrl: string;\n /**\n * Extra policy headers for this target (e.g. a resolver that carries its own\n * credential headers). `Content-Type` is stripped — the wire owns it.\n */\n policyHeaders?: Record<string, string>;\n /** Routing channel label surfaced to `onRequest` telemetry. */\n channel?: string;\n}\n\n/** Context handed to every diagnostics callback. */\nexport interface MatrxRequestInfo {\n /** The final URL (base + version-transformed path). */\n url: string;\n method: \"GET\" | \"POST\";\n /** The server-relative path as the package requested it. */\n path: string;\n /** The resolved routing channel (default \"default\"). */\n channel: string;\n /** The transport's call-site label (default \"matrxTransport\"). */\n source: string;\n}\n\n/**\n * The typed diagnostics sink — the host wires these to its telemetry/capture\n * systems; all optional, and the transport is fully functional without them.\n */\nexport interface MatrxTransportDiagnostics {\n /** Fired at the last pre-fetch moment of every call. */\n onRequest?: (info: MatrxRequestInfo) => void;\n /**\n * Fired for every thrown network failure and every non-2xx response not\n * listed in `expectedErrorStatuses`, with the classified envelope.\n */\n onError?: (error: MatrxCallError, info: MatrxRequestInfo) => void;\n /** Fired on every v2 → v1 protocol downgrade. */\n onProtocolDowngrade?: (downgrade: MatrxProtocolDowngrade) => void;\n}\n\nexport interface CreateMatrxTransportOptions {\n /** Fixed base URL, no trailing slash. Exactly one of `baseUrl` / `resolveTarget`. */\n baseUrl?: string;\n /**\n * Per-call target resolver — for hosts whose base URL / policy headers are\n * dynamic (server toggles, sandbox overrides, conversation channels).\n * Resolution runs fresh on EVERY call. May throw to refuse a call loudly.\n */\n resolveTarget?: () => MatrxTransportTarget;\n /**\n * The credential source (`@ai-matrx/data`), read fresh per call so token\n * refreshes are picked up mid-run. Omit only when the resolver's\n * `policyHeaders` already carry the credentials.\n */\n credentials?: CredentialsPort;\n /**\n * The org-context binding. When configured, every call REQUIRES a valid org\n * (fail-closed `organization_context_required` before the wire) and carries\n * `X-Organization-Id`. Omit for conversation-lane transports, which send the\n * org in the body only.\n */\n organizationId?: string | (() => string | null | undefined);\n /** AI API protocol version (value or per-call getter). Default `\"v2\"`. */\n aiApiVersion?: MatrxAiApiVersion | (() => MatrxAiApiVersion);\n /** Max ms request start → response headers. Default 15_000. */\n connectTimeoutMs?: number;\n /**\n * Max ms for the whole handshake. Default `null` (uncapped) — the port\n * cannot tell a JSON call from a long-lived stream, and capping would kill\n * long streams; the connect timeout is the real JSON guard.\n */\n totalTimeoutMs?: number | null;\n /**\n * HTTP failures this transport's call class fully handles as expected\n * domain outcomes (e.g. 404 on runtime-operation identify). They still\n * reach the package client (which maps them to typed results) but are not\n * reported through `onError`.\n */\n expectedErrorStatuses?: readonly number[];\n /** Short call-site label surfaced on `MatrxRequestInfo` (default \"matrxTransport\"). */\n source?: string;\n diagnostics?: MatrxTransportDiagnostics;\n}\n\nconst PRODUCTION_CONNECT_TIMEOUT_MS = 15_000;\n\nfunction stripContentType(\n headers: Record<string, string>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([name]) => name.toLowerCase() !== \"content-type\",\n ),\n );\n}\n\n/**\n * Build the production `MatrxTransport`. See the module doc for the pipeline;\n * every knob defaults to the proven production value.\n */\nexport function createMatrxTransport(\n options: CreateMatrxTransportOptions,\n): MatrxTransport {\n const {\n baseUrl,\n resolveTarget,\n credentials,\n organizationId,\n aiApiVersion,\n connectTimeoutMs = PRODUCTION_CONNECT_TIMEOUT_MS,\n totalTimeoutMs = null,\n expectedErrorStatuses,\n diagnostics,\n source = \"matrxTransport\",\n } = options;\n\n if ((baseUrl === undefined) === (resolveTarget === undefined)) {\n throw new Error(\n \"createMatrxTransport: provide exactly one of `baseUrl` or `resolveTarget`.\",\n );\n }\n\n const resolve: () => MatrxTransportTarget =\n resolveTarget ?? (() => ({ baseUrl: baseUrl as string }));\n\n const resolveVersion = (): MatrxAiApiVersion => {\n if (aiApiVersion === undefined) return MATRX_AI_API_VERSION_DEFAULT;\n return typeof aiApiVersion === \"function\" ? aiApiVersion() : aiApiVersion;\n };\n\n const resolveOrganizationId = (): string | null => {\n if (organizationId === undefined) return null;\n const candidate =\n typeof organizationId === \"function\" ? organizationId() : organizationId;\n // Fail closed: a configured org lane with no org refuses before the wire.\n return requireOrganizationContext(candidate);\n };\n\n return {\n async fetch(path: string, init: MatrxTransportRequest): Promise<Response> {\n const target = resolve();\n\n // `path` is already interpolated (`/ai/agents/<uuid>`), so the version\n // transform is the concrete-path bridge, not a template registry.\n const versionedPath = applyAiApiVersion(path, resolveVersion());\n const url = `${target.baseUrl}${versionedPath}`;\n\n // Wire headers FIRST; credentials, then resolver policy headers, then\n // the org header on top — none of them may carry Content-Type.\n const credentialHeaders = credentials\n ? credentialToHeaders(await credentials.get())\n : {};\n let headers: Record<string, string> = {\n ...init.headers,\n ...stripContentType(credentialHeaders),\n ...stripContentType(target.policyHeaders ?? {}),\n };\n const orgId = resolveOrganizationId();\n if (orgId !== null) {\n headers = applyOrganizationContextHeader(headers, orgId);\n }\n\n const info: MatrxRequestInfo = {\n url,\n method: init.method,\n path,\n channel: target.channel ?? \"default\",\n source,\n };\n diagnostics?.onRequest?.(info);\n\n let response: Response;\n try {\n ({ response } = await fetchWithMatrxProtocolFallback(\n url,\n {\n method: init.method,\n headers,\n ...(init.body !== undefined ? { body: init.body } : {}),\n },\n {\n ...(init.signal ? { signal: init.signal } : {}),\n connectTimeoutMs,\n totalTimeoutMs,\n throwOnHttpError: false,\n ...(diagnostics?.onProtocolDowngrade\n ? { onDowngrade: diagnostics.onProtocolDowngrade }\n : {}),\n },\n ));\n } catch (err) {\n diagnostics?.onError?.(normalizeMatrxError(err), info);\n throw err;\n }\n\n if (!response.ok && !expectedErrorStatuses?.includes(response.status)) {\n // The package client consumes the original body for its\n // MatrxApiError; read the diagnostics copy from a clone so the two\n // never fight.\n const serverDetail: unknown = await response\n .clone()\n .json()\n .catch(() => undefined);\n const code = extractMatrxErrorCode(serverDetail);\n diagnostics?.onError?.(\n {\n type: classifyStatus(response.status),\n message:\n extractMatrxErrorMessage(serverDetail) ??\n `HTTP ${response.status}`,\n status: response.status,\n serverDetail,\n ...(code ? { code } : {}),\n },\n info,\n );\n }\n\n return response;\n },\n };\n}\n","import { isUuidShape } from \"@ai-matrx/kit/uuid\";\n\n/**\n * The fail-closed organization-context kernel — ONE implementation for every\n * Matrx client transport (moved in from matrx-frontend\n * `lib/api/organization-context.ts` verbatim under C22; the host module is now\n * a re-export of this one).\n *\n * Transports resolve their authoritative organization first, then use these\n * functions to bind that exact value without guessing or defaulting. The\n * server never manufactures an org (it 422s a blank one), so the client\n * refuses before the wire: a missing or malformed org id throws\n * `OrganizationContextError` instead of sending a request that cannot succeed.\n */\n\nexport type OrganizationContextErrorCode =\n | \"organization_context_required\"\n | \"organization_context_invalid\"\n | \"organization_context_mismatch\";\n\nexport class OrganizationContextError extends Error {\n readonly code: OrganizationContextErrorCode;\n\n constructor(code: OrganizationContextErrorCode, message: string) {\n super(message);\n this.name = \"OrganizationContextError\";\n this.code = code;\n }\n}\n\ndeclare const organizationOperationBrand: unique symbol;\n\n/** A validated organization operation; construct only through the factory. */\nexport type OrganizationOperation = Readonly<{\n organization_id: string;\n readonly [organizationOperationBrand]: true;\n}>;\n\nexport function createOrganizationOperation(\n organizationId: string,\n): OrganizationOperation {\n const organization_id = requireOrganizationContext(organizationId);\n return Object.freeze({ organization_id }) as OrganizationOperation;\n}\n\nexport function assertOrganizationMatchesOperation(\n operation: OrganizationOperation,\n organizationId: string,\n): void {\n if (operation.organization_id !== requireOrganizationContext(organizationId)) {\n throw new OrganizationContextError(\n \"organization_context_mismatch\",\n \"Organization ID must match the request operation.\",\n );\n }\n}\n\n/**\n * Normalize and validate the effective organization id for a request. The\n * override (an explicit per-call value) beats the selected context value.\n * Throws `organization_context_required` when neither is present and\n * `organization_context_invalid` when the candidate is not a UUID.\n */\nexport function requireOrganizationContext(\n selectedOrganizationId: string | null | undefined,\n overrideOrganizationId?: string,\n): string {\n const candidate = overrideOrganizationId ?? selectedOrganizationId;\n if (typeof candidate !== \"string\" || candidate.trim().length === 0) {\n throw new OrganizationContextError(\n \"organization_context_required\",\n \"Select an organization before sending this request.\",\n );\n }\n\n const normalized = candidate.trim();\n if (!isUuidShape(normalized)) {\n throw new OrganizationContextError(\n \"organization_context_invalid\",\n \"The selected organization ID is invalid.\",\n );\n }\n return normalized.toLowerCase();\n}\n\n/**\n * Bind `X-Organization-Id` onto a header bag. A pre-existing org header that\n * disagrees with the context org is a `organization_context_mismatch` error —\n * never silently overwritten in either direction.\n */\nexport function applyOrganizationContextHeader(\n headers: Record<string, string>,\n organizationId: string,\n): Record<string, string> {\n const normalizedOrganizationId = requireOrganizationContext(organizationId);\n for (const [name, value] of Object.entries(headers)) {\n if (\n name.toLowerCase() === \"x-organization-id\" &&\n value.trim().toLowerCase() !== normalizedOrganizationId\n ) {\n throw new OrganizationContextError(\n \"organization_context_mismatch\",\n \"X-Organization-Id must match the request context organization.\",\n );\n }\n }\n const withoutOrganizationHeader = Object.fromEntries(\n Object.entries(headers).filter(\n ([name]) => name.toLowerCase() !== \"x-organization-id\",\n ),\n );\n return {\n ...withoutOrganizationHeader,\n \"X-Organization-Id\": normalizedOrganizationId,\n };\n}\n\n/**\n * Assert that an `organization_id` query parameter (when present) matches the\n * request context organization — the query string must never smuggle a\n * different org past the header binding.\n */\nexport function assertQueryOrganizationMatchesContext(\n queryParams: Record<string, string | number | boolean> | undefined,\n organizationId: string,\n): void {\n if (!queryParams || queryParams.organization_id === undefined) return;\n const queryOrganizationId = requireOrganizationContext(\n String(queryParams.organization_id),\n );\n if (queryOrganizationId !== requireOrganizationContext(organizationId)) {\n throw new OrganizationContextError(\n \"organization_context_mismatch\",\n \"Query organization_id must match the request context organization.\",\n );\n }\n}\n","/**\n * The AI API protocol-version policy — which version of the AI runtime a\n * Matrx client talks to, and the v2 → v1 transport fallback (moved in from\n * matrx-frontend `lib/api/ai-api-version.ts` + `call-api.ts::\n * fetchWithV2Fallback` under C22; server truth\n * `aidream/docs/runtime/V2_FRONTEND_MIGRATION.md`).\n *\n * Background: the Python backend exposes a `/v2` runtime-spine namespace that\n * wraps the core AI request surfaces in a request-tracking envelope. Body,\n * headers, and streaming response are BYTE-IDENTICAL to v1 — only the URL\n * differs.\n *\n * ─── The one rule that keeps burning us ─────────────────────────────────────\n * `/v2` is inserted at the FRONT of the in-app path, right before `/ai`:\n *\n * /ai/agents/{id} → /v2/ai/agents/{id} ✅ correct\n * /ai/v2/agents/… ❌ WRONG (nested) — 404s\n *\n * `toV2Path` below is the ONLY place this transform is spelled out.\n *\n * ─── Scope: ONLY the covered surfaces have a v2 form ────────────────────────\n * chat, manual, agents/{id}, conversations/{id} (+ singular aliases),\n * prompts/{id}, mandates/{key}. EVERYTHING ELSE — cancel, warm, resume,\n * fork-and-run, runtime operations, files … — has NO v2 route, and the server\n * does NOT auto-downgrade (a `/v2` request to an uncovered surface is a plain\n * 404). So the transform is a scoped allowlist, never a blanket prefix.\n */\n\nimport {\n isNetError,\n resilientFetch,\n type ResilientFetchOptions,\n} from \"@ai-matrx/data/net\";\n\nexport type MatrxAiApiVersion = \"v1\" | \"v2\";\n\n/**\n * The package-wide default AI API version — the production value every Matrx\n * client runs unless its host deliberately overrides\n * (`createMatrxTransport({ aiApiVersion })`).\n */\nexport const MATRX_AI_API_VERSION_DEFAULT: MatrxAiApiVersion = \"v2\";\n\n/**\n * The canonical v1 path TEMPLATES the v2 spine covers, `{param}` placeholders\n * intact — for hosts that route through a template registry.\n */\nexport const V2_COVERED_AI_PATH_TEMPLATES = [\n \"/ai/manual\",\n \"/ai/chat\",\n \"/ai/agents/{agent_id}\",\n \"/ai/agent/{agent_id}\", // singular alias — behaves identically\n \"/ai/conversations/{conversation_id}\",\n \"/ai/conversation/{conversation_id}\", // singular alias\n \"/ai/prompts/{prompt_id}\", // saved-prompt execution\n \"/ai/mandates/{mandate_key}\", // THE MANDATE DOOR — `/v2` sibling exists (routers/v2.py)\n] as const;\n\n/**\n * Insert `/v2` at the front of an in-app path. Idempotent, and prefix-aware:\n * a legacy `/api/` compatibility prefix (stripped server-side) is preserved so\n * `/api/ai/chat` → `/api/v2/ai/chat`.\n */\nexport function toV2Path(path: string): string {\n const withLead = path.startsWith(\"/\") ? path : `/${path}`;\n if (withLead.startsWith(\"/api/\")) {\n const rest = withLead.slice(\"/api\".length); // \"/ai/chat\"\n return rest.startsWith(\"/v2/\") ? withLead : `/api/v2${rest}`;\n }\n return withLead.startsWith(\"/v2/\") ? withLead : `/v2${withLead}`;\n}\n\n// Interpolated (concrete) forms of the covered surfaces — used to guard\n// callers that pass a real path (id already substituted). Anchored so ONLY the\n// exact shapes match: sub-paths like `/ai/agents/{id}/warm`,\n// `/ai/conversations/{id}/resume`, and `/ai/cancel/{id}` deliberately do NOT\n// match and stay on v1. The optional `/api` prefix mirrors `toV2Path`.\nconst COVERED_INTERPOLATED_PATH = [\n /^(?:\\/api)?\\/ai\\/manual$/,\n /^(?:\\/api)?\\/ai\\/chat$/,\n /^(?:\\/api)?\\/ai\\/agents\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/agent\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/conversations\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/conversation\\/[^/]+$/,\n /^(?:\\/api)?\\/ai\\/prompts\\/[^/]+$/, // `/warm` etc. deliberately don't match\n /^(?:\\/api)?\\/ai\\/mandates\\/[^/]+$/, // the mandate door\n];\n\n/** Whether `path` (already interpolated) is one of the covered surfaces. */\nexport function isCoveredAiPath(path: string): boolean {\n return COVERED_INTERPOLATED_PATH.some((re) => re.test(path));\n}\n\n/**\n * Whether an in-app path (or a full URL whose path was built by `toV2Path`)\n * targets the v2 namespace — the guard the downgrade fallback keys off.\n */\nexport function isV2Path(pathOrUrl: string): boolean {\n return /\\/v2\\/ai\\//.test(pathOrUrl);\n}\n\n/**\n * The inverse of `toV2Path` — strip the `/v2` version segment so a transport\n * failure of the v2 endpoint (network error, 404/405, 5xx BEFORE any stream\n * content) can retry the identical request on the v1 route. Works on a bare\n * path, an `/api`-prefixed path, or a full URL (the `/v2/ai/` shape is unique\n * to the version namespace). Idempotent on non-v2 input.\n */\nexport function toV1FallbackUrl(url: string): string {\n return url.replace(/\\/v2\\/ai\\//, \"/ai/\");\n}\n\n/**\n * Apply the active AI API version to an ALREADY-INTERPOLATED in-app path.\n *\n * - Covered surface + v2 → `/v2` prefix inserted.\n * - Anything else (or v1) → returned unchanged.\n *\n * Pass the in-app PATH only (no scheme/host); prepend the base URL afterward.\n */\nexport function applyAiApiVersion(\n path: string,\n version: MatrxAiApiVersion,\n): string {\n if (version !== \"v2\") return path;\n return isCoveredAiPath(path) ? toV2Path(path) : path;\n}\n\n/** One v2 → v1 downgrade, surfaced to the host's diagnostics sink. */\nexport interface MatrxProtocolDowngrade {\n /** The failed v2 URL. */\n url: string;\n /** Why the downgrade fired (thrown error text, or `HTTP <status>`). */\n reason: string;\n /** HTTP status when the trigger was a response (404/405/5xx). */\n status?: number;\n}\n\nexport interface MatrxProtocolFallbackOptions extends ResilientFetchOptions {\n /**\n * Fired on every downgrade — a sustained stream of these means a v2 surface\n * is unhealthy. The fallback also `console.warn`s unconditionally (parity\n * with the original host pipeline) so the signal never disappears silently.\n */\n onDowngrade?: (downgrade: MatrxProtocolDowngrade) => void;\n}\n\n/**\n * `resilientFetch` with the v2 → v1 transport fallback. Fires ONLY when a\n * `/v2/ai/...` ENDPOINT itself fails — a network-layer throw (non-abort), a\n * 404/405 (surface not on v2), or a 5xx — always BEFORE any stream content is\n * consumed. Never on an application error (those fail identically on v1), and\n * never on a caller abort (a user cancel must not be logged as a downgrade —\n * that poisons the exact telemetry the rollout reads to judge v2 health).\n */\nexport async function fetchWithMatrxProtocolFallback(\n url: string,\n init: RequestInit,\n opts: MatrxProtocolFallbackOptions = {},\n): Promise<{ response: Response }> {\n const { onDowngrade, ...fetchOpts } = opts;\n const logDowngrade = (reason: string, status?: number) => {\n console.warn(\n `[matrx] ai_v2_downgrade → retrying on v1. v2=${url} reason=${reason}`,\n );\n onDowngrade?.({ url, reason, ...(status !== undefined ? { status } : {}) });\n };\n if (!isV2Path(url)) return resilientFetch(url, init, fetchOpts);\n let result: { response: Response };\n try {\n result = await resilientFetch(url, init, fetchOpts);\n } catch (err) {\n // resilientFetch normalizes a caller-signal abort to NetError code\n // \"aborted\" (AbortedError); a raw AbortError is checked too for safety.\n const isAbort =\n (isNetError(err) && err.code === \"aborted\") ||\n (err instanceof Error && err.name === \"AbortError\");\n if (isAbort) throw err;\n logDowngrade(String(err));\n return resilientFetch(toV1FallbackUrl(url), init, fetchOpts);\n }\n const status = result.response.status;\n if (status === 404 || status === 405 || status >= 500) {\n logDowngrade(`HTTP ${status}`, status);\n return resilientFetch(toV1FallbackUrl(url), init, fetchOpts);\n }\n return result;\n}\n","/**\n * The conversation-start contract — client-minted `conversation_id`, `is_new`,\n * `store` — typed exactly per the cross-repo System of Record\n * (`common-docs/systems/agents/conversation-start-contract/FEATURE.md`;\n * server truth `aidream/services/conversation_context/scope.py::\n * ConversationStartRequest`).\n *\n * Every request that STARTS a conversation sends all three fields, no\n * defaults:\n *\n * | `is_new` | `store` | Result |\n * |----------|---------|----------------------------------------------------------|\n * | true | true | Create the row with the caller's id — 409 if it exists |\n * | true | false | No row. The id is correlation only (ephemeral run) |\n * | false | true | Continue it — 404 if the caller doesn't own it |\n * | false | false | Ephemeral run on a known id; nothing read, nothing written |\n *\n * `store` is the ONLY ephemeral signal; `is_new` is the caller's assertion\n * about the id, never a persistence switch. `prior_messages` (the client-owned\n * transcript of an ephemeral multi-turn run) is only valid with\n * `store: false` — the union below makes the invalid combination\n * unrepresentable, mirroring the server's 422.\n *\n * Continue routes (`POST /ai/conversations/{id}`) take the id from the path\n * and do not carry this triple.\n */\n\n/** Recursive JSON value — the package's honest type for free-form wire bags. */\nexport type MatrxJsonValue =\n | string\n | number\n | boolean\n | null\n | MatrxJsonValue[]\n | { [key: string]: MatrxJsonValue };\n\n/** A JSON object on the wire. */\nexport type MatrxJsonObject = { [key: string]: MatrxJsonValue };\n\n/**\n * One LLM message on the request wire — `prior_messages` entries for\n * stateless multi-turn runs. Mirrors aidream's `ChatMessageInput`\n * (`aidream/schemas/messages.py`, `extra=\"allow\"` — additional provider\n * fields round-trip untouched).\n */\nexport interface MatrxChatMessage {\n role: string;\n content?: string | MatrxJsonValue[] | null;\n name?: string | null;\n tool_call_id?: string | null;\n tool_calls?: MatrxJsonObject[] | null;\n [extra: string]: MatrxJsonValue | undefined;\n}\n\n/** `is_new: true, store: true` — create the row with the caller's id. */\nexport interface MatrxStoredConversationCreate {\n conversation_id: string;\n is_new: true;\n store: true;\n}\n\n/** `is_new: false, store: true` — continue an owned stored conversation via a start route. */\nexport interface MatrxStoredConversationContinue {\n conversation_id: string;\n is_new: false;\n store: true;\n}\n\n/**\n * `store: false` — ephemeral: nothing read, nothing written; the id is the\n * caller's correlation handle. This is the ONLY member that may carry\n * `prior_messages` (the server 422s a client transcript on a stored run).\n */\nexport interface MatrxEphemeralConversation {\n conversation_id: string;\n is_new: boolean;\n store: false;\n prior_messages?: MatrxChatMessage[];\n}\n\n/** The full conversation-start triple, one member per contract cell. */\nexport type MatrxConversationStart =\n | MatrxStoredConversationCreate\n | MatrxStoredConversationContinue\n | MatrxEphemeralConversation;\n\n/** Mint a fresh client-side conversation id (the contract requires the CLIENT to mint it). */\nexport function mintMatrxConversationId(): string {\n return crypto.randomUUID();\n}\n\n/** Start a NEW stored conversation (`is_new: true, store: true`). */\nexport function newStoredConversationStart(\n conversationId?: string,\n): MatrxStoredConversationCreate {\n return {\n conversation_id: conversationId ?? mintMatrxConversationId(),\n is_new: true,\n store: true,\n };\n}\n\n/**\n * Continue an EXISTING stored conversation through a start route\n * (`is_new: false, store: true` — 404 when the caller doesn't own the id).\n * Prefer `continueAgentConversation` (the dedicated continue route) for\n * ordinary follow-up turns.\n */\nexport function continueStoredConversationStart(\n conversationId: string,\n): MatrxStoredConversationContinue {\n return { conversation_id: conversationId, is_new: false, store: true };\n}\n\n/**\n * Start a NEW ephemeral run (`is_new: true, store: false`) — a freshly minted\n * correlation id, nothing persisted.\n */\nexport function newEphemeralConversationStart(\n conversationId?: string,\n): MatrxEphemeralConversation {\n return {\n conversation_id: conversationId ?? mintMatrxConversationId(),\n is_new: true,\n store: false,\n };\n}\n\n/**\n * Continue an ephemeral multi-turn run (`is_new: false, store: false`): the\n * CLIENT owns the transcript and replays it as `prior_messages` (ordered\n * oldest-first) because the server wrote no rows to rebuild from. The server\n * still owns the agent definition, model, tools, and system prompt.\n */\nexport function continueEphemeralConversationStart(\n conversationId: string,\n priorMessages: MatrxChatMessage[],\n): MatrxEphemeralConversation {\n return {\n conversation_id: conversationId,\n is_new: false,\n store: false,\n prior_messages: priorMessages,\n };\n}\n","/**\n * Internal request plumbing for `@ai-matrx/agents/matrx`. Not part of the\n * public surface — `matrx/index.ts` deliberately does not re-export this\n * module. Everything here is pure: no globals, no work at import time.\n */\n\nimport {\n readMatrxNdjsonStream,\n type MatrxNdjsonIssue,\n type MatrxStreamEnvelope,\n type MatrxStreamEnvelopeObservation,\n} from \"../stream/ndjson\";\nimport { MatrxApiError, type MatrxTransport } from \"./transport\";\n\n/** Encode one path segment (an id) safely into a server-relative path. */\nexport function encodePathSegment(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | readonly string[]\n | undefined;\n\n/**\n * Build a query string. Array values repeat the key (`kind=a&kind=b` — the\n * FastAPI repeatable-parameter convention); undefined values are omitted.\n * Returns \"\" or a string starting with \"?\".\n */\nexport function buildQuery(params: Record<string, QueryValue>): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const entry of value) search.append(key, entry);\n } else {\n search.append(key, String(value));\n }\n }\n const encoded = search.toString();\n return encoded ? `?${encoded}` : \"\";\n}\n\nasync function readServerDetail(response: Response): Promise<unknown> {\n try {\n return (await response.json()) as unknown;\n } catch {\n return undefined;\n }\n}\n\nasync function throwApiError(path: string, response: Response): Promise<never> {\n throw new MatrxApiError({\n status: response.status,\n path,\n serverDetail: await readServerDetail(response),\n });\n}\n\nexport interface JsonRequestOptions {\n method: \"GET\" | \"POST\";\n body?: unknown;\n signal?: AbortSignal;\n}\n\n/**\n * Execute a JSON request through the transport. Throws `MatrxApiError` on a\n * non-2xx response; resolves with the parsed JSON body otherwise.\n */\nexport async function requestJson<T>(\n transport: MatrxTransport,\n path: string,\n options: JsonRequestOptions,\n): Promise<T> {\n const hasBody = options.method !== \"GET\" && options.body !== undefined;\n const response = await transport.fetch(path, {\n method: options.method,\n headers: hasBody ? { \"Content-Type\": \"application/json\" } : {},\n ...(hasBody ? { body: JSON.stringify(options.body) } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (!response.ok) return throwApiError(path, response);\n return (await response.json()) as T;\n}\n\n/**\n * Options for every streaming call, riding the NDJSON kernel's contract.\n * Public via `./run`'s re-export.\n */\nexport interface MatrxStreamCallOptions {\n /** Abort the fetch and end the events iterator. */\n signal?: AbortSignal;\n /** Bounded background read-ahead (see `stream/ndjson`). */\n maxReadAhead?: number;\n /** Malformed NDJSON is non-fatal but must never disappear silently. */\n onMalformedLine?: (issue: MatrxNdjsonIssue) => void;\n /** Valid JSON with no recognized Matrx envelope. */\n onUnknownEnvelope?: (value: unknown) => void;\n /** Observe every valid envelope in its exact wire form. */\n onValidEnvelope?: (observation: MatrxStreamEnvelopeObservation) => void;\n}\n\n/**\n * A live agent run: the server-assigned ids (from response headers, available\n * BEFORE any event) and the normalized event stream. Public via `./run`.\n */\nexport interface MatrxRunHandle {\n /** `X-Request-ID` — the ONLY id `POST /ai/cancel/{request_id}` accepts. */\n requestId: string | null;\n /** `X-Conversation-ID` — the server's conversation identity. */\n conversationId: string | null;\n /** Normalized `{event, data}` envelopes through the ONE wire kernel. */\n events: AsyncGenerator<MatrxStreamEnvelope, void, undefined>;\n /** The raw response, for hosts that need headers/status beyond the ids. */\n response: Response;\n}\n\n/**\n * Wrap a validated streaming Response into the run handle — the ONE place\n * the id headers are read and the NDJSON kernel is attached (`./run` and\n * `./operations`' rejoin share it).\n */\nexport function toRunHandle(\n response: Response,\n options: MatrxStreamCallOptions,\n): MatrxRunHandle {\n return {\n requestId: response.headers.get(\"X-Request-ID\"),\n conversationId: response.headers.get(\"X-Conversation-ID\"),\n events: readMatrxNdjsonStream(response.body as ReadableStream<Uint8Array>, {\n ...(options.signal ? { signal: options.signal } : {}),\n ...(options.maxReadAhead !== undefined\n ? { maxReadAhead: options.maxReadAhead }\n : {}),\n ...(options.onMalformedLine\n ? { onMalformedLine: options.onMalformedLine }\n : {}),\n ...(options.onUnknownEnvelope\n ? { onUnknownEnvelope: options.onUnknownEnvelope }\n : {}),\n ...(options.onValidEnvelope\n ? { onValidEnvelope: options.onValidEnvelope }\n : {}),\n }),\n response,\n };\n}\n\nexport interface StreamRequestOptions {\n method: \"GET\" | \"POST\";\n body?: unknown;\n /** Extra wire-semantic headers (`Accept`, `Last-Event-ID`). */\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\n/**\n * Execute a streaming request. Throws `MatrxApiError` on a non-2xx response\n * (reading the error body as JSON when possible) or when a 2xx response\n * carries no body; resolves with the validated `Response` otherwise.\n */\nexport async function requestStream(\n transport: MatrxTransport,\n path: string,\n options: StreamRequestOptions,\n): Promise<Response> {\n const hasBody = options.method !== \"GET\" && options.body !== undefined;\n const response = await transport.fetch(path, {\n method: options.method,\n headers: {\n ...(hasBody ? { \"Content-Type\": \"application/json\" } : {}),\n ...options.headers,\n },\n ...(hasBody ? { body: JSON.stringify(options.body) } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (!response.ok) return throwApiError(path, response);\n if (!response.body) {\n throw new MatrxApiError({\n status: response.status,\n path,\n serverDetail: { code: \"missing_response_body\" },\n message: \"The streaming response carried no body.\",\n });\n }\n return response;\n}\n","/**\n * Runtime operations — the canonical reconnect & resume read surface of the\n * execution spine, over the `MatrxTransport` port.\n *\n * Server truth (verified against aidream source,\n * `aidream/api/routers/runtime_operations.py` + `aidream/services/runtime/\n * reconnect.py`; mounted at bare `/runtime`):\n * - `GET /runtime/operations/{request_id}` — identify by `X-Request-ID`\n * - `GET /runtime/operations/by-link/{kind}/{id}` — identify by feature record\n * - `GET /runtime/executions/{id}/events` — durable seq-cursored page\n * - `GET /runtime/executions/{id}/events/stream` — SSE replay-then-follow,\n * `id:` = per-tree seq, reconnect with `Last-Event-ID`\n * - `POST /runtime/operations/{request_id}/rejoin` — replay + follow the\n * ORIGINAL NDJSON response while its detached task is alive (409 when live\n * delivery is unavailable — fall back to the durable lifecycle stream)\n *\n * The contract: identify → recover durable progress → follow live → re-query\n * the final result from the feature's own record. Token text is deliberately\n * never replayed on the lifecycle stream — that is what `/rejoin` is for.\n *\n * The SSE wire rides the package's own `stream/sse` kernel. This module owns\n * ONE connection's semantics (frames → typed events, cursor advancement,\n * terminal `end`); stall timers, retry budgets, and reconnect loops stay host\n * policy — every yielded item carries the cursor the next attempt resumes from.\n */\n\nimport { readMatrxSseStream, type MatrxSseFrame } from \"../stream/sse\";\nimport type { MatrxJsonObject } from \"./conversation\";\nimport {\n encodePathSegment,\n buildQuery,\n requestJson,\n requestStream,\n toRunHandle,\n type MatrxRunHandle,\n type MatrxStreamCallOptions,\n} from \"./internal\";\nimport { MatrxApiError, type MatrxTransport } from \"./transport\";\n\n// ─── Wire types (mirroring `aidream/services/runtime/reconnect.py`) ─────────\n\n/** `matrx_runtime.models.ExecutionStatus` — the only progress column. */\nexport type MatrxRuntimeExecutionStatus =\n | \"pending\"\n | \"running\"\n | \"paused\"\n | \"waiting_input\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\nexport const TERMINAL_MATRX_RUNTIME_STATUSES: ReadonlySet<MatrxRuntimeExecutionStatus> =\n new Set([\"completed\", \"failed\", \"cancelled\"]);\n\nconst RUNTIME_STATUSES: ReadonlySet<string> = new Set([\n \"pending\",\n \"running\",\n \"paused\",\n \"waiting_input\",\n \"completed\",\n \"failed\",\n \"cancelled\",\n]);\n\n/** One durable spine event on the wire (`OperationEvent`) — `seq` is the reconnect cursor. */\nexport interface MatrxRuntimeOperationEvent {\n seq: number | null;\n /** Lifecycle vocabulary: created | started | paused | resumed | waiting_input | completed | failed | cancelled | checkpoint_saved | note. */\n kind: string;\n execution_id: string;\n root_execution_id: string | null;\n detail: MatrxJsonObject | null;\n created_at: string | null;\n}\n\n/** One root execution as a reconnecting client sees it (`OperationView`). */\nexport interface MatrxRuntimeOperationView {\n execution_id: string;\n /** Durable request identity — feeds `/rejoin` and no-prompt resume recovery. */\n request_id: string | null;\n type: string;\n status: MatrxRuntimeExecutionStatus;\n is_terminal: boolean;\n waiting_input: boolean;\n /** Decimal on the wire — may arrive as number or string; display-only. */\n cost: number | string;\n meters: Record<string, number | string>;\n link_kind: string | null;\n link_id: string | null;\n error: MatrxJsonObject | null;\n created_at: string | null;\n started_at: string | null;\n ended_at: string | null;\n last_event_seq: number;\n events_path: string;\n stream_path: string;\n}\n\nexport interface MatrxOperationStatusResponse {\n request_id: string;\n operation_count: number;\n operations: MatrxRuntimeOperationView[];\n}\n\nexport interface MatrxOperationsByLinkResponse {\n link_kind: string;\n link_id: string;\n operation_count: number;\n operations: MatrxRuntimeOperationView[];\n}\n\nexport interface MatrxOperationEventsPage {\n execution_id: string;\n root_execution_id: string;\n events: MatrxRuntimeOperationEvent[];\n /** Feeds the next page or the SSE `Last-Event-ID` — polling and push share ONE cursor. */\n next_after_seq: number;\n has_more: boolean;\n root_status: MatrxRuntimeExecutionStatus;\n root_is_terminal: boolean;\n}\n\n// ─── Identify + durable progress ────────────────────────────────────────────\n\n/**\n * Where is my operation? Resolves an `X-Request-ID` to its root execution(s).\n * Returns null on 404 — missing and unowned share one shape by design\n * (existence is never leaked).\n */\nexport async function getRuntimeOperationStatus(\n transport: MatrxTransport,\n requestId: string,\n options: { signal?: AbortSignal } = {},\n): Promise<MatrxOperationStatusResponse | null> {\n try {\n return await requestJson<MatrxOperationStatusResponse>(\n transport,\n `/runtime/operations/${encodePathSegment(requestId)}`,\n { method: \"GET\", ...(options.signal ? { signal: options.signal } : {}) },\n );\n } catch (error) {\n if (error instanceof MatrxApiError && error.status === 404) return null;\n throw error;\n }\n}\n\n/**\n * Operations for a feature record — e.g. `(\"conversation\", conversationId)`,\n * `(\"workflow\", runId)`, `(\"agent_run\", runId)`. Newest first; unowned trees\n * omitted. Returns null on 404 (surface absent, or the caller owns nothing —\n * one shape by design).\n */\nexport async function getRuntimeOperationsByLink(\n transport: MatrxTransport,\n linkKind: string,\n linkId: string,\n options: { limit?: number; signal?: AbortSignal } = {},\n): Promise<MatrxOperationsByLinkResponse | null> {\n const query = buildQuery(\n options.limit !== undefined ? { limit: options.limit } : {},\n );\n try {\n return await requestJson<MatrxOperationsByLinkResponse>(\n transport,\n `/runtime/operations/by-link/${encodePathSegment(linkKind)}/${encodePathSegment(linkId)}${query}`,\n { method: \"GET\", ...(options.signal ? { signal: options.signal } : {}) },\n );\n } catch (error) {\n if (error instanceof MatrxApiError && error.status === 404) return null;\n throw error;\n }\n}\n\n/**\n * Durable progress page for the whole operation TREE:\n * `GET /runtime/executions/{id}/events?after_seq=…`. Pass any node id — it\n * resolves to the root.\n */\nexport function listRuntimeOperationEvents(\n transport: MatrxTransport,\n executionId: string,\n options: {\n afterSeq?: number;\n limit?: number;\n /** Repeatable event-kind filter. */\n kinds?: readonly string[];\n signal?: AbortSignal;\n } = {},\n): Promise<MatrxOperationEventsPage> {\n const query = buildQuery({\n ...(options.afterSeq !== undefined ? { after_seq: options.afterSeq } : {}),\n ...(options.limit !== undefined ? { limit: options.limit } : {}),\n ...(options.kinds !== undefined ? { kind: options.kinds } : {}),\n });\n return requestJson<MatrxOperationEventsPage>(\n transport,\n `/runtime/executions/${encodePathSegment(executionId)}/events${query}`,\n { method: \"GET\", ...(options.signal ? { signal: options.signal } : {}) },\n );\n}\n\n// ─── SSE follow (replay-then-follow with Last-Event-ID) ─────────────────────\n\n/**\n * One item from the follow stream. Every item carries `cursor` — the highest\n * event seq seen so far, which is exactly the `Last-Event-ID` a reconnect\n * resumes from (host retry policy owns the reconnect loop).\n */\nexport type MatrxOperationFollowEvent =\n | {\n /** A parsed durable spine event. */\n type: \"event\";\n event: MatrxRuntimeOperationEvent;\n /** The frame's SSE `id:` as an integer, when it carried one. */\n seq: number | null;\n cursor: number;\n }\n | {\n /**\n * A frame that carried no deliverable event — a comment heartbeat, an\n * unknown event name, or a malformed payload (also surfaced through\n * `onMalformedFrame`). ANY parsed frame proves the wire is alive: hosts\n * reset stall timers and retry budgets on it.\n */\n type: \"liveness\";\n cursor: number;\n }\n | {\n /** The server's terminal frame — the root settled; the stream is over. */\n type: \"end\";\n status: MatrxRuntimeExecutionStatus | null;\n cursor: number;\n };\n\nexport interface FollowRuntimeOperationOptions {\n /** Resume cursor — the operation view's `last_event_seq` (0 = from start). */\n lastEventSeq?: number;\n /** Abort the follow — the generator simply ends. */\n signal?: AbortSignal;\n /** A frame whose payload failed to parse — never silently dropped. */\n onMalformedFrame?: (frame: MatrxSseFrame, error: unknown) => void;\n /** Unterminated trailing SSE text at stream end (diagnostic, never an event). */\n onIncomplete?: (text: string) => void;\n}\n\nfunction parseEndStatus(data: string | null): MatrxRuntimeExecutionStatus | null {\n if (data === null) return null;\n try {\n const parsed = JSON.parse(data) as unknown;\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n typeof (parsed as { status?: unknown }).status === \"string\"\n ) {\n const status = (parsed as { status: string }).status;\n return RUNTIME_STATUSES.has(status)\n ? (status as MatrxRuntimeExecutionStatus)\n : null;\n }\n } catch {\n // malformed end payload — still terminal\n }\n return null;\n}\n\n/**\n * Follow ONE SSE connection of an operation's lifecycle stream:\n * `GET /runtime/executions/{id}/events/stream` with `Last-Event-ID` when\n * resuming past 0. Replays from the cursor, then follows live; a\n * WAITING_INPUT park keeps it open (a resume re-attaches to the same\n * execution and its events continue here). Ends after yielding\n * `{type: \"end\"}` when the root settles; a server close WITHOUT an end frame\n * simply ends the generator — reconnect from the last yielded `cursor` (host\n * retry policy).\n */\nexport async function* followRuntimeOperationEvents(\n transport: MatrxTransport,\n executionId: string,\n options: FollowRuntimeOperationOptions = {},\n): AsyncGenerator<MatrxOperationFollowEvent, void, undefined> {\n let cursor = options.lastEventSeq ?? 0;\n\n const headers: Record<string, string> = { Accept: \"text/event-stream\" };\n if (cursor > 0) headers[\"Last-Event-ID\"] = String(cursor);\n\n const response = await requestStream(\n transport,\n `/runtime/executions/${encodePathSegment(executionId)}/events/stream`,\n {\n method: \"GET\",\n headers,\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n\n const frames = readMatrxSseStream(\n response.body as ReadableStream<Uint8Array>,\n options.onIncomplete ? { onIncomplete: options.onIncomplete } : {},\n );\n\n for await (const frame of frames) {\n if (frame.event === \"end\") {\n yield { type: \"end\", status: parseEndStatus(frame.data), cursor };\n return;\n }\n if (frame.event === \"execution_event\" && frame.data !== null) {\n let event: MatrxRuntimeOperationEvent;\n try {\n event = JSON.parse(frame.data) as MatrxRuntimeOperationEvent;\n } catch (error) {\n options.onMalformedFrame?.(frame, error);\n yield { type: \"liveness\", cursor };\n continue;\n }\n if (frame.seq !== null && frame.seq > cursor) cursor = frame.seq;\n yield { type: \"event\", event, seq: frame.seq, cursor };\n continue;\n }\n // Comment heartbeats, unknown event names, data-less frames: liveness.\n yield { type: \"liveness\", cursor };\n }\n}\n\n// ─── Follow to end (the production reconnect policy) ────────────────────────\n\nexport interface FollowRuntimeOperationToEndOptions {\n /** Resume cursor — the operation view's `last_event_seq` (0 = from start). */\n lastEventSeq?: number;\n /** Caller teardown — aborting resolves with `ended: false`. */\n signal?: AbortSignal;\n /**\n * The server pings every ~15s, so a wire that is open but silent past this\n * is dead (buffering proxy, idle-killed connection) — abort the attempt and\n * retry rather than hanging forever. Default 45_000.\n */\n stallTimeoutMs?: number;\n /**\n * Consecutive failed attempts before giving up. A single-server deployment\n * deliberately drains for 60s, then starts a new container — the default\n * budget (60 × 2s) keeps following for ~three minutes so the runtime ledger\n * can bridge that handoff. ANY parsed frame resets the budget. Default 60.\n */\n reconnectLimit?: number;\n /** Delay between attempts. Default 2_000. */\n reconnectDelayMs?: number;\n /** Fired per durable spine event (lifecycle transitions + notes). */\n onEvent: (event: MatrxRuntimeOperationEvent, seq: number | null) => void;\n /** A failed attempt (never silently swallowed when provided). */\n onAttemptError?: (error: unknown) => void;\n /** A frame whose payload failed to parse (the ledger heals gaps on reconnect). */\n onMalformedFrame?: (frame: MatrxSseFrame, error: unknown) => void;\n}\n\nexport interface FollowRuntimeOperationToEndResult {\n /** True when the server sent the terminal `end` frame. */\n ended: boolean;\n /** The root status carried on the `end` frame (when `ended`). */\n status: MatrxRuntimeExecutionStatus | null;\n}\n\n/**\n * Follow an operation's lifecycle stream TO ITS END — the full production\n * reconnect policy over `followRuntimeOperationEvents`: replay-then-follow\n * with bounded reconnects, a stall watchdog, and durable `Last-Event-ID`\n * cursor advancement across attempts.\n *\n * Resolves `{ended: true, status}` on the server's `end` frame (the operation\n * settled); `{ended: false}` when the caller aborted or every reconnect\n * attempt failed. A WAITING_INPUT park keeps the stream open by design — a\n * resume re-attaches to the same execution and its events continue arriving\n * on the same cursor. Any parsed frame — comment heartbeats included —\n * proves the wire is alive and resets both the stall timer and the retry\n * budget.\n */\nexport async function followRuntimeOperationToEnd(\n transport: MatrxTransport,\n executionId: string,\n options: FollowRuntimeOperationToEndOptions,\n): Promise<FollowRuntimeOperationToEndResult> {\n const stallTimeoutMs = options.stallTimeoutMs ?? 45_000;\n const reconnectLimit = options.reconnectLimit ?? 60;\n const reconnectDelayMs = options.reconnectDelayMs ?? 2_000;\n const outer = options.signal;\n\n let cursor = options.lastEventSeq ?? 0;\n let failures = 0;\n\n while (!outer?.aborted && failures < reconnectLimit) {\n const attempt = new AbortController();\n const onOuterAbort = () => attempt.abort();\n outer?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\n let stallTimer: ReturnType<typeof setTimeout> | null = null;\n const armStall = () => {\n if (stallTimer !== null) clearTimeout(stallTimer);\n stallTimer = setTimeout(() => attempt.abort(), stallTimeoutMs);\n };\n\n try {\n const items = followRuntimeOperationEvents(transport, executionId, {\n lastEventSeq: cursor,\n signal: attempt.signal,\n ...(options.onMalformedFrame\n ? { onMalformedFrame: options.onMalformedFrame }\n : {}),\n });\n\n armStall();\n for await (const item of items) {\n armStall();\n failures = 0;\n cursor = item.cursor;\n if (item.type === \"end\") {\n return { ended: true, status: item.status };\n }\n if (item.type === \"event\") {\n options.onEvent(item.event, item.seq);\n }\n }\n // Server closed without an `end` frame (e.g. process restart). Retry —\n // `Last-Event-ID` replays anything missed from the durable ledger.\n failures += 1;\n } catch (error) {\n if (outer?.aborted) break;\n failures += 1;\n options.onAttemptError?.(error);\n } finally {\n if (stallTimer !== null) clearTimeout(stallTimer);\n outer?.removeEventListener(\"abort\", onOuterAbort);\n }\n\n if (!outer?.aborted && failures < reconnectLimit) {\n await new Promise((r) => setTimeout(r, reconnectDelayMs));\n }\n }\n\n return { ended: false, status: null };\n}\n\n// ─── NDJSON rejoin (replay the original response) ───────────────────────────\n\n/**\n * Rejoin the ORIGINAL NDJSON response while its detached task is still alive:\n * `POST /runtime/operations/{request_id}/rejoin`. Replays the response from\n * frame one, then continues live — every frame is sequence-stamped\n * (`stream_seq`), so a same-page reconnect can drop frames it already\n * rendered. Throws `MatrxApiError` with status 409 when live delivery is\n * unavailable — fall back to `followRuntimeOperationEvents` + a final record\n * re-query. The `requestId` must be the server's `X-Request-ID`.\n */\nexport async function rejoinRuntimeOperation(\n transport: MatrxTransport,\n requestId: string,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n const response = await requestStream(\n transport,\n `/runtime/operations/${encodePathSegment(requestId)}/rejoin`,\n {\n method: \"POST\",\n // The route takes no body model; the reference client posts an empty\n // JSON object. Match it so proxies see an ordinary JSON POST.\n body: {},\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n return toRunHandle(response, options);\n}\n","/**\n * Resume-or-rejoin — the ONE client behavior for \"pick a run back up\".\n *\n * Server truth (aidream `services/runtime/FEATURE.md` § \"A live run is\n * REJOINED, never resumed beside itself\"; `reconnect.run_in_progress_error`):\n * - Every resume / retry / continue door asked to resume a run that is STILL\n * LIVE answers `409` with, at the ROOT of the error body,\n * `{error, code: \"run_in_progress\", live_request_id, rejoin_path, message,\n * …extras}` (extras: `run_id` for workflow / SEO / comparison, `arm_index` /\n * `arm`, `analysis_id`). The client follows `rejoin_path` — never a URL it\n * builds — because a door outside the spine (SEO collections) answers\n * `live_request_id: null` with its own `/seo/collections/{run_id}/rejoin`.\n * - Chat/conversation resume keeps `code: \"resume_conflict\"` for older clients\n * but ALSO carries `live_request_id` + `rejoin_path` (+\n * `details.live_request_id`) when the run is live — then rejoin, never the\n * retry loop. A bare `resume_conflict` (no rejoin target) stays host retry.\n * - The envelope RESERVES `request_id` for the refusing call's own id — the\n * live run is read from `live_request_id`, never `request_id` (reading it\n * rejoined a request that did not exist: 404, 2026-10-01).\n * - A rejoin answers `409 live_stream_unavailable` when there is no journal to\n * replay (resumed workflow legs, comparison arms). Then: a body naming a\n * workflow `run_id` → follow `GET /runs/{run_id}/events/stream` (the workflow\n * SSE, which also carries the node_stream media frames); otherwise follow the\n * durable lifecycle (`followRuntimeOperationToEnd`).\n *\n * Resume and rejoin are work on an EXISTING run, so they carry THAT run's\n * organization (`organizationId`), never whatever the session has selected.\n */\n\nimport type { MatrxStreamEnvelope } from \"../stream/ndjson\";\nimport { readMatrxSseStream } from \"../stream/sse\";\nimport {\n encodePathSegment,\n requestStream,\n toRunHandle,\n type MatrxRunHandle,\n type MatrxStreamCallOptions,\n} from \"./internal\";\nimport {\n followRuntimeOperationToEnd,\n getRuntimeOperationStatus,\n type FollowRuntimeOperationToEndOptions,\n type MatrxRuntimeExecutionStatus,\n type MatrxRuntimeOperationEvent,\n} from \"./operations\";\nimport { requireOrganizationContext } from \"./org-context\";\nimport { MatrxApiError, type MatrxTransport } from \"./transport\";\n\nexport const MATRX_RUN_IN_PROGRESS = \"run_in_progress\";\nexport const MATRX_RESUME_CONFLICT = \"resume_conflict\";\nexport const MATRX_LIVE_STREAM_UNAVAILABLE = \"live_stream_unavailable\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonBlank(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value : null;\n}\n\n/**\n * Any error carrying an HTTP status and the parsed server body —\n * `MatrxApiError`, matrx-frontend's `ApiCallError`, or a host's own shape.\n */\nexport interface MatrxHttpErrorLike {\n status?: unknown;\n serverDetail?: unknown;\n}\n\n/** The places a structured detail can sit: FastAPI `detail`, envelope `details`, envelope top level. */\nfunction detailCandidates(body: unknown): Record<string, unknown>[] {\n if (!isRecord(body)) return [];\n const out: Record<string, unknown>[] = [];\n if (isRecord(body.detail)) out.push(body.detail);\n if (isRecord(body.details)) out.push(body.details);\n out.push(body);\n return out;\n}\n\nfunction statusOf(error: unknown): number | null {\n if (!isRecord(error) && !(error instanceof Error)) return null;\n const status = (error as MatrxHttpErrorLike).status;\n return typeof status === \"number\" ? status : null;\n}\n\nfunction bodyOf(error: unknown): unknown {\n if (!isRecord(error) && !(error instanceof Error)) return undefined;\n return (error as MatrxHttpErrorLike).serverDetail;\n}\n\n/**\n * The machine code of a Matrx HTTP error: `code` (or the envelope's hoisted\n * `error`) from `detail`, `details`, or the top level. Null when absent.\n */\nexport function readMatrxErrorCode(error: unknown): string | null {\n for (const candidate of detailCandidates(bodyOf(error))) {\n const code = nonBlank(candidate.code);\n if (code) return code;\n }\n for (const candidate of detailCandidates(bodyOf(error))) {\n const code = nonBlank(candidate.error);\n if (code) return code;\n }\n return null;\n}\n\n/** Where to rejoin a live run, read from a resume door's 409. */\nexport interface MatrxLiveRunRejoin {\n /** The live request (`GET /runtime/operations/{id}`); null for doors outside the spine (SEO). */\n liveRequestId: string | null;\n /** Server-relative path to `POST` for the NDJSON replay-then-follow. Always from the body when present. */\n rejoinPath: string;\n /** `run_id` extra (workflow / SEO / comparison), when present. */\n runId: string | null;\n /** The refusal's code: `run_in_progress`, or chat's `resume_conflict` carrying a rejoin target. */\n code: string;\n /** The refusal body (root of the envelope), for door-specific extras (`arm_index`, `analysis_id`, …). */\n body: Record<string, unknown>;\n}\n\nfunction firstString(candidates: Record<string, unknown>[], key: string): string | null {\n for (const candidate of candidates) {\n const value = nonBlank(candidate[key]);\n if (value) return value.trim();\n }\n return null;\n}\n\n/**\n * The rejoin target of a live-run refusal: `409` with `code: run_in_progress`,\n * or chat's `409 resume_conflict` that names a live run. Null for every other\n * error (a genuine failure is never mistaken for a live run). Reads\n * `rejoin_path` from the body first; derives the runtime rejoin from\n * `live_request_id` only when the body names no path. Never reads\n * `request_id`.\n */\nexport function readLiveRunRejoin(error: unknown): MatrxLiveRunRejoin | null {\n if (statusOf(error) !== 409) return null;\n const candidates = detailCandidates(bodyOf(error));\n if (candidates.length === 0) return null;\n const code = readMatrxErrorCode(error);\n if (code !== MATRX_RUN_IN_PROGRESS && code !== MATRX_RESUME_CONFLICT) return null;\n const liveRequestId = firstString(candidates, \"live_request_id\");\n const pathFromBody = firstString(candidates, \"rejoin_path\");\n const rejoinPath =\n pathFromBody && pathFromBody.startsWith(\"/\")\n ? pathFromBody\n : liveRequestId\n ? runtimeOperationRejoinPath(liveRequestId)\n : null;\n if (!rejoinPath) return null;\n const root = bodyOf(error);\n return {\n liveRequestId,\n rejoinPath,\n runId: firstString(candidates, \"run_id\"),\n code,\n body: isRecord(root) ? root : {},\n };\n}\n\n/**\n * The request id of a run that is STILL LIVE, read from a resume door's\n * refusal (`live_request_id` — never the envelope's own `request_id`). Null\n * for every other error, and for a live refusal outside the spine (SEO) —\n * follow `readLiveRunRejoin(error).rejoinPath` instead.\n */\nexport function readLiveRunRequestId(error: unknown): string | null {\n return readLiveRunRejoin(error)?.liveRequestId ?? null;\n}\n\n/**\n * A bare `409 resume_conflict` — another resume holds the claim and NO live\n * run is named; retry is host policy. (A `resume_conflict` that names a live\n * run is a rejoin — `readLiveRunRejoin`.)\n */\nexport function isResumeConflict(error: unknown): boolean {\n return (\n statusOf(error) === 409 &&\n readMatrxErrorCode(error) === MATRX_RESUME_CONFLICT &&\n readLiveRunRejoin(error) === null\n );\n}\n\n/** `409 live_stream_unavailable` — the rejoin journal is gone; follow the durable lifecycle instead. */\nexport function isLiveStreamUnavailable(error: unknown): boolean {\n return (\n statusOf(error) === 409 &&\n readMatrxErrorCode(error) === MATRX_LIVE_STREAM_UNAVAILABLE\n );\n}\n\n/**\n * The server-relative rejoin path — for hosts whose stream pipeline takes a\n * URL instead of a transport (prepend the resolved base URL).\n */\nexport function runtimeOperationRejoinPath(requestId: string): string {\n return `/runtime/operations/${encodePathSegment(requestId)}/rejoin`;\n}\n\n/**\n * The text to show for a stream `error` event: the server's `user_message`\n * first (it is written for the person — e.g. \"OpenAI refused this request:\n * the platform's OpenAI account is out of credit.\"), then `message`. Accepts\n * the `{event, data}` envelope or its `data` payload. Null when neither is\n * present — the host supplies its own fallback; it must never REPLACE a\n * message the server sent.\n */\nexport function streamErrorText(eventOrPayload: unknown): string | null {\n if (!isRecord(eventOrPayload)) return null;\n const payload =\n typeof eventOrPayload.event === \"string\" && isRecord(eventOrPayload.data)\n ? eventOrPayload.data\n : eventOrPayload;\n return nonBlank(payload.user_message) ?? nonBlank(payload.message);\n}\n\n/**\n * Open any Matrx NDJSON stream by path (`POST`, optional JSON body) — for\n * feature doors outside the agent lifecycle (`/podcast/resume/{run_id}`, …)\n * so their streams ride the same transport and wire kernel as every run.\n */\nexport async function openMatrxStream(\n transport: MatrxTransport,\n path: string,\n options: MatrxStreamCallOptions & { body?: unknown } = {},\n): Promise<MatrxRunHandle> {\n const response = await requestStream(transport, path, {\n method: \"POST\",\n ...(options.body !== undefined ? { body: options.body } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n });\n return toRunHandle(response, options);\n}\n\n/**\n * Bind a run's organization onto every call as `X-Organization-Id`. Host\n * policy headers still merge on top; the package's own `createMatrxTransport`\n * refuses a disagreeing org (`organization_context_mismatch`) rather than\n * silently swapping it, so a host must not force the SESSION org onto a\n * resume/rejoin transport.\n */\nexport function withRunOrganization(\n transport: MatrxTransport,\n organizationId: string,\n): MatrxTransport {\n const orgId = requireOrganizationContext(organizationId);\n return {\n fetch: (path, init) =>\n transport.fetch(path, {\n ...init,\n headers: { ...init.headers, \"X-Organization-Id\": orgId },\n }),\n };\n}\n\n/**\n * Follow a workflow run's SSE (`GET /runs/{run_id}/events/stream`) — the\n * rejoin fallback for workflow legs with no stream journal. Delivers every\n * parsed event (durable run events with their seq; ephemeral `node_stream`\n * frames — including `kind: \"media\"` — with seq null). One connection, no\n * reconnect policy: resolves `{ended: true}` on the server's `end` frame,\n * `{ended: false}` when the wire closes or the caller aborts.\n */\nexport async function followWorkflowRunEvents(\n transport: MatrxTransport,\n runId: string,\n options: {\n onEvent: (event: Record<string, unknown>, seq: number | null) => void;\n lastEventId?: number | null;\n signal?: AbortSignal;\n },\n): Promise<{ ended: boolean }> {\n const headers: Record<string, string> = { Accept: \"text/event-stream\" };\n if (options.lastEventId) headers[\"Last-Event-ID\"] = String(options.lastEventId);\n let response: Response;\n try {\n response = await requestStream(\n transport,\n `/runs/${encodePathSegment(runId)}/events/stream`,\n {\n method: \"GET\",\n headers,\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n } catch (error) {\n if (options.signal?.aborted) return { ended: false };\n throw error;\n }\n try {\n for await (const frame of readMatrxSseStream(\n response.body as ReadableStream<Uint8Array>,\n )) {\n if (frame.event === \"end\") return { ended: true };\n if (frame.data === null) continue;\n let parsed: unknown;\n try {\n parsed = JSON.parse(frame.data);\n } catch {\n continue;\n }\n if (!isRecord(parsed)) continue;\n options.onEvent(parsed, parsed.event === \"node_stream\" ? null : frame.seq);\n }\n } catch (error) {\n if (!options.signal?.aborted) throw error;\n }\n return { ended: false };\n}\n\nexport type ResumeOrRejoinOutcome =\n /** The resume door ran the run; its stream was delivered to `onEnvelope`. */\n | { kind: \"resumed\"; requestId: string | null }\n /** The run was live; its stream (from `rejoin_path`) was replayed + followed into `onEnvelope`. */\n | { kind: \"rejoined\"; rejoin: MatrxLiveRunRejoin }\n /**\n * The run was live but had no journal to replay; the durable lifecycle was\n * followed instead. Re-query the feature's record for the result.\n * `ended: false` = the follow gave up (or no operation was found).\n */\n | {\n kind: \"followed\";\n rejoin: MatrxLiveRunRejoin;\n executionId: string | null;\n ended: boolean;\n status: MatrxRuntimeExecutionStatus | null;\n }\n /** No journal, and the run is a workflow: its run SSE was followed into `onWorkflowEvent`. */\n | { kind: \"followed_workflow\"; rejoin: MatrxLiveRunRejoin; runId: string; ended: boolean }\n /** A bare `409 resume_conflict` (no live run named) — retry with the host's backoff policy. */\n | { kind: \"resume_conflict\"; error: MatrxApiError };\n\nexport interface ResumeOrRejoinOptions\n extends Omit<MatrxStreamCallOptions, \"signal\"> {\n /** Every NDJSON envelope — from the resume stream OR the rejoined stream. */\n onEnvelope: (envelope: MatrxStreamEnvelope) => void;\n /** THE RUN'S organization (from its durable record) — bound on every call. */\n organizationId?: string | null;\n signal?: AbortSignal;\n /** Fired the moment a live run is detected, before the rejoin opens (reset replay-sensitive state). */\n onRejoin?: (rejoin: MatrxLiveRunRejoin) => void;\n /** Durable lifecycle events while following (the no-journal fallback). */\n onOperationEvent?: (event: MatrxRuntimeOperationEvent) => void;\n /** Workflow run SSE events (the no-journal fallback for a workflow `run_id`). */\n onWorkflowEvent?: (event: Record<string, unknown>, seq: number | null) => void;\n /** Tuning for the durable follow (stall / reconnect policy). */\n follow?: Omit<\n FollowRuntimeOperationToEndOptions,\n \"onEvent\" | \"signal\" | \"lastEventSeq\"\n >;\n}\n\nasync function drain(\n handle: MatrxRunHandle,\n onEnvelope: (envelope: MatrxStreamEnvelope) => void,\n): Promise<void> {\n for await (const envelope of handle.events) onEnvelope(envelope);\n}\n\n/**\n * Resume a run — or, when the server says it is still live, REJOIN it.\n *\n * Calls `resumeCall` (the feature's resume door) and pipes its stream into\n * `onEnvelope`. On a live-run refusal (`run_in_progress`, or chat's\n * `resume_conflict` naming a live run) it follows the body's `rejoin_path`\n * into the SAME handler under the same organization; when the rejoin has no\n * journal (`live_stream_unavailable`) it follows the workflow run SSE (body\n * names a workflow `run_id`) or the durable lifecycle. Never runs a live run a\n * second time. A bare `resume_conflict` comes back as an outcome; any other\n * error is thrown.\n */\nexport async function resumeOrRejoin(\n transport: MatrxTransport,\n resumeCall: (\n transport: MatrxTransport,\n options: MatrxStreamCallOptions,\n ) => Promise<MatrxRunHandle>,\n options: ResumeOrRejoinOptions,\n): Promise<ResumeOrRejoinOutcome> {\n const {\n onEnvelope,\n organizationId,\n onRejoin,\n onOperationEvent,\n onWorkflowEvent,\n follow,\n ...rest\n } = options;\n const bound = organizationId\n ? withRunOrganization(transport, organizationId)\n : transport;\n const streamOptions: MatrxStreamCallOptions = {\n ...rest,\n ...(options.signal ? { signal: options.signal } : {}),\n };\n const signalOnly = options.signal ? { signal: options.signal } : {};\n\n let rejoin: MatrxLiveRunRejoin;\n try {\n const handle = await resumeCall(bound, streamOptions);\n await drain(handle, onEnvelope);\n return { kind: \"resumed\", requestId: handle.requestId };\n } catch (error) {\n const target = readLiveRunRejoin(error);\n if (!target) {\n if (error instanceof MatrxApiError && isResumeConflict(error)) {\n return { kind: \"resume_conflict\", error };\n }\n throw error;\n }\n rejoin = target;\n }\n\n onRejoin?.(rejoin);\n let unavailableBody: unknown;\n try {\n const handle = await openMatrxStream(bound, rejoin.rejoinPath, {\n ...streamOptions,\n // The rejoin routes take no body model; the reference client posts {}.\n body: {},\n });\n await drain(handle, onEnvelope);\n return { kind: \"rejoined\", rejoin };\n } catch (error) {\n if (!isLiveStreamUnavailable(error)) throw error;\n unavailableBody = bodyOf(error);\n }\n\n const runId =\n firstString(detailCandidates(unavailableBody), \"run_id\") ?? rejoin.runId;\n if (runId && rejoin.rejoinPath.startsWith(\"/runtime/operations/\")) {\n const result = await followWorkflowRunEvents(bound, runId, {\n ...signalOnly,\n onEvent: (event, seq) => onWorkflowEvent?.(event, seq),\n });\n return { kind: \"followed_workflow\", rejoin, runId, ended: result.ended };\n }\n\n const liveRequestId = rejoin.liveRequestId;\n const statusView = liveRequestId\n ? await getRuntimeOperationStatus(bound, liveRequestId, signalOnly)\n : null;\n const operation =\n statusView?.operations.find((op) => !op.is_terminal) ??\n statusView?.operations[0] ??\n null;\n if (!operation) {\n return { kind: \"followed\", rejoin, executionId: null, ended: false, status: null };\n }\n if (operation.is_terminal) {\n return {\n kind: \"followed\",\n rejoin,\n executionId: operation.execution_id,\n ended: true,\n status: operation.status,\n };\n }\n const result = await followRuntimeOperationToEnd(bound, operation.execution_id, {\n ...follow,\n lastEventSeq: operation.last_event_seq,\n ...signalOnly,\n onEvent: (event) => onOperationEvent?.(event),\n });\n return {\n kind: \"followed\",\n rejoin,\n executionId: operation.execution_id,\n ended: result.ended,\n status: result.status,\n };\n}\n","/**\n * Agent run lifecycle against the AI Matrx API — start, continue, resume,\n * cancel — over the `MatrxTransport` port, with every streaming response\n * parsed through the package's ONE NDJSON wire kernel (`stream/ndjson`).\n *\n * Server truth (verified against aidream source):\n * - `POST /ai/agents/{agent_id}` — start (`aidream/api/routers/agents.py`)\n * - `POST /ai/conversations/{conversation_id}` — continue (`aidream/api/routers/conversations.py`)\n * - `POST /ai/conversations/{conversation_id}/resume` — resume after\n * client-delegated tool suspension (same router)\n * - `POST /ai/cancel/{request_id}?mode=interrupt` — cancel (`aidream/api/routers/cancel.py`)\n *\n * Response headers arrive before the body: `X-Conversation-ID` and\n * `X-Request-ID` are surfaced on the run handle immediately. `X-Request-ID`\n * is the ONLY id the server accepts for cancel — a client-local id means\n * nothing to it.\n *\n * Host policy stays out: no retry, no store, no timeouts, no persistence\n * (C10: no-persistence). Cancellation is the caller's `AbortSignal`; a client\n * disconnect never stops server work (`detach_on_disconnect`).\n */\n\nimport type { MatrxStreamEnvelope } from \"../stream/ndjson\";\nimport type {\n MatrxConversationStart,\n MatrxJsonObject,\n MatrxJsonValue,\n} from \"./conversation\";\nimport {\n encodePathSegment,\n buildQuery,\n requestJson,\n requestStream,\n toRunHandle,\n type MatrxRunHandle,\n type MatrxStreamCallOptions,\n} from \"./internal\";\nimport type { MatrxTransport } from \"./transport\";\nimport { streamErrorText } from \"./rejoin\";\n\nexport type { MatrxRunHandle, MatrxStreamCallOptions } from \"./internal\";\n\n// ─── Request shapes (mirroring the server's Pydantic models) ────────────────\n\n/**\n * Stable identity of the durable entity whose saved context owns a run —\n * the server reloads the row and uses ITS scope (`ContextAnchor`,\n * `aidream/services/conversation_context/scope.py`).\n */\nexport interface MatrxContextAnchor {\n resource_type: string;\n resource_id: string;\n}\n\n/**\n * Scope and source fields shared by every scoped request\n * (`ScopedRequest` / `AcceptsInjectedScope` server-side). All optional here;\n * the start request narrows `organization_id` to required.\n */\nexport interface MatrxRequestScope {\n organization_id?: string;\n project_id?: string | null;\n task_id?: string | null;\n /** Active context-scope ids from the client's global picker (membership-validated server-side). */\n scope_ids?: string[] | null;\n /** Active scope-TYPE ids — a type-level selection with no specific scope chosen. */\n active_scope_type_ids?: string[] | null;\n context_anchor?: MatrxContextAnchor | null;\n /** Stable application slug that initiated the request. */\n source_app?: string | null;\n /** Stable feature slug within the source application. */\n source_feature?: string | null;\n /** \"user\" = a person directly triggered this; \"auto\" = client automation; omit for API callers. */\n initiation?: \"user\" | \"auto\" | null;\n /** Specific connected desktop instance allowed to claim delegated local tools. */\n target_instance_id?: string | null;\n}\n\n/**\n * Fields shared by start/continue turn requests (tool injection, client\n * capability envelope, context object). The complex bags (`tools`, `client`,\n * `user`, `config_overrides`) are typed as JSON objects — their authoritative\n * schemas are the server's Pydantic models and the generated API types;\n * this package stays payload-agnostic about them by design.\n */\nexport interface MatrxTurnFields {\n /** What the human typed (string), or structured input parts. Never smuggle machine content here. */\n user_input?: string | MatrxJsonValue[] | null;\n /** Per-run model/config overrides (LLMParams shape). */\n config_overrides?: MatrxJsonObject | null;\n debug?: boolean;\n /** Additive tool specs merged into the agent's resolved tool set. */\n tools?: MatrxJsonObject[];\n /** When set, becomes the agent's ENTIRE tool set for the turn. */\n tools_replace?: MatrxJsonObject[] | null;\n /** Client capability envelope (`ClientContext`). */\n client?: MatrxJsonObject | null;\n /** Per-request user-level tool inclusion/exclusion overrides. */\n user?: MatrxJsonObject | null;\n /** Per-route context object, free-form by design. */\n context?: MatrxJsonObject;\n writable_variables?: string[];\n allow_context_create?: boolean;\n /** Request-snapshot capture override (tri-state; omit for the platform default). */\n snapshot?: boolean | null;\n}\n\n/**\n * `POST /ai/agents/{agent_id}` body (`AgentStartRequest` server-side).\n * The conversation-start triple is required by construction; `organization_id`\n * is required (the server 422s a blank one — it never manufactures an org).\n * `stream` is not accepted here: this client is the streaming path and always\n * sends `stream: true`.\n */\nexport type MatrxAgentStartRequest = MatrxConversationStart &\n Omit<MatrxRequestScope, \"organization_id\"> &\n MatrxTurnFields & {\n organization_id: string;\n /** Variable name → value map filling the agent's declared variables. */\n variables?: MatrxJsonObject | null;\n /** Run the versions table row instead of the live agent row. */\n is_version?: boolean;\n max_iterations?: number;\n max_retries_per_iteration?: number;\n };\n\n/**\n * `POST /ai/mandates/{mandate_key}` uses the exact saved-agent start body.\n * The server resolves the mandate's holder, binding, and configuration; a\n * client must offer only the declared variables and human input here.\n */\nexport type MatrxMandateStartRequest = MatrxAgentStartRequest;\n\n/** `POST /ai/conversations/{id}` body (`ConversationContinueRequest` server-side). */\nexport type MatrxConversationContinueRequest = MatrxRequestScope &\n MatrxTurnFields & {\n /** Re-run the conversation's current persisted state (recovery after a failed turn); omit `user_input`. */\n retry?: boolean;\n };\n\n/**\n * `POST /ai/conversations/{id}/resume` body (`ResumeRequest` server-side) —\n * the shipped durable continuation after client-delegated tool calls were\n * answered via `POST /tool_results` while the original stream was gone.\n * `user_request_id` is optional: when omitted the server resolves the turn\n * from the conversation's newest answered client-delegated tool call.\n * Re-send fresh `context` here — a resumed loop is otherwise context-blind.\n */\nexport type MatrxConversationResumeRequest = MatrxRequestScope & {\n user_request_id?: string | null;\n config_overrides?: MatrxJsonObject | null;\n debug?: boolean;\n tools?: MatrxJsonObject[];\n tools_replace?: MatrxJsonObject[] | null;\n client?: MatrxJsonObject | null;\n user?: MatrxJsonObject | null;\n context?: MatrxJsonObject;\n writable_variables?: string[];\n allow_context_create?: boolean;\n};\n\n/** `POST /ai/cancel/{request_id}` response (`CancelResponse` server-side). */\nexport interface MatrxCancelResponse {\n status: string;\n request_id: string;\n spine_executions_signalled: string[];\n}\n\n// ─── The run handle ─────────────────────────────────────────────────────────\n// `MatrxStreamCallOptions`, `MatrxRunHandle`, and the handle constructor live\n// in ./internal so `./operations`' rejoin shares the exact same construction.\n\nasync function streamCall(\n transport: MatrxTransport,\n path: string,\n body: object,\n options: MatrxStreamCallOptions,\n): Promise<MatrxRunHandle> {\n const response = await requestStream(transport, path, {\n method: \"POST\",\n // This client IS the streaming path — `stream: true` always, last so a\n // caller-supplied value can never flip the response off NDJSON.\n body: { ...body, stream: true },\n ...(options.signal ? { signal: options.signal } : {}),\n });\n return toRunHandle(response, options);\n}\n\n// ─── Lifecycle calls ────────────────────────────────────────────────────────\n\n/** Start an agent run: `POST /ai/agents/{agent_id}` (NDJSON stream). */\nexport function startAgentRun(\n transport: MatrxTransport,\n agentId: string,\n request: MatrxAgentStartRequest,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/agents/${encodePathSegment(agentId)}`,\n request,\n options,\n );\n}\n\n/**\n * Start a declared mandate: `POST /ai/mandates/{mandate_key}` (NDJSON\n * stream). This is deliberately separate from `startAgentRun`: callers name\n * the mandate and never resolve or echo its holder/configuration themselves.\n */\nexport function startMandateRun(\n transport: MatrxTransport,\n mandateKey: string,\n request: MatrxMandateStartRequest,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/mandates/${encodePathSegment(mandateKey)}`,\n request,\n options,\n );\n}\n\n/** Continue a stored conversation: `POST /ai/conversations/{id}` (NDJSON stream). */\nexport function continueAgentConversation(\n transport: MatrxTransport,\n conversationId: string,\n request: MatrxConversationContinueRequest,\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}`,\n request,\n options,\n );\n}\n\n/**\n * Resume a suspended loop after delegated tool answers landed:\n * `POST /ai/conversations/{id}/resume` (NDJSON stream). A 409\n * (`resume_conflict`) means another resume holds the run claim — retrying is\n * host policy.\n */\nexport function resumeAgentConversation(\n transport: MatrxTransport,\n conversationId: string,\n request: MatrxConversationResumeRequest = {},\n options: MatrxStreamCallOptions = {},\n): Promise<MatrxRunHandle> {\n return streamCall(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}/resume`,\n request,\n options,\n );\n}\n\n/**\n * Stop a running request at its next iteration boundary:\n * `POST /ai/cancel/{request_id}`. Cooperative and best-effort — the in-flight\n * provider call finishes by design, and everything already streamed persists.\n * `mode: \"interrupt\"` = stop-and-fork: the tail after the last clean boundary\n * persists hidden so the user's follow-up replies to what they actually saw.\n * The id must be the server's `X-Request-ID`.\n */\nexport function cancelAgentRun(\n transport: MatrxTransport,\n requestId: string,\n options: { mode?: \"cancel\" | \"interrupt\"; signal?: AbortSignal } = {},\n): Promise<MatrxCancelResponse> {\n const query = buildQuery(\n options.mode === \"interrupt\" ? { mode: \"interrupt\" } : {},\n );\n return requestJson<MatrxCancelResponse>(\n transport,\n `/ai/cancel/${encodePathSegment(requestId)}${query}`,\n {\n method: \"POST\",\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n\n// ─── End-to-end convenience: run to completion ──────────────────────────────\n\n/**\n * A run that terminated unsuccessfully: the server emitted a fatal `error`\n * event, or the `user_request` completion settled `failed`/`cancelled`.\n */\nexport class MatrxRunError extends Error {\n override readonly name = \"MatrxRunError\";\n /** The verbatim `error` event payload, when one fired. */\n readonly errorPayload: Record<string, unknown> | null;\n /** The `user_request` completion status (`\"failed\"` | `\"cancelled\"`), when that was the trigger. */\n readonly completionStatus: string | null;\n /** Text streamed before the failure — partial content never vanishes. */\n readonly partialText: string;\n\n constructor(args: {\n message: string;\n errorPayload?: Record<string, unknown> | null;\n completionStatus?: string | null;\n partialText?: string;\n }) {\n super(args.message);\n this.errorPayload = args.errorPayload ?? null;\n this.completionStatus = args.completionStatus ?? null;\n this.partialText = args.partialText ?? \"\";\n }\n}\n\nexport interface MatrxCompletedRun {\n /** Accumulated `chunk` text (falls back to the completion's `result.output`). */\n text: string;\n requestId: string | null;\n conversationId: string | null;\n /** The `user_request` completion payload, verbatim, when one arrived. */\n completion: Record<string, unknown> | null;\n}\n\nexport interface RunAgentToCompletionOptions extends MatrxStreamCallOptions {\n /** Live progress: the full accumulated text after each chunk. */\n onChunk?: (fullText: string) => void;\n /** Every normalized envelope, before this helper interprets it. */\n onEvent?: (envelope: MatrxStreamEnvelope) => void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringField(value: unknown, key: string): string | null {\n if (!isRecord(value)) return null;\n const field = value[key];\n return typeof field === \"string\" && field ? field : null;\n}\n\n/**\n * Run an agent end-to-end and resolve with its full text output — the\n * package-level equivalent of the simplest existing host path\n * (`useRunAgent`): accumulate `chunk` text, treat a fatal `error` event or a\n * `failed`/`cancelled` `user_request` completion as a thrown `MatrxRunError`,\n * and fall back to the completion's `result.output` when no text streamed.\n *\n * The caller still owns the conversation-start triple on `request` — a\n * one-shot run typically uses `newEphemeralConversationStart()`.\n */\nexport async function runAgentToCompletion(\n transport: MatrxTransport,\n agentId: string,\n request: MatrxAgentStartRequest,\n options: RunAgentToCompletionOptions = {},\n): Promise<MatrxCompletedRun> {\n const handle = await startAgentRun(transport, agentId, request, options);\n\n let text = \"\";\n let completion: Record<string, unknown> | null = null;\n let failure: MatrxRunError | null = null;\n\n for await (const envelope of handle.events) {\n options.onEvent?.(envelope);\n\n if (envelope.event === \"chunk\") {\n const chunk = stringField(envelope.data, \"text\");\n if (chunk !== null) {\n text += chunk;\n options.onChunk?.(text);\n }\n continue;\n }\n\n if (envelope.event === \"error\" && failure === null) {\n const payload = isRecord(envelope.data) ? envelope.data : null;\n failure = new MatrxRunError({\n message: streamErrorText(payload) ?? \"The agent run failed\",\n errorPayload: payload,\n partialText: text,\n });\n continue;\n }\n\n if (envelope.event !== \"completion\" || !isRecord(envelope.data)) continue;\n // `init`/`completion` pairs exist for five operations; the terminal\n // outcome of the run is the `user_request` completion (STREAM-CONTRACT\n // §3.2 — always present, always last).\n if (envelope.data.operation !== \"user_request\") continue;\n\n completion = envelope.data;\n const status = envelope.data.status;\n if ((status === \"failed\" || status === \"cancelled\") && failure === null) {\n const result = isRecord(envelope.data.result) ? envelope.data.result : null;\n failure = new MatrxRunError({\n message:\n stringField(result, \"error\") ??\n stringField(result, \"user_message\") ??\n `The agent run ${status}`,\n completionStatus: status,\n partialText: text,\n });\n }\n }\n\n if (failure) throw failure;\n\n if (!text && completion) {\n const result = completion.result;\n const output = stringField(result, \"output\");\n if (output !== null) text = output;\n }\n\n return {\n text,\n requestId: handle.requestId,\n conversationId: handle.conversationId,\n completion,\n };\n}\n","/**\n * Browser-held provider sessions report their failures through the server.\n *\n * Realtime voice (OpenAI / xAI) and Cartesia TTS run browser → provider\n * directly on an ephemeral token from the token broker, so a provider refusal\n * (e.g. the platform's account is out of credit) never touches the server —\n * the operator would never hear of it, and the person would see raw provider\n * text. Every client calls `reportProviderSessionFailure` from the session's\n * error handler and shows the returned `user_message`.\n *\n * Server truth: `POST /broker/provider-failures`\n * (`aidream/api/routers/token_broker.py`; body `ProviderSessionFailureReport`\n * in `aidream/services/token_broker/models.py` — `extra=\"forbid\"`, allow-listed\n * providers, bounded text; identity and organization come from the session).\n */\n\nimport { requestJson } from \"./internal\";\nimport type { MatrxTransport } from \"./transport\";\n\n/** The providers whose sessions a browser holds directly (server allow-list). */\nexport type MatrxClientSessionProvider = \"openai\" | \"xai\" | \"cartesia\";\n\nexport interface ProviderSessionFailure {\n provider: MatrxClientSessionProvider;\n model?: string | null;\n /** HTTP status the provider answered, when the failure was an HTTP answer. */\n status_code?: number | null;\n /** The provider's own error type/code (`insufficient_quota`, …). */\n error_type?: string | null;\n /** The provider's text, verbatim — classified server-side, never shown. */\n message: string;\n}\n\n/** `ProviderSessionFailureVerdict` — what to show, and whether reconnecting can help. */\nexport interface ProviderSessionFailureVerdict {\n error_type: string;\n retryable: boolean;\n /** The sentence to show the person (never the provider's raw text). */\n user_message: string;\n}\n\nconst clip = (value: string, max: number): string =>\n value.length > max ? value.slice(0, max) : value;\n\n/** The body the server accepts — bounded exactly as its model bounds it. */\nexport function providerSessionFailureBody(\n failure: ProviderSessionFailure,\n): Record<string, string | number> {\n const message =\n failure.message?.trim() ||\n failure.error_type?.trim() ||\n (failure.status_code ? `HTTP ${failure.status_code}` : \"provider session failed\");\n const body: Record<string, string | number> = {\n provider: failure.provider,\n message: clip(message, 4000),\n };\n if (failure.model?.trim()) body.model = clip(failure.model.trim(), 200);\n if (failure.error_type?.trim()) body.error_type = clip(failure.error_type.trim(), 200);\n if (\n typeof failure.status_code === \"number\" &&\n Number.isInteger(failure.status_code) &&\n failure.status_code >= 100 &&\n failure.status_code <= 599\n ) {\n body.status_code = failure.status_code;\n }\n return body;\n}\n\n/**\n * Report a browser-held provider session failure and get the sentence to\n * show. Resolves null (and warns) when the report itself could not be made —\n * the caller then shows its own fallback; it never throws from an error\n * handler.\n */\nexport async function reportProviderSessionFailure(\n transport: MatrxTransport,\n failure: ProviderSessionFailure,\n options: { signal?: AbortSignal } = {},\n): Promise<ProviderSessionFailureVerdict | null> {\n try {\n return await requestJson<ProviderSessionFailureVerdict>(\n transport,\n \"/broker/provider-failures\",\n {\n method: \"POST\",\n body: providerSessionFailureBody(failure),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n } catch (error) {\n console.warn(\n `[provider-failures] could not report a ${failure.provider} session failure`,\n error,\n );\n return null;\n }\n}\n","/**\n * Delegated client tools — submit results and discover pending calls.\n *\n * Server truth (verified against aidream source,\n * `aidream/api/routers/conversations.py` + `aidream/services/ai_execution/\n * tool_results.py`):\n * - `POST /ai/conversations/{id}/tool_results` — durable, idempotent submit.\n * A delegated tool call HARD-SUSPENDS the loop; when the last outstanding\n * delegated row for the user_request resolves, the response carries\n * `continuation_needed: true` and the owning `user_request_id` — the signal\n * to open `resumeAgentConversation`. `continuation_needed` is best-effort:\n * parallel submits can both see `true`; `/resume` takes an atomic run claim\n * and the loser gets a 409.\n * - `GET /ai/conversations/{id}/pending_calls` — delegated calls awaiting the\n * user in one conversation (rows survive disconnects and reloads).\n * - `GET /ai/user/pending_calls` — every pending call for this user; an\n * optional `instance_id` atomically claims them for a desktop instance.\n *\n * A 404 from the submit means EVERY call_id was unknown (duplicate/expired);\n * partial success returns 200 with `not_found` populated. Batching, retries,\n * and the resume handoff are host policy — this module is the wire.\n */\n\nimport type { MatrxJsonObject, MatrxJsonValue } from \"./conversation\";\nimport { encodePathSegment, buildQuery, requestJson } from \"./internal\";\nimport type { MatrxTransport } from \"./transport\";\n\n/** One client tool answer (`ClientToolResult` server-side). */\nexport interface MatrxClientToolResult {\n call_id: string;\n tool_name: string;\n /** Tool output — inherently polymorphic; recursive JSON by design. */\n output?: MatrxJsonValue | null;\n is_error?: boolean;\n error_message?: string | null;\n /** Client-measured execution time in ms. */\n duration_ms?: number | null;\n}\n\n/** `POST /tool_results` response (`ToolResultsResponse` server-side). */\nexport interface MatrxToolResultsResponse {\n resolved: string[];\n already_resolved: string[];\n not_found: string[];\n /** True when the original stream is gone and no delegated calls remain — open `/resume`. */\n continuation_needed: boolean;\n user_request_id: string | null;\n conversation_id: string;\n}\n\n/** One delegated call awaiting an answer (`PendingCallSummary` server-side). */\nexport interface MatrxPendingCallSummary {\n id: string;\n call_id: string;\n conversation_id: string;\n user_request_id: string | null;\n message_id: string | null;\n tool_name: string;\n /** Tool-call argument bag — schema is per-tool (its input_schema). */\n arguments: MatrxJsonObject;\n iteration: number;\n created_at: string | null;\n expires_at: string | null;\n target_instance_id: string | null;\n claimed_by_instance_id: string | null;\n claim_expires_at: string | null;\n execution_authorization: MatrxJsonObject | null;\n}\n\n/**\n * Submit client tool results: `POST /ai/conversations/{id}/tool_results`.\n * Idempotent — duplicate submits return 200 with the ids in\n * `already_resolved`. Throws `MatrxApiError` (status 404) when every call_id\n * was unknown or expired; the stream stays alive in that case.\n */\nexport function submitAgentToolResults(\n transport: MatrxTransport,\n conversationId: string,\n results: MatrxClientToolResult[],\n options: { instanceId?: string; signal?: AbortSignal } = {},\n): Promise<MatrxToolResultsResponse> {\n return requestJson<MatrxToolResultsResponse>(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}/tool_results`,\n {\n method: \"POST\",\n body: {\n results,\n ...(options.instanceId !== undefined\n ? { instance_id: options.instanceId }\n : {}),\n },\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n\n/**\n * Discover delegated calls awaiting the user in one conversation:\n * `GET /ai/conversations/{id}/pending_calls`. Safe to call on every\n * conversation load; a non-empty list should be surfaced exactly as if the\n * original stream had delivered the `tool_delegated` events live.\n */\nexport function listConversationPendingToolCalls(\n transport: MatrxTransport,\n conversationId: string,\n options: { signal?: AbortSignal } = {},\n): Promise<MatrxPendingCallSummary[]> {\n return requestJson<MatrxPendingCallSummary[]>(\n transport,\n `/ai/conversations/${encodePathSegment(conversationId)}/pending_calls`,\n {\n method: \"GET\",\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n\n/**\n * Discover every delegated call awaiting this user across all conversations:\n * `GET /ai/user/pending_calls`. Passing `instanceId` atomically CLAIMS the\n * calls for that desktop instance — only pass it from a client that will\n * actually execute them.\n */\nexport function listUserPendingToolCalls(\n transport: MatrxTransport,\n options: { instanceId?: string; signal?: AbortSignal } = {},\n): Promise<MatrxPendingCallSummary[]> {\n const query = buildQuery(\n options.instanceId !== undefined ? { instance_id: options.instanceId } : {},\n );\n return requestJson<MatrxPendingCallSummary[]>(\n transport,\n `/ai/user/pending_calls${query}`,\n {\n method: \"GET\",\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n}\n","/**\n * Media reference roles — the builder's side of the one vocabulary.\n *\n * Image generation reads an image as subject / character / style / mask /\n * edit target / composition. Video generation reads an image as first frame /\n * last frame / asset / style, a video as extend / restyle, and an audio clip as\n * lip sync; an asset/style image or a reference video may carry a `name` the\n * prompt addresses as `@name` (server: `matrx_ai/media/video_reference_roles.py`).\n *\n * A reference image in an image-generation request says what it controls.\n * The role rides on the image block itself (`role` on the image part); absent\n * = a plain image the model sees. The server owns the wire mapping and the\n * refusal gate (aidream `matrx_ai/media/image_reference_roles.py`); this module\n * mirrors its vocabulary and limits so the builder can tell the truth BEFORE a\n * run: a role the selected model cannot take is shown greyed with the reason.\n *\n * Limits come from the catalog: the routing offering's\n * `capabilities_override.image_reference_roles` (`{role: max, total: n}`).\n * Law: `common-docs/systems/agents/typed-messages/FEATURE.md` (Image generation).\n * Home: `@ai-matrx/agents` (moved from matrx-frontend `features/agents/image-roles/roles.ts`).\n */\n\n/** The roles an IMAGE-generating model reads an image as (vocabulary order). */\nexport const IMAGE_REFERENCE_ROLES = [\n \"subject\",\n \"character\",\n \"style\",\n \"mask\",\n \"edit_target\",\n \"composition_control\",\n] as const;\n\n/** The roles a VIDEO-generating model reads an image as (`style` is shared). */\nexport const VIDEO_IMAGE_ROLES = [\n \"first_frame\",\n \"last_frame\",\n \"asset\",\n \"style\",\n] as const;\n\n/** Roles on a video part beside a video prompt. */\nexport const VIDEO_REFERENCE_ROLES = [\"extend\", \"restyle\"] as const;\n\n/** Roles on an audio part beside a video prompt. */\nexport const AUDIO_REFERENCE_ROLES = [\"lip_sync\"] as const;\n\nexport type ImageReferenceRole =\n | (typeof IMAGE_REFERENCE_ROLES)[number]\n | (typeof VIDEO_IMAGE_ROLES)[number];\nexport type VideoReferenceRole = (typeof VIDEO_REFERENCE_ROLES)[number];\nexport type AudioReferenceRole = (typeof AUDIO_REFERENCE_ROLES)[number];\n/** Any role a media part can carry — one union, one metadata table. */\nexport type ReferenceRole =\n | ImageReferenceRole\n | VideoReferenceRole\n | AudioReferenceRole;\n\nconst ALL_IMAGE_ROLES: readonly string[] = [\n ...IMAGE_REFERENCE_ROLES,\n ...VIDEO_IMAGE_ROLES,\n];\n\nexport interface ImageRoleMeta {\n /** Segment label — plain words, never the wire token. */\n label: string;\n /** What the run form asks for when a variable fills this role. */\n ask: string;\n /** One line: what the model does with an image in this role. */\n explanation: string;\n}\n\nexport const IMAGE_ROLE_META: Record<ReferenceRole, ImageRoleMeta> = {\n subject: {\n label: \"Subject\",\n ask: \"Subject reference\",\n explanation:\n \"Keeps this exact product or object recognisable: shape, materials, labels.\",\n },\n character: {\n label: \"Character\",\n ask: \"Character reference\",\n explanation: \"Keeps this person or character looking the same.\",\n },\n style: {\n label: \"Style\",\n ask: \"Style reference\",\n explanation:\n \"Borrows only the look (colours, lighting, medium), never the content.\",\n },\n mask: {\n label: \"Mask\",\n ask: \"Mask\",\n explanation:\n \"Marks the only area of the edited image that is allowed to change.\",\n },\n edit_target: {\n label: \"Edit this\",\n ask: \"Image to edit\",\n explanation: \"The image being edited; everything not asked for stays the same.\",\n },\n composition_control: {\n label: \"Composition\",\n ask: \"Composition reference\",\n explanation: \"Follows its layout, pose and geometry, not its appearance.\",\n },\n first_frame: {\n label: \"First frame\",\n ask: \"First frame\",\n explanation: \"The video starts on exactly this image.\",\n },\n last_frame: {\n label: \"Last frame\",\n ask: \"Last frame\",\n explanation: \"The video ends on exactly this image (needs a first frame).\",\n },\n asset: {\n label: \"Asset\",\n ask: \"Asset reference\",\n explanation:\n \"Keeps this product, object or character recognisable throughout the clip.\",\n },\n extend: {\n label: \"Extend\",\n ask: \"Video to extend\",\n explanation: \"The new clip continues this video from its last frame.\",\n },\n restyle: {\n label: \"Restyle\",\n ask: \"Reference video\",\n explanation: \"Re-renders this video: same motion and timing, a new look.\",\n },\n lip_sync: {\n label: \"Lip sync\",\n ask: \"Lip-sync audio\",\n explanation: \"The speech the on-screen face mouths, word for word.\",\n },\n};\n\n/** Which roles a block of this kind offers for this output modality. */\nexport function rolesFor(\n blockKind: \"image\" | \"video\" | \"audio\",\n output: \"image\" | \"video\",\n): readonly ReferenceRole[] {\n if (output === \"image\") return blockKind === \"image\" ? IMAGE_REFERENCE_ROLES : [];\n if (blockKind === \"image\") return VIDEO_IMAGE_ROLES;\n if (blockKind === \"video\") return VIDEO_REFERENCE_ROLES;\n return AUDIO_REFERENCE_ROLES;\n}\n\n/** Roles whose reference may carry a name the prompt addresses as `@name`. */\nexport function roleTakesName(role: ReferenceRole | null | undefined): boolean {\n return role === \"asset\" || role === \"style\" || role === \"restyle\" || role === \"extend\";\n}\n\n/** `@name` rule shared with the server (media/video_reference_roles.py). */\nexport function normalizeReferenceName(raw: string): string | null {\n const candidate = raw.trim().replace(/^@/, \"\");\n if (!candidate) return null;\n return /^[A-Za-z][A-Za-z0-9_-]{0,31}$/.test(candidate) ? candidate : null;\n}\n\nexport function isReferenceRole(value: unknown): value is ReferenceRole {\n return typeof value === \"string\" && value in IMAGE_ROLE_META;\n}\n\nexport function isImageReferenceRole(value: unknown): value is ImageReferenceRole {\n return typeof value === \"string\" && ALL_IMAGE_ROLES.includes(value);\n}\n\n/**\n * `{role: max, total: n, named: n}` — image roles from\n * `capabilities_override.image_reference_roles`, video/audio roles and the\n * named-reference cap from `capabilities_override.video_reference_roles`.\n * Empty = the model takes no roled reference.\n */\nexport type ImageRoleLimits = Partial<Record<ReferenceRole | \"total\" | \"named\", number>>;\n\nfunction readLimitMap(\n source: unknown,\n accept: (key: string) => boolean,\n out: ImageRoleLimits,\n): void {\n if (typeof source !== \"object\" || source === null || Array.isArray(source)) return;\n for (const [key, value] of Object.entries(source)) {\n if (\n accept(key) &&\n typeof value === \"number\" &&\n Number.isInteger(value) &&\n value >= 0\n ) {\n out[key as keyof ImageRoleLimits] = value;\n }\n }\n}\n\n/** Read the offering's role limits (image + video maps) defensively. */\nexport function readImageRoleLimits(raw: unknown): ImageRoleLimits {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return {};\n const record = raw as Record<string, unknown>;\n const out: ImageRoleLimits = {};\n readLimitMap(\n record.image_reference_roles,\n (k) => isImageReferenceRole(k) || k === \"total\",\n out,\n );\n readLimitMap(\n record.video_reference_roles,\n (k) =>\n (VIDEO_REFERENCE_ROLES as readonly string[]).includes(k) ||\n (AUDIO_REFERENCE_ROLES as readonly string[]).includes(k) ||\n k === \"named\",\n out,\n );\n return out;\n}\n\nexport type ImageRoleVerdict =\n | { verdict: \"ok\" }\n | { verdict: \"refused\"; reason: string };\n\n/**\n * Can this model take an image in this role? The reason is a sentence a\n * person can act on; it names the role and the model, like the server's\n * refusal does.\n */\nexport function imageRoleVerdict(\n role: ReferenceRole,\n limits: ImageRoleLimits,\n modelLabel: string,\n countOfRole = 1,\n): ImageRoleVerdict {\n const label = IMAGE_ROLE_META[role].label;\n const noun = (VIDEO_REFERENCE_ROLES as readonly string[]).includes(role)\n ? \"video\"\n : role === \"lip_sync\"\n ? \"audio clip\"\n : ALL_IMAGE_ROLES.includes(role) &&\n !(IMAGE_REFERENCE_ROLES as readonly string[]).includes(role)\n ? \"image\"\n : \"reference image\";\n const allowed = limits[role] ?? 0;\n if (allowed <= 0) {\n return {\n verdict: \"refused\",\n reason: `${modelLabel} cannot take a ${label} ${noun}. Pick another role or another model.`,\n };\n }\n if (countOfRole > allowed) {\n return {\n verdict: \"refused\",\n reason: `${modelLabel} takes at most ${allowed} ${label} ${noun}${allowed === 1 ? \"\" : \"s\"}; this message has ${countOfRole}.`,\n };\n }\n return { verdict: \"ok\" };\n}\n\n/** Can this model take a named (`@name`) reference at all? */\nexport function namedReferenceVerdict(\n limits: ImageRoleLimits,\n modelLabel: string,\n): ImageRoleVerdict {\n return (limits.named ?? 0) > 0\n ? { verdict: \"ok\" }\n : {\n verdict: \"refused\",\n reason: `${modelLabel} cannot take named references. Clear the name, or pick a model with named elements.`,\n };\n}\n\n/** The variable an image block is filled by, when its url is exactly `{{name}}`. */\nexport function variableNameOfImageUrl(url: unknown): string | null {\n return variableNameOfMediaUrl(url);\n}\n\n/** The variable any media block (image, video, audio) is filled by. */\nexport function variableNameOfMediaUrl(url: unknown): string | null {\n if (typeof url !== \"string\") return null;\n const match = /^\\s*\\{\\{\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}\\s*$/.exec(url);\n return match?.[1] ?? null;\n}\n\n/**\n * The one-line caption a REDISPLAYED reference shows — \"Subject reference\",\n * \"Style reference · @brand\". Shared by the attachment chip and the inline\n * image/video block so a role set in the builder is never lost on reload. An\n * unrecognised role string is shown as-is (honest) rather than dropped.\n */\nexport function referenceRoleCaption(role: unknown, name: unknown): string | null {\n const roleLabel =\n typeof role === \"string\" && role\n ? isReferenceRole(role)\n ? IMAGE_ROLE_META[role].ask\n : role\n : null;\n const refName = typeof name === \"string\" ? normalizeReferenceName(name) : null;\n if (!roleLabel && !refName) return null;\n return [roleLabel, refName ? `@${refName}` : null].filter(Boolean).join(\" · \");\n}\n","/**\n * Run inputs — the ONE derivation from an agent's variable definitions to the\n * inputs a run surface asks for.\n *\n * Every surface that runs an agent (the run page and chat composer, Agent\n * Battle's shared request, a Workflow Studio Step node) asks the same\n * questions in the same order: content inputs first, then bound model\n * controls in a \"Settings\" group; a media variable that fills a reference role\n * is asked for BY that role (\"Style reference\"); a control keeps the catalog\n * component the builder stamped on it. A speech-script variable is an ordinary\n * content variable — its `{{name}}` lives in a turn's text.\n *\n * Canonical doc: common-docs/systems/agents/typed-messages/FEATURE.md.\n */\n\nimport {\n IMAGE_ROLE_META,\n isReferenceRole,\n type ReferenceRole,\n} from \"./reference-roles\";\n\n/** The minimum variable shape this derivation reads (a superset is fine). */\nexport interface RunInputVariable {\n name: string;\n defaultValue?: unknown;\n helpText?: string | null;\n required?: boolean | null;\n customComponent?: {\n type?: string | null;\n options?: readonly string[] | null;\n imageRole?: unknown;\n min?: number | null;\n max?: number | null;\n step?: number | null;\n toggleValues?: readonly [string, string] | readonly string[] | null;\n } | null;\n control?: { key?: string | null } | null;\n}\n\nexport type RunInputGroup = \"content\" | \"settings\";\n\nexport type RunInputMediaKind = \"image\" | \"video\" | \"audio\" | \"document\" | \"youtube\";\n\nconst MEDIA_KINDS: readonly string[] = [\"image\", \"video\", \"audio\", \"document\", \"youtube\"];\n\nexport interface RunInput<V extends RunInputVariable = RunInputVariable> {\n name: string;\n /** What the form asks: the role's ask for a roled media input, else the formatted name. */\n label: string;\n /** The variable's help text, else the role's one-line explanation. */\n hint: string | undefined;\n group: RunInputGroup;\n required: boolean;\n /** The component type the builder chose (`textarea` when none). */\n component: string;\n options: readonly string[] | undefined;\n /** Set when this input takes a file / media reference. */\n mediaKind: RunInputMediaKind | null;\n /** The reference role a media input fills (subject, style, first_frame, …). */\n role: ReferenceRole | null;\n /** The model control this input IS (aspect_ratio, quality, voice, …). */\n controlKey: string | null;\n variable: V;\n}\n\nexport function isControlVariable(def: RunInputVariable): boolean {\n return typeof def.control?.key === \"string\" && def.control.key.length > 0;\n}\n\n/** Content inputs first, bound controls after — stable within each group. */\nexport function partitionControlVariables<T extends RunInputVariable>(\n defs: readonly T[],\n): { content: T[]; settings: T[] } {\n const content: T[] = [];\n const settings: T[] = [];\n for (const d of defs) (isControlVariable(d) ? settings : content).push(d);\n return { content, settings };\n}\n\n/** The order every variable form renders in. Returns the same array when already ordered. */\nexport function orderVariablesForForm<T extends RunInputVariable>(defs: T[]): T[] {\n const { content, settings } = partitionControlVariables(defs);\n if (settings.length === 0) return defs;\n const ordered = [...content, ...settings];\n return ordered.every((d, i) => d === defs[i]) ? defs : ordered;\n}\n\nfunction roleOf(variable: RunInputVariable): ReferenceRole | null {\n const type = variable.customComponent?.type;\n const role = variable.customComponent?.imageRole;\n const roled = type === \"image\" || type === \"video\" || type === \"audio\";\n return roled && isReferenceRole(role) ? role : null;\n}\n\n/**\n * The label a run form shows for a variable: a media variable that fills a\n * reference role is asked for BY that role (\"Style reference\"); every other\n * variable keeps its formatted name.\n */\nexport function variableRunLabel(\n variable: RunInputVariable,\n formatName: (name: string) => string,\n): string {\n const role = roleOf(variable);\n return role ? IMAGE_ROLE_META[role].ask : formatName(variable.name);\n}\n\n/** The hint under / beside a variable: its own help text, else the role's line. */\nexport function variableRunHint(variable: RunInputVariable): string | undefined {\n if (variable.helpText) return variable.helpText;\n const role = roleOf(variable);\n return role ? IMAGE_ROLE_META[role].explanation : undefined;\n}\n\n/** Derive the ordered, grouped, labelled run inputs for an agent's variables. */\nexport function deriveRunInputs<V extends RunInputVariable>(\n defs: readonly V[] | null | undefined,\n formatName: (name: string) => string,\n): RunInput<V>[] {\n return orderVariablesForForm([...(defs ?? [])]).map((variable) => {\n const type = variable.customComponent?.type ?? \"textarea\";\n const options = variable.customComponent?.options ?? undefined;\n return {\n name: variable.name,\n label: variableRunLabel(variable, formatName),\n hint: variableRunHint(variable),\n group: isControlVariable(variable) ? \"settings\" : \"content\",\n required: Boolean(variable.required),\n component: type,\n options: options && options.length > 0 ? options : undefined,\n mediaKind: MEDIA_KINDS.includes(type) ? (type as RunInputMediaKind) : null,\n role: roleOf(variable),\n controlKey: isControlVariable(variable) ? (variable.control?.key ?? null) : null,\n variable,\n };\n });\n}\n"],"mappings":"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","names":["isRecord","changed","output","asRecord","asString","asNumber","isRecord","import_data","status","isRecord","result","isRecord"]}