@dudousxd/nestjs-agent-react 0.34.0 → 0.34.2
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/dist/index.cjs +155 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -14
- package/dist/index.d.ts +33 -14
- package/dist/index.js +155 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1064,7 +1064,10 @@ var AgentChatTransport = class {
|
|
|
1064
1064
|
forwardAsData(event, true);
|
|
1065
1065
|
break;
|
|
1066
1066
|
default:
|
|
1067
|
-
forwardAsData(
|
|
1067
|
+
forwardAsData(
|
|
1068
|
+
event,
|
|
1069
|
+
event.kind === "proposal-decision"
|
|
1070
|
+
);
|
|
1068
1071
|
break;
|
|
1069
1072
|
}
|
|
1070
1073
|
}
|
|
@@ -2079,8 +2082,33 @@ function defaultForwardedProps(body) {
|
|
|
2079
2082
|
for (const key of ["pageContext", "agent", "model", "persona", "uiCapabilities"]) {
|
|
2080
2083
|
if (body[key] !== void 0 && body[key] !== null) out[key] = body[key];
|
|
2081
2084
|
}
|
|
2085
|
+
if (body.regenerate === true) out.regenerate = true;
|
|
2082
2086
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
2083
2087
|
}
|
|
2088
|
+
var MEDIA_PROVIDER = "nestjs-agent";
|
|
2089
|
+
function partTypeFor(contentType) {
|
|
2090
|
+
const major = contentType?.split("/")[0]?.toLowerCase();
|
|
2091
|
+
return major === "image" || major === "audio" || major === "video" ? major : "document";
|
|
2092
|
+
}
|
|
2093
|
+
function defaultContent(body, message) {
|
|
2094
|
+
const attachments = Array.isArray(body.attachments) ? body.attachments : [];
|
|
2095
|
+
const files = [];
|
|
2096
|
+
for (const attachment of attachments) {
|
|
2097
|
+
if (!isRecord2(attachment) || typeof attachment.mediaId !== "string") continue;
|
|
2098
|
+
const contentType = typeof attachment.contentType === "string" ? attachment.contentType : void 0;
|
|
2099
|
+
files.push({
|
|
2100
|
+
type: partTypeFor(contentType),
|
|
2101
|
+
source: {
|
|
2102
|
+
type: "file",
|
|
2103
|
+
value: attachment.mediaId,
|
|
2104
|
+
provider: MEDIA_PROVIDER,
|
|
2105
|
+
...contentType !== void 0 ? { mimeType: contentType } : {}
|
|
2106
|
+
}
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
if (files.length === 0) return message;
|
|
2110
|
+
return [...message.length > 0 ? [{ type: "text", text: message }] : [], ...files];
|
|
2111
|
+
}
|
|
2084
2112
|
async function agUiChatStream(request, options) {
|
|
2085
2113
|
const body = request.body;
|
|
2086
2114
|
const threadId = typeof body.threadId === "string" ? body.threadId : newId();
|
|
@@ -2090,7 +2118,13 @@ async function agUiChatStream(request, options) {
|
|
|
2090
2118
|
threadId,
|
|
2091
2119
|
runId: newId(),
|
|
2092
2120
|
protocolVersion: "1.0",
|
|
2093
|
-
messages: [
|
|
2121
|
+
messages: [
|
|
2122
|
+
{
|
|
2123
|
+
id: newId(),
|
|
2124
|
+
role: "user",
|
|
2125
|
+
content: options.content?.(body) ?? defaultContent(body, message)
|
|
2126
|
+
}
|
|
2127
|
+
],
|
|
2094
2128
|
...forwarded !== void 0 ? { forwardedProps: forwarded } : {}
|
|
2095
2129
|
};
|
|
2096
2130
|
const doFetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
@@ -2127,6 +2161,8 @@ function reframeAgUiStream(source, ids) {
|
|
|
2127
2161
|
for (; ; ) {
|
|
2128
2162
|
const { value, done } = await reader.read();
|
|
2129
2163
|
if (done) {
|
|
2164
|
+
const rest = reframer.flush();
|
|
2165
|
+
if (rest.length > 0) controller.enqueue(encoder.encode(rest));
|
|
2130
2166
|
controller.close();
|
|
2131
2167
|
return;
|
|
2132
2168
|
}
|
|
@@ -2137,7 +2173,10 @@ function reframeAgUiStream(source, ids) {
|
|
|
2137
2173
|
const block = buffer.slice(0, separator);
|
|
2138
2174
|
buffer = buffer.slice(separator + 2);
|
|
2139
2175
|
separator = buffer.indexOf("\n\n");
|
|
2140
|
-
const
|
|
2176
|
+
const lines = block.split("\n");
|
|
2177
|
+
const idLine = lines.find((line) => line.startsWith("id:"));
|
|
2178
|
+
const id = idLine === void 0 ? void 0 : Number(idLine.slice(3).trim());
|
|
2179
|
+
const data = lines.filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
2141
2180
|
if (data.length === 0) continue;
|
|
2142
2181
|
let event;
|
|
2143
2182
|
try {
|
|
@@ -2146,7 +2185,10 @@ function reframeAgUiStream(source, ids) {
|
|
|
2146
2185
|
continue;
|
|
2147
2186
|
}
|
|
2148
2187
|
if (isRecord2(event) && typeof event.type === "string") {
|
|
2149
|
-
out += reframer.push(
|
|
2188
|
+
out += reframer.push(
|
|
2189
|
+
event,
|
|
2190
|
+
id !== void 0 && Number.isSafeInteger(id) && id > 0 ? id : void 0
|
|
2191
|
+
);
|
|
2150
2192
|
}
|
|
2151
2193
|
if (reframer.closed) break;
|
|
2152
2194
|
}
|
|
@@ -2166,21 +2208,55 @@ function reframeAgUiStream(source, ids) {
|
|
|
2166
2208
|
}
|
|
2167
2209
|
function createReframer(threadId) {
|
|
2168
2210
|
const activities = /* @__PURE__ */ new Map();
|
|
2169
|
-
let seq = 0;
|
|
2170
2211
|
let metaSent = false;
|
|
2171
2212
|
const tools = /* @__PURE__ */ new Map();
|
|
2213
|
+
let pendingStep;
|
|
2214
|
+
const encodeFrame = (streamEvent) => `data: ${JSON.stringify(streamEvent)}
|
|
2215
|
+
|
|
2216
|
+
`;
|
|
2217
|
+
const flushStep = () => {
|
|
2218
|
+
if (pendingStep === void 0) return "";
|
|
2219
|
+
const step = pendingStep;
|
|
2220
|
+
pendingStep = void 0;
|
|
2221
|
+
return encodeFrame(step);
|
|
2222
|
+
};
|
|
2223
|
+
let current;
|
|
2224
|
+
let written;
|
|
2225
|
+
const cursor = () => {
|
|
2226
|
+
if (current === void 0 || current === written) return "";
|
|
2227
|
+
written = current;
|
|
2228
|
+
return `${flushStep()}id: ${current}
|
|
2229
|
+
|
|
2230
|
+
`;
|
|
2231
|
+
};
|
|
2232
|
+
const shown = /* @__PURE__ */ new Set();
|
|
2233
|
+
let decision;
|
|
2172
2234
|
const state = {
|
|
2173
2235
|
closed: false,
|
|
2174
|
-
|
|
2236
|
+
flush() {
|
|
2237
|
+
return state.closed ? "" : `${flushStep()}${cursor()}`;
|
|
2238
|
+
},
|
|
2239
|
+
push(event, id) {
|
|
2175
2240
|
if (state.closed) return "";
|
|
2176
2241
|
let out = "";
|
|
2242
|
+
if (id !== void 0) {
|
|
2243
|
+
if (current !== void 0 && id > current) out += cursor();
|
|
2244
|
+
current = id;
|
|
2245
|
+
}
|
|
2177
2246
|
const frame = (streamEvent) => {
|
|
2178
|
-
|
|
2179
|
-
out += `id: ${seq}
|
|
2180
|
-
data: ${JSON.stringify(streamEvent)}
|
|
2181
|
-
|
|
2182
|
-
`;
|
|
2247
|
+
out += encodeFrame(streamEvent);
|
|
2183
2248
|
};
|
|
2249
|
+
if (event.type === "CUSTOM" && event.name === "agora.step-usage" && pendingStep !== void 0 && isRecord2(event.value)) {
|
|
2250
|
+
const value = event.value;
|
|
2251
|
+
if (isRecord2(value.usage)) pendingStep.usage = value.usage;
|
|
2252
|
+
if (typeof value.costUsd === "number" || value.costUsd === null) {
|
|
2253
|
+
pendingStep.costUsd = value.costUsd;
|
|
2254
|
+
}
|
|
2255
|
+
if (typeof value.reasoningMs === "number") pendingStep.reasoningMs = value.reasoningMs;
|
|
2256
|
+
out += flushStep();
|
|
2257
|
+
return out;
|
|
2258
|
+
}
|
|
2259
|
+
out += flushStep();
|
|
2184
2260
|
const meta = (runId, thread) => {
|
|
2185
2261
|
if (metaSent) return;
|
|
2186
2262
|
metaSent = true;
|
|
@@ -2210,9 +2286,24 @@ data: ${JSON.stringify({
|
|
|
2210
2286
|
frame({ kind: "title", title: value.title });
|
|
2211
2287
|
} else if (event.name === "agora.queue") frame({ kind: "queue", ...value });
|
|
2212
2288
|
else if (event.name === "agora.approval-requested") {
|
|
2289
|
+
if (typeof value.id === "string") shown.add(value.id);
|
|
2213
2290
|
frame({ ...value, kind: "approval-requested" });
|
|
2214
2291
|
} else if (event.name === "agora.approval-settled") {
|
|
2215
2292
|
frame({ ...value, kind: "approval-settled" });
|
|
2293
|
+
} else if (event.name === "agora.elicitation" && typeof value.id === "string" && isRecord2(value.request) && Array.isArray(value.request.questions)) {
|
|
2294
|
+
shown.add(value.id);
|
|
2295
|
+
if (typeof value.request.id === "string") shown.add(value.request.id);
|
|
2296
|
+
frame({
|
|
2297
|
+
kind: "elicitation",
|
|
2298
|
+
id: value.id,
|
|
2299
|
+
request: value.request
|
|
2300
|
+
});
|
|
2301
|
+
} else if (event.name === "agora.action-proposal-decision") {
|
|
2302
|
+
decision = {
|
|
2303
|
+
threadId: value.threadId,
|
|
2304
|
+
proposalDecision: value.proposalDecision,
|
|
2305
|
+
text: ""
|
|
2306
|
+
};
|
|
2216
2307
|
}
|
|
2217
2308
|
return out;
|
|
2218
2309
|
}
|
|
@@ -2222,6 +2313,9 @@ data: ${JSON.stringify({
|
|
|
2222
2313
|
switch (event.type) {
|
|
2223
2314
|
case "TEXT_MESSAGE_CONTENT":
|
|
2224
2315
|
case "TEXT_MESSAGE_CHUNK":
|
|
2316
|
+
if (decision !== void 0 && typeof event.delta === "string") {
|
|
2317
|
+
decision.text += event.delta;
|
|
2318
|
+
}
|
|
2225
2319
|
if (typeof event.delta === "string" && event.delta.length > 0) {
|
|
2226
2320
|
frame({ kind: "text", text: event.delta });
|
|
2227
2321
|
}
|
|
@@ -2236,20 +2330,34 @@ data: ${JSON.stringify({
|
|
|
2236
2330
|
frame({ kind: "step-start" });
|
|
2237
2331
|
break;
|
|
2238
2332
|
case "STEP_FINISHED":
|
|
2239
|
-
|
|
2333
|
+
pendingStep = { kind: "step-finish" };
|
|
2240
2334
|
break;
|
|
2241
2335
|
case "TOOL_CALL_START":
|
|
2242
2336
|
case "TOOL_CALL_CHUNK": {
|
|
2243
|
-
const
|
|
2244
|
-
if (
|
|
2245
|
-
if (!tools.has(
|
|
2337
|
+
const id2 = String(event.toolCallId ?? "");
|
|
2338
|
+
if (id2 === "") break;
|
|
2339
|
+
if (!tools.has(id2)) {
|
|
2246
2340
|
const name = typeof event.toolCallName === "string" ? event.toolCallName : "";
|
|
2247
|
-
|
|
2248
|
-
|
|
2341
|
+
const metadata = isRecord2(event.metadata) ? event.metadata : {};
|
|
2342
|
+
const toolKind2 = metadata["agora.toolKind"] === "action" ? "action" : "read";
|
|
2343
|
+
const parentId = typeof metadata["agora.parentId"] === "string" ? metadata["agora.parentId"] : void 0;
|
|
2344
|
+
tools.set(id2, {
|
|
2345
|
+
name,
|
|
2346
|
+
args: "",
|
|
2347
|
+
toolKind: toolKind2,
|
|
2348
|
+
...parentId !== void 0 ? { parentId } : {}
|
|
2349
|
+
});
|
|
2350
|
+
frame({
|
|
2351
|
+
kind: "tool-input-start",
|
|
2352
|
+
id: id2,
|
|
2353
|
+
name,
|
|
2354
|
+
toolKind: toolKind2,
|
|
2355
|
+
...parentId !== void 0 ? { parentId } : {}
|
|
2356
|
+
});
|
|
2249
2357
|
}
|
|
2250
2358
|
if (event.type === "TOOL_CALL_CHUNK" && typeof event.delta === "string") {
|
|
2251
|
-
tools.get(
|
|
2252
|
-
frame({ kind: "tool-input-delta", id, delta: event.delta });
|
|
2359
|
+
tools.get(id2).args += event.delta;
|
|
2360
|
+
frame({ kind: "tool-input-delta", id: id2, delta: event.delta });
|
|
2253
2361
|
}
|
|
2254
2362
|
break;
|
|
2255
2363
|
}
|
|
@@ -2261,25 +2369,26 @@ data: ${JSON.stringify({
|
|
|
2261
2369
|
break;
|
|
2262
2370
|
}
|
|
2263
2371
|
case "TOOL_CALL_END": {
|
|
2264
|
-
const
|
|
2265
|
-
const call = tools.get(
|
|
2372
|
+
const id2 = String(event.toolCallId);
|
|
2373
|
+
const call = tools.get(id2);
|
|
2266
2374
|
if (call === void 0) break;
|
|
2267
2375
|
frame({
|
|
2268
2376
|
kind: "tool-input-available",
|
|
2269
|
-
id,
|
|
2377
|
+
id: id2,
|
|
2270
2378
|
name: call.name,
|
|
2271
2379
|
input: parseJson(call.args, {}),
|
|
2272
|
-
toolKind:
|
|
2380
|
+
toolKind: call.toolKind,
|
|
2381
|
+
...call.parentId !== void 0 ? { parentId: call.parentId } : {}
|
|
2273
2382
|
});
|
|
2274
2383
|
break;
|
|
2275
2384
|
}
|
|
2276
2385
|
case "TOOL_CALL_RESULT": {
|
|
2277
|
-
const
|
|
2386
|
+
const id2 = String(event.toolCallId);
|
|
2278
2387
|
const content = contentText(event.content);
|
|
2279
2388
|
const outcome = isRecord2(event.metadata) ? event.metadata["agora.outcome"] : void 0;
|
|
2280
|
-
if (outcome === "error") frame({ kind: "tool-output-error", id, error: content });
|
|
2281
|
-
else if (outcome === "denied") frame({ kind: "tool-output-denied", id, reason: content });
|
|
2282
|
-
else frame({ kind: "tool-output", id, output: parseJson(content, content) });
|
|
2389
|
+
if (outcome === "error") frame({ kind: "tool-output-error", id: id2, error: content });
|
|
2390
|
+
else if (outcome === "denied") frame({ kind: "tool-output-denied", id: id2, reason: content });
|
|
2391
|
+
else frame({ kind: "tool-output", id: id2, output: parseJson(content, content) });
|
|
2283
2392
|
break;
|
|
2284
2393
|
}
|
|
2285
2394
|
case "ACTIVITY_SNAPSHOT":
|
|
@@ -2318,15 +2427,26 @@ data: ${JSON.stringify({
|
|
|
2318
2427
|
break;
|
|
2319
2428
|
case "RUN_FINISHED": {
|
|
2320
2429
|
const outcome = isRecord2(event.outcome) ? event.outcome : void 0;
|
|
2430
|
+
if (decision !== void 0) {
|
|
2431
|
+
frame({ kind: "proposal-decision", ...decision });
|
|
2432
|
+
decision = void 0;
|
|
2433
|
+
}
|
|
2321
2434
|
if (outcome?.type === "cancelled") frame({ kind: "cancelled" });
|
|
2322
2435
|
if (outcome?.type === "interrupt" && Array.isArray(outcome.interrupts)) {
|
|
2436
|
+
const unseen = outcome.interrupts.filter((interrupt) => !isShown(interrupt, shown));
|
|
2437
|
+
if (unseen.length === 0) {
|
|
2438
|
+
out += cursor();
|
|
2439
|
+
state.closed = true;
|
|
2440
|
+
break;
|
|
2441
|
+
}
|
|
2323
2442
|
frame({
|
|
2324
2443
|
kind: "ui",
|
|
2325
2444
|
id: `ag-ui:interrupt:${String(event.runId ?? "")}`,
|
|
2326
2445
|
component: "AgUiInterrupt",
|
|
2327
|
-
props: { interrupts:
|
|
2446
|
+
props: { interrupts: unseen }
|
|
2328
2447
|
});
|
|
2329
2448
|
}
|
|
2449
|
+
out += cursor();
|
|
2330
2450
|
state.closed = true;
|
|
2331
2451
|
out += "event: done\ndata: {}\n\n";
|
|
2332
2452
|
break;
|
|
@@ -2346,6 +2466,13 @@ data: ${JSON.stringify({
|
|
|
2346
2466
|
let pendingStart;
|
|
2347
2467
|
return state;
|
|
2348
2468
|
}
|
|
2469
|
+
function isShown(interrupt, shown) {
|
|
2470
|
+
if (!isRecord2(interrupt)) return false;
|
|
2471
|
+
if (typeof interrupt.toolCallId === "string" && shown.has(interrupt.toolCallId)) return true;
|
|
2472
|
+
const metadata = isRecord2(interrupt.metadata) ? interrupt.metadata : void 0;
|
|
2473
|
+
const request = isRecord2(metadata?.["agora.request"]) ? metadata["agora.request"] : void 0;
|
|
2474
|
+
return typeof request?.id === "string" && shown.has(request.id);
|
|
2475
|
+
}
|
|
2349
2476
|
function parseJson(text, fallback2) {
|
|
2350
2477
|
if (text.trim().length === 0) return fallback2;
|
|
2351
2478
|
try {
|