@dudousxd/nestjs-agent-react 0.3.2 → 0.3.3
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 +147 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -5
- package/dist/index.d.ts +24 -5
- package/dist/index.js +147 -31
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -147,18 +147,26 @@ var AgentChatTransport = class {
|
|
|
147
147
|
this.options.onMeta?.(meta);
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
150
|
-
* Parse the backend's SSE byte stream and
|
|
151
|
-
*
|
|
152
|
-
* - `event: meta` `data: {"runId","threadId"}`
|
|
153
|
-
* - `data:
|
|
154
|
-
* - `event: done` `data: {}`
|
|
150
|
+
* Parse the backend's SSE byte stream and re-emit it as a valid v7 UI-message chunk stream.
|
|
151
|
+
* Recognized frames:
|
|
152
|
+
* - `event: meta` `data: {"runId","threadId"}` → records identity
|
|
153
|
+
* - `data: <AgentStreamEvent JSON>` → mapped to UI chunks (text / reasoning / tool)
|
|
154
|
+
* - `event: done` `data: {}` → terminates
|
|
155
|
+
* - `event: error` `data: {code,message}` → error chunk
|
|
156
|
+
*
|
|
157
|
+
* A run is ONE UI message with N steps. Each `step-start`/`step-finish` pair brackets a model
|
|
158
|
+
* call plus its tool execution; text and reasoning open lazily and close at the step boundary, so
|
|
159
|
+
* tool-call cards (input streaming → output) render live between the prose.
|
|
155
160
|
*/
|
|
156
161
|
toChunkStream(source) {
|
|
157
162
|
const reader = source.getReader();
|
|
158
163
|
const decoder = new TextDecoder();
|
|
159
|
-
const textId = `txt-${Math.random().toString(36).slice(2)}`;
|
|
160
164
|
let buffer = "";
|
|
161
165
|
let started = false;
|
|
166
|
+
let stepOpen = false;
|
|
167
|
+
let stepIndex = 0;
|
|
168
|
+
let textId = null;
|
|
169
|
+
let reasoningId = null;
|
|
162
170
|
const record = /* @__PURE__ */ __name((meta) => this.recordMeta(meta), "record");
|
|
163
171
|
return new ReadableStream({
|
|
164
172
|
async pull(controller) {
|
|
@@ -168,24 +176,133 @@ var AgentChatTransport = class {
|
|
|
168
176
|
controller.enqueue({
|
|
169
177
|
type: "start"
|
|
170
178
|
});
|
|
171
|
-
controller.enqueue({
|
|
172
|
-
type: "start-step"
|
|
173
|
-
});
|
|
174
|
-
controller.enqueue({
|
|
175
|
-
type: "text-start",
|
|
176
|
-
id: textId
|
|
177
|
-
});
|
|
178
179
|
}
|
|
179
180
|
__name(ensureStarted, "ensureStarted");
|
|
180
|
-
function
|
|
181
|
+
function openStep() {
|
|
181
182
|
ensureStarted();
|
|
183
|
+
if (stepOpen) closeStep();
|
|
184
|
+
stepOpen = true;
|
|
185
|
+
stepIndex += 1;
|
|
186
|
+
textId = null;
|
|
187
|
+
reasoningId = null;
|
|
182
188
|
controller.enqueue({
|
|
183
|
-
type: "
|
|
184
|
-
id: textId
|
|
189
|
+
type: "start-step"
|
|
185
190
|
});
|
|
191
|
+
}
|
|
192
|
+
__name(openStep, "openStep");
|
|
193
|
+
function ensureStep() {
|
|
194
|
+
if (!stepOpen) openStep();
|
|
195
|
+
}
|
|
196
|
+
__name(ensureStep, "ensureStep");
|
|
197
|
+
function closeStep() {
|
|
198
|
+
if (!stepOpen) return;
|
|
199
|
+
if (textId !== null) {
|
|
200
|
+
controller.enqueue({
|
|
201
|
+
type: "text-end",
|
|
202
|
+
id: textId
|
|
203
|
+
});
|
|
204
|
+
textId = null;
|
|
205
|
+
}
|
|
206
|
+
if (reasoningId !== null) {
|
|
207
|
+
controller.enqueue({
|
|
208
|
+
type: "reasoning-end",
|
|
209
|
+
id: reasoningId
|
|
210
|
+
});
|
|
211
|
+
reasoningId = null;
|
|
212
|
+
}
|
|
186
213
|
controller.enqueue({
|
|
187
214
|
type: "finish-step"
|
|
188
215
|
});
|
|
216
|
+
stepOpen = false;
|
|
217
|
+
}
|
|
218
|
+
__name(closeStep, "closeStep");
|
|
219
|
+
function emit(event) {
|
|
220
|
+
switch (event.kind) {
|
|
221
|
+
case "step-start":
|
|
222
|
+
openStep();
|
|
223
|
+
break;
|
|
224
|
+
case "step-finish":
|
|
225
|
+
closeStep();
|
|
226
|
+
break;
|
|
227
|
+
case "text":
|
|
228
|
+
ensureStep();
|
|
229
|
+
if (textId === null) {
|
|
230
|
+
textId = `txt-${stepIndex}`;
|
|
231
|
+
controller.enqueue({
|
|
232
|
+
type: "text-start",
|
|
233
|
+
id: textId
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
controller.enqueue({
|
|
237
|
+
type: "text-delta",
|
|
238
|
+
id: textId,
|
|
239
|
+
delta: event.text
|
|
240
|
+
});
|
|
241
|
+
break;
|
|
242
|
+
case "reasoning":
|
|
243
|
+
ensureStep();
|
|
244
|
+
if (reasoningId === null) {
|
|
245
|
+
reasoningId = `rsn-${stepIndex}`;
|
|
246
|
+
controller.enqueue({
|
|
247
|
+
type: "reasoning-start",
|
|
248
|
+
id: reasoningId
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
controller.enqueue({
|
|
252
|
+
type: "reasoning-delta",
|
|
253
|
+
id: reasoningId,
|
|
254
|
+
delta: event.text
|
|
255
|
+
});
|
|
256
|
+
break;
|
|
257
|
+
case "tool-input-start":
|
|
258
|
+
ensureStep();
|
|
259
|
+
controller.enqueue({
|
|
260
|
+
type: "tool-input-start",
|
|
261
|
+
toolCallId: event.id,
|
|
262
|
+
toolName: event.name
|
|
263
|
+
});
|
|
264
|
+
break;
|
|
265
|
+
case "tool-input-delta":
|
|
266
|
+
ensureStep();
|
|
267
|
+
controller.enqueue({
|
|
268
|
+
type: "tool-input-delta",
|
|
269
|
+
toolCallId: event.id,
|
|
270
|
+
inputTextDelta: event.delta
|
|
271
|
+
});
|
|
272
|
+
break;
|
|
273
|
+
case "tool-input-available":
|
|
274
|
+
ensureStep();
|
|
275
|
+
controller.enqueue({
|
|
276
|
+
type: "tool-input-available",
|
|
277
|
+
toolCallId: event.id,
|
|
278
|
+
toolName: event.name,
|
|
279
|
+
input: event.input
|
|
280
|
+
});
|
|
281
|
+
break;
|
|
282
|
+
case "tool-output":
|
|
283
|
+
ensureStep();
|
|
284
|
+
controller.enqueue({
|
|
285
|
+
type: "tool-output-available",
|
|
286
|
+
toolCallId: event.id,
|
|
287
|
+
output: event.output
|
|
288
|
+
});
|
|
289
|
+
break;
|
|
290
|
+
case "tool-output-error":
|
|
291
|
+
ensureStep();
|
|
292
|
+
controller.enqueue({
|
|
293
|
+
type: "tool-output-error",
|
|
294
|
+
toolCallId: event.id,
|
|
295
|
+
errorText: event.error
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
298
|
+
default:
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
__name(emit, "emit");
|
|
303
|
+
function finish() {
|
|
304
|
+
ensureStarted();
|
|
305
|
+
closeStep();
|
|
189
306
|
controller.enqueue({
|
|
190
307
|
type: "finish"
|
|
191
308
|
});
|
|
@@ -224,15 +341,8 @@ var AgentChatTransport = class {
|
|
|
224
341
|
const meta = parseMeta(frame.data);
|
|
225
342
|
if (meta) record(meta);
|
|
226
343
|
} else if (frame.data) {
|
|
227
|
-
const
|
|
228
|
-
if (
|
|
229
|
-
ensureStarted();
|
|
230
|
-
controller.enqueue({
|
|
231
|
-
type: "text-delta",
|
|
232
|
-
id: textId,
|
|
233
|
-
delta
|
|
234
|
-
});
|
|
235
|
-
}
|
|
344
|
+
const event = parseEvent(frame.data);
|
|
345
|
+
if (event) emit(event);
|
|
236
346
|
}
|
|
237
347
|
separator = buffer.indexOf("\n\n");
|
|
238
348
|
}
|
|
@@ -294,17 +404,17 @@ function parseErrorText(data) {
|
|
|
294
404
|
return "Agent run failed";
|
|
295
405
|
}
|
|
296
406
|
__name(parseErrorText, "parseErrorText");
|
|
297
|
-
function
|
|
407
|
+
function parseEvent(data) {
|
|
298
408
|
try {
|
|
299
409
|
const parsed = JSON.parse(data);
|
|
300
|
-
if (parsed !== null && typeof parsed === "object" && "
|
|
301
|
-
return parsed
|
|
410
|
+
if (parsed !== null && typeof parsed === "object" && "kind" in parsed) {
|
|
411
|
+
return parsed;
|
|
302
412
|
}
|
|
303
413
|
} catch {
|
|
304
414
|
}
|
|
305
415
|
return null;
|
|
306
416
|
}
|
|
307
|
-
__name(
|
|
417
|
+
__name(parseEvent, "parseEvent");
|
|
308
418
|
function extractText(message) {
|
|
309
419
|
let text = "";
|
|
310
420
|
for (const part of message.parts ?? []) {
|
|
@@ -411,6 +521,7 @@ function useAgentChat(options) {
|
|
|
411
521
|
const runIdRef = (0, import_react2.useRef)(runId);
|
|
412
522
|
runIdRef.current = runId;
|
|
413
523
|
const regenerateNext = (0, import_react2.useRef)(false);
|
|
524
|
+
const createdThreadId = (0, import_react2.useRef)(void 0);
|
|
414
525
|
const client = (0, import_react2.useMemo)(() => {
|
|
415
526
|
if (options.client) return options.client;
|
|
416
527
|
return new AgentClient({
|
|
@@ -429,6 +540,10 @@ function useAgentChat(options) {
|
|
|
429
540
|
const transport = (0, import_react2.useMemo)(() => {
|
|
430
541
|
function onMeta(meta) {
|
|
431
542
|
setRunId(meta.runId);
|
|
543
|
+
if (latest.current.threadId === void 0 && meta.threadId && createdThreadId.current !== meta.threadId) {
|
|
544
|
+
createdThreadId.current = meta.threadId;
|
|
545
|
+
latest.current.onThreadCreated?.(meta.threadId);
|
|
546
|
+
}
|
|
432
547
|
}
|
|
433
548
|
__name(onMeta, "onMeta");
|
|
434
549
|
return new AgentChatTransport({
|
|
@@ -450,9 +565,10 @@ function useAgentChat(options) {
|
|
|
450
565
|
const pageContext = current.getPageContext?.() ?? null;
|
|
451
566
|
const regenerate2 = regenerateNext.current;
|
|
452
567
|
regenerateNext.current = false;
|
|
568
|
+
const threadId = current.threadId ?? createdThreadId.current;
|
|
453
569
|
return {
|
|
454
|
-
...
|
|
455
|
-
threadId
|
|
570
|
+
...threadId !== void 0 ? {
|
|
571
|
+
threadId
|
|
456
572
|
} : {},
|
|
457
573
|
...pageContext ? {
|
|
458
574
|
pageContext
|