@dudousxd/nestjs-agent-react 0.29.2 → 0.30.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,35 @@ 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
+ - `reframeAgUiStream(body, { threadId })` is the re-framing alone, for a backend that fetches itself.
652
+
624
653
  ### Typing ahead: the message queue
625
654
 
626
655
  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,282 @@ 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: 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
+ let seq = 0;
2037
+ let metaSent = false;
2038
+ const tools = /* @__PURE__ */ new Map();
2039
+ const state = {
2040
+ closed: false,
2041
+ push(event) {
2042
+ if (state.closed) return "";
2043
+ let out = "";
2044
+ const frame = (streamEvent) => {
2045
+ seq += 1;
2046
+ out += `id: ${seq}
2047
+ data: ${JSON.stringify(streamEvent)}
2048
+
2049
+ `;
2050
+ };
2051
+ const meta = (runId, thread) => {
2052
+ if (metaSent) return;
2053
+ metaSent = true;
2054
+ out += `event: meta
2055
+ data: ${JSON.stringify({
2056
+ runId: typeof runId === "string" ? runId : "",
2057
+ threadId: typeof thread === "string" ? thread : threadId
2058
+ })}
2059
+
2060
+ `;
2061
+ };
2062
+ switch (event.type) {
2063
+ case "RUN_STARTED":
2064
+ pendingStart = { runId: event.runId, threadId: event.threadId };
2065
+ return out;
2066
+ case "CUSTOM": {
2067
+ const value = event.value;
2068
+ if (event.name === "agora.run" && isRecord2(value)) {
2069
+ meta(value.runId, pendingStart?.threadId ?? value.threadId);
2070
+ pendingStart = void 0;
2071
+ return out;
2072
+ }
2073
+ flushStart();
2074
+ if (!isRecord2(value)) return out;
2075
+ if (event.name === "agora.ui") frame({ kind: "ui", ...value });
2076
+ else if (event.name === "agora.title" && typeof value.title === "string") {
2077
+ frame({ kind: "title", title: value.title });
2078
+ } else if (event.name === "agora.queue") frame({ kind: "queue", ...value });
2079
+ else if (event.name === "agora.approval-requested") {
2080
+ frame({ ...value, kind: "approval-requested" });
2081
+ } else if (event.name === "agora.approval-settled") {
2082
+ frame({ ...value, kind: "approval-settled" });
2083
+ }
2084
+ return out;
2085
+ }
2086
+ default:
2087
+ flushStart();
2088
+ }
2089
+ switch (event.type) {
2090
+ case "TEXT_MESSAGE_CONTENT":
2091
+ case "TEXT_MESSAGE_CHUNK":
2092
+ if (typeof event.delta === "string" && event.delta.length > 0) {
2093
+ frame({ kind: "text", text: event.delta });
2094
+ }
2095
+ break;
2096
+ case "REASONING_MESSAGE_CONTENT":
2097
+ case "REASONING_MESSAGE_CHUNK":
2098
+ if (typeof event.delta === "string" && event.delta.length > 0) {
2099
+ frame({ kind: "reasoning", text: event.delta });
2100
+ }
2101
+ break;
2102
+ case "STEP_STARTED":
2103
+ frame({ kind: "step-start" });
2104
+ break;
2105
+ case "STEP_FINISHED":
2106
+ frame({ kind: "step-finish" });
2107
+ break;
2108
+ case "TOOL_CALL_START":
2109
+ case "TOOL_CALL_CHUNK": {
2110
+ const id = String(event.toolCallId ?? "");
2111
+ if (id === "") break;
2112
+ if (!tools.has(id)) {
2113
+ const name = typeof event.toolCallName === "string" ? event.toolCallName : "";
2114
+ tools.set(id, { name, args: "" });
2115
+ frame({ kind: "tool-input-start", id, name, toolKind: "read" });
2116
+ }
2117
+ if (event.type === "TOOL_CALL_CHUNK" && typeof event.delta === "string") {
2118
+ tools.get(id).args += event.delta;
2119
+ frame({ kind: "tool-input-delta", id, delta: event.delta });
2120
+ }
2121
+ break;
2122
+ }
2123
+ case "TOOL_CALL_ARGS": {
2124
+ const call = tools.get(String(event.toolCallId));
2125
+ if (call === void 0 || typeof event.delta !== "string") break;
2126
+ call.args += event.delta;
2127
+ frame({ kind: "tool-input-delta", id: String(event.toolCallId), delta: event.delta });
2128
+ break;
2129
+ }
2130
+ case "TOOL_CALL_END": {
2131
+ const id = String(event.toolCallId);
2132
+ const call = tools.get(id);
2133
+ if (call === void 0) break;
2134
+ frame({
2135
+ kind: "tool-input-available",
2136
+ id,
2137
+ name: call.name,
2138
+ input: parseJson(call.args, {}),
2139
+ toolKind: "read"
2140
+ });
2141
+ break;
2142
+ }
2143
+ case "TOOL_CALL_RESULT": {
2144
+ const id = String(event.toolCallId);
2145
+ const content = contentText(event.content);
2146
+ const outcome = isRecord2(event.metadata) ? event.metadata["agora.outcome"] : void 0;
2147
+ if (outcome === "error") frame({ kind: "tool-output-error", id, error: content });
2148
+ else if (outcome === "denied") frame({ kind: "tool-output-denied", id, reason: content });
2149
+ else frame({ kind: "tool-output", id, output: parseJson(content, content) });
2150
+ break;
2151
+ }
2152
+ case "RUN_ERROR":
2153
+ state.closed = true;
2154
+ out += `event: error
2155
+ data: ${JSON.stringify({
2156
+ code: typeof event.code === "string" ? event.code : "run_failed",
2157
+ message: typeof event.message === "string" ? event.message : "The run failed."
2158
+ })}
2159
+
2160
+ `;
2161
+ break;
2162
+ case "RUN_FINISHED": {
2163
+ const outcome = isRecord2(event.outcome) ? event.outcome : void 0;
2164
+ if (outcome?.type === "cancelled") frame({ kind: "cancelled" });
2165
+ if (outcome?.type === "interrupt" && Array.isArray(outcome.interrupts)) {
2166
+ frame({
2167
+ kind: "ui",
2168
+ id: `ag-ui:interrupt:${String(event.runId ?? "")}`,
2169
+ component: "AgUiInterrupt",
2170
+ props: { interrupts: outcome.interrupts }
2171
+ });
2172
+ }
2173
+ state.closed = true;
2174
+ out += "event: done\ndata: {}\n\n";
2175
+ break;
2176
+ }
2177
+ default:
2178
+ break;
2179
+ }
2180
+ return out;
2181
+ function flushStart() {
2182
+ if (pendingStart !== void 0) {
2183
+ meta(pendingStart.runId, pendingStart.threadId);
2184
+ pendingStart = void 0;
2185
+ }
2186
+ }
2187
+ }
2188
+ };
2189
+ let pendingStart;
2190
+ return state;
2191
+ }
2192
+ function parseJson(text, fallback2) {
2193
+ if (text.trim().length === 0) return fallback2;
2194
+ try {
2195
+ return JSON.parse(text);
2196
+ } catch {
2197
+ return fallback2;
2198
+ }
2199
+ }
2200
+ function contentText(content) {
2201
+ if (typeof content === "string") return content;
2202
+ if (!Array.isArray(content)) return "";
2203
+ return content.filter((part) => isRecord2(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
2204
+ }
2205
+
1928
2206
  // src/catalog/use-agents.ts
1929
2207
  var import_react9 = require("react");
1930
2208
 
@@ -2562,7 +2840,7 @@ function phraseFor(presentation, input, isSettled2, fallback2 = { running: "Work
2562
2840
  }
2563
2841
 
2564
2842
  // src/presentation/result-view.ts
2565
- function isRecord2(value) {
2843
+ function isRecord3(value) {
2566
2844
  return typeof value === "object" && value !== null && !Array.isArray(value);
2567
2845
  }
2568
2846
  function toText(value) {
@@ -2574,18 +2852,18 @@ function toText(value) {
2574
2852
  return "\u2014";
2575
2853
  }
2576
2854
  function inferResultView(output) {
2577
- if (!isRecord2(output)) return void 0;
2855
+ if (!isRecord3(output)) return void 0;
2578
2856
  for (const [key, value] of Object.entries(output)) {
2579
2857
  if (!Array.isArray(value) || value.length === 0) continue;
2580
2858
  if (value.every((entry) => typeof entry === "string")) {
2581
2859
  return { kind: "log", lines: key };
2582
2860
  }
2583
- if (value.every(isRecord2)) {
2861
+ if (value.every(isRecord3)) {
2584
2862
  const first = value[0];
2585
2863
  return {
2586
2864
  kind: "table",
2587
2865
  rows: key,
2588
- columns: Object.keys(first).filter((column) => !isRecord2(first[column])).map((column) => ({ path: column, label: column }))
2866
+ columns: Object.keys(first).filter((column) => !isRecord3(first[column])).map((column) => ({ path: column, label: column }))
2589
2867
  };
2590
2868
  }
2591
2869
  }
@@ -2912,7 +3190,7 @@ function isSettled(state) {
2912
3190
  }
2913
3191
  function toolKind(part) {
2914
3192
  const metadata = part.toolMetadata;
2915
- return isRecord3(metadata) && typeof metadata.toolKind === "string" ? metadata.toolKind : void 0;
3193
+ return isRecord4(metadata) && typeof metadata.toolKind === "string" ? metadata.toolKind : void 0;
2916
3194
  }
2917
3195
  function isAwaitingApproval(part) {
2918
3196
  if (part.state === "approval-requested") {
@@ -2925,7 +3203,7 @@ function isAwaitingApproval(part) {
2925
3203
  }
2926
3204
  function toolParentId(part) {
2927
3205
  const metadata = part.toolMetadata;
2928
- return isRecord3(metadata) && typeof metadata.parentId === "string" ? metadata.parentId : null;
3206
+ return isRecord4(metadata) && typeof metadata.parentId === "string" ? metadata.parentId : null;
2929
3207
  }
2930
3208
  function nestToolCalls(calls) {
2931
3209
  const byId = new Map(calls.map((call) => [call.toolCallId, call]));
@@ -2984,12 +3262,12 @@ function buildToolCall(part, options, approval, catalog) {
2984
3262
  }
2985
3263
  function readElicitationRequest(part) {
2986
3264
  const input = part.input;
2987
- if (!isRecord3(input) || !Array.isArray(input.questions) || input.questions.length === 0) {
3265
+ if (!isRecord4(input) || !Array.isArray(input.questions) || input.questions.length === 0) {
2988
3266
  return null;
2989
3267
  }
2990
3268
  const questions = [];
2991
3269
  for (const candidate of input.questions) {
2992
- if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
3270
+ if (!isRecord4(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
2993
3271
  return null;
2994
3272
  }
2995
3273
  const input2 = (0, import_nestjs_agent_core3.readElicitationInput)(candidate.input) ?? null;
@@ -2999,7 +3277,7 @@ function readElicitationRequest(part) {
2999
3277
  }
3000
3278
  const options = [];
3001
3279
  for (const option of rawOptions) {
3002
- if (!isRecord3(option) || typeof option.value !== "string" || typeof option.label !== "string") {
3280
+ if (!isRecord4(option) || typeof option.value !== "string" || typeof option.label !== "string") {
3003
3281
  return null;
3004
3282
  }
3005
3283
  options.push({
@@ -3026,7 +3304,7 @@ function readElicitationRequest(part) {
3026
3304
  }
3027
3305
  function readElicitationOutcome(part) {
3028
3306
  const output = part.output;
3029
- if (!isRecord3(output) || !isRecord3(output.answers) || typeof output.skipped !== "boolean") {
3307
+ if (!isRecord4(output) || !isRecord4(output.answers) || typeof output.skipped !== "boolean") {
3030
3308
  return null;
3031
3309
  }
3032
3310
  const answers = {};
@@ -3151,7 +3429,7 @@ function readApprovals(parts) {
3151
3429
  continue;
3152
3430
  }
3153
3431
  const data = part.data;
3154
- if (!isRecord3(data) || typeof data.id !== "string") {
3432
+ if (!isRecord4(data) || typeof data.id !== "string") {
3155
3433
  continue;
3156
3434
  }
3157
3435
  const approval = entry(data.id);
@@ -3204,7 +3482,7 @@ function statusFromPart(call) {
3204
3482
  }
3205
3483
  function readUiComponent(part) {
3206
3484
  const data = part.data;
3207
- if (!isRecord3(data) || typeof data.component !== "string") {
3485
+ if (!isRecord4(data) || typeof data.component !== "string") {
3208
3486
  return null;
3209
3487
  }
3210
3488
  const id = typeof data.id === "string" ? data.id : part.id;
@@ -3214,29 +3492,29 @@ function readUiComponent(part) {
3214
3492
  return {
3215
3493
  id,
3216
3494
  component: data.component,
3217
- props: isRecord3(data.props) ? data.props : {},
3495
+ props: isRecord4(data.props) ? data.props : {},
3218
3496
  version: typeof data.version === "number" ? data.version : null,
3219
3497
  toolCallId: typeof data.toolCallId === "string" ? data.toolCallId : null
3220
3498
  };
3221
3499
  }
3222
- function isRecord3(value) {
3500
+ function isRecord4(value) {
3223
3501
  return typeof value === "object" && value !== null;
3224
3502
  }
3225
3503
  function readQuery(part) {
3226
3504
  const input = part.input;
3227
- if (!isRecord3(input) || typeof input.query !== "string") {
3505
+ if (!isRecord4(input) || typeof input.query !== "string") {
3228
3506
  return null;
3229
3507
  }
3230
3508
  return input.query;
3231
3509
  }
3232
3510
  function readPassages(part) {
3233
3511
  const output = part.output;
3234
- if (!isRecord3(output) || !Array.isArray(output.passages) || output.passages.length === 0) {
3512
+ if (!isRecord4(output) || !Array.isArray(output.passages) || output.passages.length === 0) {
3235
3513
  return null;
3236
3514
  }
3237
3515
  const passages = [];
3238
3516
  for (const candidate of output.passages) {
3239
- if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.text !== "string") {
3517
+ if (!isRecord4(candidate) || typeof candidate.id !== "string" || typeof candidate.text !== "string") {
3240
3518
  return null;
3241
3519
  }
3242
3520
  passages.push({
@@ -3244,7 +3522,7 @@ function readPassages(part) {
3244
3522
  text: candidate.text,
3245
3523
  score: typeof candidate.score === "number" ? candidate.score : 0,
3246
3524
  ...typeof candidate.source === "string" ? { source: candidate.source } : {},
3247
- ...isRecord3(candidate.metadata) ? { metadata: candidate.metadata } : {}
3525
+ ...isRecord4(candidate.metadata) ? { metadata: candidate.metadata } : {}
3248
3526
  });
3249
3527
  }
3250
3528
  return passages;
@@ -5871,6 +6149,7 @@ function isRunNotActiveError(error) {
5871
6149
  RUN_NOT_ACTIVE_CODE,
5872
6150
  SPEECH_LANGUAGES,
5873
6151
  acceptsFile,
6152
+ agUiChatStream,
5874
6153
  applyCompletion,
5875
6154
  approvalCountdown,
5876
6155
  attachmentFile,
@@ -5903,6 +6182,7 @@ function isRunNotActiveError(error) {
5903
6182
  phraseFor,
5904
6183
  readPath,
5905
6184
  readReasoningMs,
6185
+ reframeAgUiStream,
5906
6186
  requireBackendMethod,
5907
6187
  resolveResultView,
5908
6188
  storedMessageToUiMessage,