@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 +29 -0
- package/dist/{client-DhHEJi7c.d.cts → client-BuobfZtx.d.cts} +1 -1
- package/dist/{client-DhHEJi7c.d.ts → client-BuobfZtx.d.ts} +1 -1
- package/dist/index.cjs +298 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -3
- package/dist/index.d.ts +56 -3
- package/dist/index.js +296 -18
- package/dist/index.js.map +1 -1
- package/dist/media.d.cts +1 -1
- package/dist/media.d.ts +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
|
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 (!
|
|
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(
|
|
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) => !
|
|
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
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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:
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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
|
-
...
|
|
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,
|