@dudousxd/nestjs-agent-react 0.29.2 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -621,6 +621,40 @@ const readCookie = (name: string) =>
621
621
  </AgentProvider>;
622
622
  ```
623
623
 
624
+
625
+ ### An AG-UI agent (`agUiChatStream`)
626
+
627
+ `useAgentChat` can drive any [AG-UI 1.0](https://docs.ag-ui.com/spec/1.0) producer — this library's
628
+ own (`@adonis-agora/agent/ag-ui`), CopilotKit's, a Python or .NET agent. Put `agUiChatStream` behind
629
+ `openChatStream`: it POSTs a `RunAgentInput` (the send's text as the user message, `pageContext`,
630
+ `agent` and `model` in `forwardedProps`) and hands the transport the answer re-framed in this
631
+ library's stream protocol, so the transcript, tool activity and generative UI render unchanged.
632
+
633
+ ```ts
634
+ import { agUiChatStream, type AgentBackend } from '@dudousxd/nestjs-agent-react';
635
+
636
+ const backend: AgentBackend = {
637
+ ...myBackend,
638
+ openChatStream: (request) =>
639
+ agUiChatStream(request, { url: '/agent/ag-ui', headers: { 'x-csrf-token': csrf } }),
640
+ };
641
+ ```
642
+
643
+ - Text, reasoning, steps, tool calls and tool results map one to one; `RUN_ERROR` is the stream's
644
+ error, a cancelled outcome writes `cancelled`.
645
+ - `CUSTOM` events named `agora.*` (generative UI, title, queue, approvals) become the frames they
646
+ stand for; any other `CUSTOM` is ignored, as the protocol requires.
647
+ - An interrupt outcome arrives as a `ui` part, component `AgUiInterrupt`, props `{ interrupts }`:
648
+ answering it is a new run with `resume`, which the app sends through its own backend.
649
+ - A send without a `threadId` gets a new one (AG-UI's thread id is the consumer's), returned as
650
+ the stream's `threadId`, so `onThreadCreated` fires as usual.
651
+ - Activity (`ACTIVITY_SNAPSHOT` / `ACTIVITY_DELTA`) arrives as a `ui` part, component `AgUiActivity`,
652
+ id `activity:<messageId>`, props `{ activityType, content }`: the whole content each time (the
653
+ delta's JSON Patch applied), so the widget updates in place.
654
+ - `content: (body) => parts` sends a file with the message as AG-UI content parts (`image`,
655
+ `document`… by inline `data`), next to the text part.
656
+ - `reframeAgUiStream(body, { threadId })` is the re-framing alone, for a backend that fetches itself.
657
+
624
658
  ### Typing ahead: the message queue
625
659
 
626
660
  Send while a turn is still answering and the message waits in the thread's queue — server-side, so
@@ -436,4 +436,4 @@ declare class AgentClient implements AgentBackend {
436
436
  private handleResponse;
437
437
  }
438
438
 
439
- export { type AgentRequestError as A, type CancelResult as C, type ErrorAnswer as E, type HttpErrorListener as H, type MessageFeedbackInput as M, type QueuedMessageUpdate as Q, type ResumeStreamRequest as R, type ThreadPatch as T, type UploadAttachmentOptions as U, type AgentBackend as a, type AttachmentUploadStrategy as b, AgentBackendUnsupportedError as c, AgentClient as d, type AgentClientOptions as e, type AgentConnection as f, AgentHttpError as g, type ChatStreamRequest as h, type ChatStreamResponse as i, type QueuedSendResult as j, requireBackendMethod as r };
439
+ export { type AgentRequestError as A, type ChatStreamRequest as C, type ErrorAnswer as E, type HttpErrorListener as H, type MessageFeedbackInput as M, type QueuedMessageUpdate as Q, type ResumeStreamRequest as R, type ThreadPatch as T, type UploadAttachmentOptions as U, type AgentBackend as a, type ChatStreamResponse as b, type AttachmentUploadStrategy as c, AgentBackendUnsupportedError as d, AgentClient as e, type AgentClientOptions as f, type AgentConnection as g, AgentHttpError as h, type CancelResult as i, type QueuedSendResult as j, requireBackendMethod as r };
@@ -436,4 +436,4 @@ declare class AgentClient implements AgentBackend {
436
436
  private handleResponse;
437
437
  }
438
438
 
439
- export { type AgentRequestError as A, type CancelResult as C, type ErrorAnswer as E, type HttpErrorListener as H, type MessageFeedbackInput as M, type QueuedMessageUpdate as Q, type ResumeStreamRequest as R, type ThreadPatch as T, type UploadAttachmentOptions as U, type AgentBackend as a, type AttachmentUploadStrategy as b, AgentBackendUnsupportedError as c, AgentClient as d, type AgentClientOptions as e, type AgentConnection as f, AgentHttpError as g, type ChatStreamRequest as h, type ChatStreamResponse as i, type QueuedSendResult as j, requireBackendMethod as r };
439
+ export { type AgentRequestError as A, type ChatStreamRequest as C, type ErrorAnswer as E, type HttpErrorListener as H, type MessageFeedbackInput as M, type QueuedMessageUpdate as Q, type ResumeStreamRequest as R, type ThreadPatch as T, type UploadAttachmentOptions as U, type AgentBackend as a, type ChatStreamResponse as b, type AttachmentUploadStrategy as c, AgentBackendUnsupportedError as d, AgentClient as e, type AgentClientOptions as f, type AgentConnection as g, AgentHttpError as h, type CancelResult as i, type QueuedSendResult as j, requireBackendMethod as r };
package/dist/index.cjs CHANGED
@@ -47,6 +47,7 @@ __export(src_exports, {
47
47
  RUN_NOT_ACTIVE_CODE: () => RUN_NOT_ACTIVE_CODE,
48
48
  SPEECH_LANGUAGES: () => SPEECH_LANGUAGES,
49
49
  acceptsFile: () => acceptsFile,
50
+ agUiChatStream: () => agUiChatStream,
50
51
  applyCompletion: () => applyCompletion,
51
52
  approvalCountdown: () => approvalCountdown,
52
53
  attachmentFile: () => attachmentFile,
@@ -79,6 +80,7 @@ __export(src_exports, {
79
80
  phraseFor: () => phraseFor,
80
81
  readPath: () => readPath,
81
82
  readReasoningMs: () => readReasoningMs,
83
+ reframeAgUiStream: () => reframeAgUiStream,
82
84
  requireBackendMethod: () => requireBackendMethod,
83
85
  resolveResultView: () => resolveResultView,
84
86
  storedMessageToUiMessage: () => storedMessageToUiMessage,
@@ -1925,6 +1927,339 @@ function useAttachments(options = {}) {
1925
1927
  }, [items, add, remove, retry, clear, inputProps, dropZoneProps, dragDepth, onPaste]);
1926
1928
  }
1927
1929
 
1930
+ // src/ag-ui-backend.ts
1931
+ function newId() {
1932
+ return globalThis.crypto.randomUUID();
1933
+ }
1934
+ function isRecord2(value) {
1935
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1936
+ }
1937
+ async function defaultRefusal(response) {
1938
+ try {
1939
+ const body = await response.json();
1940
+ if (typeof body.message === "string" && body.message.length > 0) return new Error(body.message);
1941
+ } catch {
1942
+ }
1943
+ return new Error(`The agent refused the request (${response.status}).`);
1944
+ }
1945
+ function defaultForwardedProps(body) {
1946
+ const out = {};
1947
+ for (const key of ["pageContext", "agent", "model"]) {
1948
+ if (body[key] !== void 0 && body[key] !== null) out[key] = body[key];
1949
+ }
1950
+ return Object.keys(out).length > 0 ? out : void 0;
1951
+ }
1952
+ async function agUiChatStream(request, options) {
1953
+ const body = request.body;
1954
+ const threadId = typeof body.threadId === "string" ? body.threadId : newId();
1955
+ const message = typeof body.message === "string" ? body.message : "";
1956
+ const forwarded = (options.forwardedProps ?? defaultForwardedProps)(body);
1957
+ const input = {
1958
+ threadId,
1959
+ runId: newId(),
1960
+ protocolVersion: "1.0",
1961
+ messages: [{ id: newId(), role: "user", content: options.content?.(body) ?? message }],
1962
+ ...forwarded !== void 0 ? { forwardedProps: forwarded } : {}
1963
+ };
1964
+ const doFetch = options.fetch ?? globalThis.fetch.bind(globalThis);
1965
+ const response = await doFetch(options.url, {
1966
+ method: "POST",
1967
+ credentials: "same-origin",
1968
+ headers: {
1969
+ "content-type": "application/json",
1970
+ accept: "text/event-stream",
1971
+ ...options.headers,
1972
+ ...request.headers
1973
+ },
1974
+ body: JSON.stringify(input),
1975
+ ...request.signal !== void 0 ? { signal: request.signal } : {}
1976
+ });
1977
+ if (!response.ok || response.body === null) {
1978
+ throw await (options.refusal ?? defaultRefusal)(response);
1979
+ }
1980
+ const runId = response.headers.get("x-agent-run-id") ?? void 0;
1981
+ return {
1982
+ body: reframeAgUiStream(response.body, { threadId }),
1983
+ threadId,
1984
+ ...runId !== void 0 ? { runId } : {}
1985
+ };
1986
+ }
1987
+ function reframeAgUiStream(source, ids) {
1988
+ const encoder = new TextEncoder();
1989
+ const decoder = new TextDecoder();
1990
+ const reframer = createReframer(ids.threadId);
1991
+ const reader = source.getReader();
1992
+ let buffer = "";
1993
+ return new ReadableStream({
1994
+ async pull(controller) {
1995
+ for (; ; ) {
1996
+ const { value, done } = await reader.read();
1997
+ if (done) {
1998
+ controller.close();
1999
+ return;
2000
+ }
2001
+ buffer += decoder.decode(value, { stream: true }).replace(/\r\n?/g, "\n");
2002
+ let out = "";
2003
+ let separator = buffer.indexOf("\n\n");
2004
+ while (separator !== -1) {
2005
+ const block = buffer.slice(0, separator);
2006
+ buffer = buffer.slice(separator + 2);
2007
+ separator = buffer.indexOf("\n\n");
2008
+ const data = block.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
2009
+ if (data.length === 0) continue;
2010
+ let event;
2011
+ try {
2012
+ event = JSON.parse(data);
2013
+ } catch {
2014
+ continue;
2015
+ }
2016
+ if (isRecord2(event) && typeof event.type === "string") {
2017
+ out += reframer.push(event);
2018
+ }
2019
+ if (reframer.closed) break;
2020
+ }
2021
+ if (out.length > 0) controller.enqueue(encoder.encode(out));
2022
+ if (reframer.closed) {
2023
+ void reader.cancel().catch(() => void 0);
2024
+ controller.close();
2025
+ return;
2026
+ }
2027
+ if (out.length > 0) return;
2028
+ }
2029
+ },
2030
+ cancel(reason) {
2031
+ return reader.cancel(reason).catch(() => void 0);
2032
+ }
2033
+ });
2034
+ }
2035
+ function createReframer(threadId) {
2036
+ const activities = /* @__PURE__ */ new Map();
2037
+ let seq = 0;
2038
+ let metaSent = false;
2039
+ const tools = /* @__PURE__ */ new Map();
2040
+ const state = {
2041
+ closed: false,
2042
+ push(event) {
2043
+ if (state.closed) return "";
2044
+ let out = "";
2045
+ const frame = (streamEvent) => {
2046
+ seq += 1;
2047
+ out += `id: ${seq}
2048
+ data: ${JSON.stringify(streamEvent)}
2049
+
2050
+ `;
2051
+ };
2052
+ const meta = (runId, thread) => {
2053
+ if (metaSent) return;
2054
+ metaSent = true;
2055
+ out += `event: meta
2056
+ data: ${JSON.stringify({
2057
+ runId: typeof runId === "string" ? runId : "",
2058
+ threadId: typeof thread === "string" ? thread : threadId
2059
+ })}
2060
+
2061
+ `;
2062
+ };
2063
+ switch (event.type) {
2064
+ case "RUN_STARTED":
2065
+ pendingStart = { runId: event.runId, threadId: event.threadId };
2066
+ return out;
2067
+ case "CUSTOM": {
2068
+ const value = event.value;
2069
+ if (event.name === "agora.run" && isRecord2(value)) {
2070
+ meta(value.runId, pendingStart?.threadId ?? value.threadId);
2071
+ pendingStart = void 0;
2072
+ return out;
2073
+ }
2074
+ flushStart();
2075
+ if (!isRecord2(value)) return out;
2076
+ if (event.name === "agora.ui") frame({ kind: "ui", ...value });
2077
+ else if (event.name === "agora.title" && typeof value.title === "string") {
2078
+ frame({ kind: "title", title: value.title });
2079
+ } else if (event.name === "agora.queue") frame({ kind: "queue", ...value });
2080
+ else if (event.name === "agora.approval-requested") {
2081
+ frame({ ...value, kind: "approval-requested" });
2082
+ } else if (event.name === "agora.approval-settled") {
2083
+ frame({ ...value, kind: "approval-settled" });
2084
+ }
2085
+ return out;
2086
+ }
2087
+ default:
2088
+ flushStart();
2089
+ }
2090
+ switch (event.type) {
2091
+ case "TEXT_MESSAGE_CONTENT":
2092
+ case "TEXT_MESSAGE_CHUNK":
2093
+ if (typeof event.delta === "string" && event.delta.length > 0) {
2094
+ frame({ kind: "text", text: event.delta });
2095
+ }
2096
+ break;
2097
+ case "REASONING_MESSAGE_CONTENT":
2098
+ case "REASONING_MESSAGE_CHUNK":
2099
+ if (typeof event.delta === "string" && event.delta.length > 0) {
2100
+ frame({ kind: "reasoning", text: event.delta });
2101
+ }
2102
+ break;
2103
+ case "STEP_STARTED":
2104
+ frame({ kind: "step-start" });
2105
+ break;
2106
+ case "STEP_FINISHED":
2107
+ frame({ kind: "step-finish" });
2108
+ break;
2109
+ case "TOOL_CALL_START":
2110
+ case "TOOL_CALL_CHUNK": {
2111
+ const id = String(event.toolCallId ?? "");
2112
+ if (id === "") break;
2113
+ if (!tools.has(id)) {
2114
+ const name = typeof event.toolCallName === "string" ? event.toolCallName : "";
2115
+ tools.set(id, { name, args: "" });
2116
+ frame({ kind: "tool-input-start", id, name, toolKind: "read" });
2117
+ }
2118
+ if (event.type === "TOOL_CALL_CHUNK" && typeof event.delta === "string") {
2119
+ tools.get(id).args += event.delta;
2120
+ frame({ kind: "tool-input-delta", id, delta: event.delta });
2121
+ }
2122
+ break;
2123
+ }
2124
+ case "TOOL_CALL_ARGS": {
2125
+ const call = tools.get(String(event.toolCallId));
2126
+ if (call === void 0 || typeof event.delta !== "string") break;
2127
+ call.args += event.delta;
2128
+ frame({ kind: "tool-input-delta", id: String(event.toolCallId), delta: event.delta });
2129
+ break;
2130
+ }
2131
+ case "TOOL_CALL_END": {
2132
+ const id = String(event.toolCallId);
2133
+ const call = tools.get(id);
2134
+ if (call === void 0) break;
2135
+ frame({
2136
+ kind: "tool-input-available",
2137
+ id,
2138
+ name: call.name,
2139
+ input: parseJson(call.args, {}),
2140
+ toolKind: "read"
2141
+ });
2142
+ break;
2143
+ }
2144
+ case "TOOL_CALL_RESULT": {
2145
+ const id = String(event.toolCallId);
2146
+ const content = contentText(event.content);
2147
+ const outcome = isRecord2(event.metadata) ? event.metadata["agora.outcome"] : void 0;
2148
+ if (outcome === "error") frame({ kind: "tool-output-error", id, error: content });
2149
+ else if (outcome === "denied") frame({ kind: "tool-output-denied", id, reason: content });
2150
+ else frame({ kind: "tool-output", id, output: parseJson(content, content) });
2151
+ break;
2152
+ }
2153
+ case "ACTIVITY_SNAPSHOT":
2154
+ case "ACTIVITY_DELTA": {
2155
+ const messageId = typeof event.messageId === "string" ? event.messageId : "";
2156
+ if (messageId === "") break;
2157
+ const known = activities.get(messageId);
2158
+ const activityType = typeof event.activityType === "string" ? event.activityType : known?.activityType ?? "";
2159
+ let content;
2160
+ if (event.type === "ACTIVITY_SNAPSHOT") {
2161
+ if (known !== void 0 && event.replace === false) break;
2162
+ content = isRecord2(event.content) ? event.content : {};
2163
+ } else {
2164
+ if (known === void 0 || !Array.isArray(event.patch)) break;
2165
+ content = applyPatch(known.content, event.patch);
2166
+ if (content === void 0) break;
2167
+ }
2168
+ activities.set(messageId, { activityType, content });
2169
+ frame({
2170
+ kind: "ui",
2171
+ id: `activity:${messageId}`,
2172
+ component: "AgUiActivity",
2173
+ props: { activityType, content }
2174
+ });
2175
+ break;
2176
+ }
2177
+ case "RUN_ERROR":
2178
+ state.closed = true;
2179
+ out += `event: error
2180
+ data: ${JSON.stringify({
2181
+ code: typeof event.code === "string" ? event.code : "run_failed",
2182
+ message: typeof event.message === "string" ? event.message : "The run failed."
2183
+ })}
2184
+
2185
+ `;
2186
+ break;
2187
+ case "RUN_FINISHED": {
2188
+ const outcome = isRecord2(event.outcome) ? event.outcome : void 0;
2189
+ if (outcome?.type === "cancelled") frame({ kind: "cancelled" });
2190
+ if (outcome?.type === "interrupt" && Array.isArray(outcome.interrupts)) {
2191
+ frame({
2192
+ kind: "ui",
2193
+ id: `ag-ui:interrupt:${String(event.runId ?? "")}`,
2194
+ component: "AgUiInterrupt",
2195
+ props: { interrupts: outcome.interrupts }
2196
+ });
2197
+ }
2198
+ state.closed = true;
2199
+ out += "event: done\ndata: {}\n\n";
2200
+ break;
2201
+ }
2202
+ default:
2203
+ break;
2204
+ }
2205
+ return out;
2206
+ function flushStart() {
2207
+ if (pendingStart !== void 0) {
2208
+ meta(pendingStart.runId, pendingStart.threadId);
2209
+ pendingStart = void 0;
2210
+ }
2211
+ }
2212
+ }
2213
+ };
2214
+ let pendingStart;
2215
+ return state;
2216
+ }
2217
+ function parseJson(text, fallback2) {
2218
+ if (text.trim().length === 0) return fallback2;
2219
+ try {
2220
+ return JSON.parse(text);
2221
+ } catch {
2222
+ return fallback2;
2223
+ }
2224
+ }
2225
+ function contentText(content) {
2226
+ if (typeof content === "string") return content;
2227
+ if (!Array.isArray(content)) return "";
2228
+ return content.filter((part) => isRecord2(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
2229
+ }
2230
+ function applyPatch(target, patch) {
2231
+ const doc = structuredClone(target);
2232
+ for (const operation of patch) {
2233
+ if (!isRecord2(operation) || typeof operation.path !== "string") return void 0;
2234
+ const tokens = operation.path.split("/").slice(1).map((token) => token.replace(/~1/g, "/").replace(/~0/g, "~"));
2235
+ const key = tokens.pop();
2236
+ if (key === void 0) return void 0;
2237
+ let parent = doc;
2238
+ for (const token of tokens) {
2239
+ parent = Array.isArray(parent) ? parent[Number(token)] : isRecord2(parent) ? parent[token] : void 0;
2240
+ if (parent === void 0) return void 0;
2241
+ }
2242
+ if (Array.isArray(parent)) {
2243
+ const index = key === "-" ? parent.length : Number(key);
2244
+ if (!Number.isInteger(index) || index < 0 || index > parent.length) return void 0;
2245
+ if (operation.op === "add") parent.splice(index, 0, operation.value);
2246
+ else if (operation.op === "replace" && index < parent.length) parent[index] = operation.value;
2247
+ else if (operation.op === "remove" && index < parent.length) parent.splice(index, 1);
2248
+ else if (operation.op === "test") {
2249
+ if (JSON.stringify(parent[index]) !== JSON.stringify(operation.value)) return void 0;
2250
+ } else return void 0;
2251
+ } else if (isRecord2(parent)) {
2252
+ if (operation.op === "add" || operation.op === "replace" && key in parent) {
2253
+ parent[key] = operation.value;
2254
+ } else if (operation.op === "remove" && key in parent) delete parent[key];
2255
+ else if (operation.op === "test") {
2256
+ if (JSON.stringify(parent[key]) !== JSON.stringify(operation.value)) return void 0;
2257
+ } else return void 0;
2258
+ } else return void 0;
2259
+ }
2260
+ return doc;
2261
+ }
2262
+
1928
2263
  // src/catalog/use-agents.ts
1929
2264
  var import_react9 = require("react");
1930
2265
 
@@ -2562,7 +2897,7 @@ function phraseFor(presentation, input, isSettled2, fallback2 = { running: "Work
2562
2897
  }
2563
2898
 
2564
2899
  // src/presentation/result-view.ts
2565
- function isRecord2(value) {
2900
+ function isRecord3(value) {
2566
2901
  return typeof value === "object" && value !== null && !Array.isArray(value);
2567
2902
  }
2568
2903
  function toText(value) {
@@ -2574,18 +2909,18 @@ function toText(value) {
2574
2909
  return "\u2014";
2575
2910
  }
2576
2911
  function inferResultView(output) {
2577
- if (!isRecord2(output)) return void 0;
2912
+ if (!isRecord3(output)) return void 0;
2578
2913
  for (const [key, value] of Object.entries(output)) {
2579
2914
  if (!Array.isArray(value) || value.length === 0) continue;
2580
2915
  if (value.every((entry) => typeof entry === "string")) {
2581
2916
  return { kind: "log", lines: key };
2582
2917
  }
2583
- if (value.every(isRecord2)) {
2918
+ if (value.every(isRecord3)) {
2584
2919
  const first = value[0];
2585
2920
  return {
2586
2921
  kind: "table",
2587
2922
  rows: key,
2588
- columns: Object.keys(first).filter((column) => !isRecord2(first[column])).map((column) => ({ path: column, label: column }))
2923
+ columns: Object.keys(first).filter((column) => !isRecord3(first[column])).map((column) => ({ path: column, label: column }))
2589
2924
  };
2590
2925
  }
2591
2926
  }
@@ -2912,7 +3247,7 @@ function isSettled(state) {
2912
3247
  }
2913
3248
  function toolKind(part) {
2914
3249
  const metadata = part.toolMetadata;
2915
- return isRecord3(metadata) && typeof metadata.toolKind === "string" ? metadata.toolKind : void 0;
3250
+ return isRecord4(metadata) && typeof metadata.toolKind === "string" ? metadata.toolKind : void 0;
2916
3251
  }
2917
3252
  function isAwaitingApproval(part) {
2918
3253
  if (part.state === "approval-requested") {
@@ -2925,7 +3260,7 @@ function isAwaitingApproval(part) {
2925
3260
  }
2926
3261
  function toolParentId(part) {
2927
3262
  const metadata = part.toolMetadata;
2928
- return isRecord3(metadata) && typeof metadata.parentId === "string" ? metadata.parentId : null;
3263
+ return isRecord4(metadata) && typeof metadata.parentId === "string" ? metadata.parentId : null;
2929
3264
  }
2930
3265
  function nestToolCalls(calls) {
2931
3266
  const byId = new Map(calls.map((call) => [call.toolCallId, call]));
@@ -2984,12 +3319,12 @@ function buildToolCall(part, options, approval, catalog) {
2984
3319
  }
2985
3320
  function readElicitationRequest(part) {
2986
3321
  const input = part.input;
2987
- if (!isRecord3(input) || !Array.isArray(input.questions) || input.questions.length === 0) {
3322
+ if (!isRecord4(input) || !Array.isArray(input.questions) || input.questions.length === 0) {
2988
3323
  return null;
2989
3324
  }
2990
3325
  const questions = [];
2991
3326
  for (const candidate of input.questions) {
2992
- if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
3327
+ if (!isRecord4(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
2993
3328
  return null;
2994
3329
  }
2995
3330
  const input2 = (0, import_nestjs_agent_core3.readElicitationInput)(candidate.input) ?? null;
@@ -2999,7 +3334,7 @@ function readElicitationRequest(part) {
2999
3334
  }
3000
3335
  const options = [];
3001
3336
  for (const option of rawOptions) {
3002
- if (!isRecord3(option) || typeof option.value !== "string" || typeof option.label !== "string") {
3337
+ if (!isRecord4(option) || typeof option.value !== "string" || typeof option.label !== "string") {
3003
3338
  return null;
3004
3339
  }
3005
3340
  options.push({
@@ -3026,7 +3361,7 @@ function readElicitationRequest(part) {
3026
3361
  }
3027
3362
  function readElicitationOutcome(part) {
3028
3363
  const output = part.output;
3029
- if (!isRecord3(output) || !isRecord3(output.answers) || typeof output.skipped !== "boolean") {
3364
+ if (!isRecord4(output) || !isRecord4(output.answers) || typeof output.skipped !== "boolean") {
3030
3365
  return null;
3031
3366
  }
3032
3367
  const answers = {};
@@ -3151,7 +3486,7 @@ function readApprovals(parts) {
3151
3486
  continue;
3152
3487
  }
3153
3488
  const data = part.data;
3154
- if (!isRecord3(data) || typeof data.id !== "string") {
3489
+ if (!isRecord4(data) || typeof data.id !== "string") {
3155
3490
  continue;
3156
3491
  }
3157
3492
  const approval = entry(data.id);
@@ -3204,7 +3539,7 @@ function statusFromPart(call) {
3204
3539
  }
3205
3540
  function readUiComponent(part) {
3206
3541
  const data = part.data;
3207
- if (!isRecord3(data) || typeof data.component !== "string") {
3542
+ if (!isRecord4(data) || typeof data.component !== "string") {
3208
3543
  return null;
3209
3544
  }
3210
3545
  const id = typeof data.id === "string" ? data.id : part.id;
@@ -3214,29 +3549,29 @@ function readUiComponent(part) {
3214
3549
  return {
3215
3550
  id,
3216
3551
  component: data.component,
3217
- props: isRecord3(data.props) ? data.props : {},
3552
+ props: isRecord4(data.props) ? data.props : {},
3218
3553
  version: typeof data.version === "number" ? data.version : null,
3219
3554
  toolCallId: typeof data.toolCallId === "string" ? data.toolCallId : null
3220
3555
  };
3221
3556
  }
3222
- function isRecord3(value) {
3557
+ function isRecord4(value) {
3223
3558
  return typeof value === "object" && value !== null;
3224
3559
  }
3225
3560
  function readQuery(part) {
3226
3561
  const input = part.input;
3227
- if (!isRecord3(input) || typeof input.query !== "string") {
3562
+ if (!isRecord4(input) || typeof input.query !== "string") {
3228
3563
  return null;
3229
3564
  }
3230
3565
  return input.query;
3231
3566
  }
3232
3567
  function readPassages(part) {
3233
3568
  const output = part.output;
3234
- if (!isRecord3(output) || !Array.isArray(output.passages) || output.passages.length === 0) {
3569
+ if (!isRecord4(output) || !Array.isArray(output.passages) || output.passages.length === 0) {
3235
3570
  return null;
3236
3571
  }
3237
3572
  const passages = [];
3238
3573
  for (const candidate of output.passages) {
3239
- if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.text !== "string") {
3574
+ if (!isRecord4(candidate) || typeof candidate.id !== "string" || typeof candidate.text !== "string") {
3240
3575
  return null;
3241
3576
  }
3242
3577
  passages.push({
@@ -3244,7 +3579,7 @@ function readPassages(part) {
3244
3579
  text: candidate.text,
3245
3580
  score: typeof candidate.score === "number" ? candidate.score : 0,
3246
3581
  ...typeof candidate.source === "string" ? { source: candidate.source } : {},
3247
- ...isRecord3(candidate.metadata) ? { metadata: candidate.metadata } : {}
3582
+ ...isRecord4(candidate.metadata) ? { metadata: candidate.metadata } : {}
3248
3583
  });
3249
3584
  }
3250
3585
  return passages;
@@ -5871,6 +6206,7 @@ function isRunNotActiveError(error) {
5871
6206
  RUN_NOT_ACTIVE_CODE,
5872
6207
  SPEECH_LANGUAGES,
5873
6208
  acceptsFile,
6209
+ agUiChatStream,
5874
6210
  applyCompletion,
5875
6211
  approvalCountdown,
5876
6212
  attachmentFile,
@@ -5903,6 +6239,7 @@ function isRunNotActiveError(error) {
5903
6239
  phraseFor,
5904
6240
  readPath,
5905
6241
  readReasoningMs,
6242
+ reframeAgUiStream,
5906
6243
  requireBackendMethod,
5907
6244
  resolveResultView,
5908
6245
  storedMessageToUiMessage,