veryfront 0.1.199 → 0.1.201
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/esm/cli/commands/knowledge/command.d.ts +13 -0
- package/esm/cli/commands/knowledge/command.d.ts.map +1 -1
- package/esm/cli/commands/knowledge/command.js +52 -19
- package/esm/deno.js +1 -1
- package/esm/src/agent/ag-ui-browser-encoder.d.ts.map +1 -1
- package/esm/src/agent/ag-ui-browser-encoder.js +97 -34
- package/esm/src/agent/runtime/chat-stream-handler.d.ts +1 -0
- package/esm/src/agent/runtime/chat-stream-handler.d.ts.map +1 -1
- package/esm/src/agent/runtime/chat-stream-handler.js +149 -9
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +0 -2
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/cli/commands/knowledge/command.ts +77 -21
- package/src/deno.js +1 -1
- package/src/src/agent/ag-ui-browser-encoder.ts +101 -31
- package/src/src/agent/runtime/chat-stream-handler.ts +172 -9
- package/src/src/agent/runtime/index.ts +0 -3
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -299,12 +299,10 @@ export class AgentRuntime {
|
|
|
299
299
|
model: effectiveModel,
|
|
300
300
|
},
|
|
301
301
|
});
|
|
302
|
-
sendSSE(controller, encoder, { type: "text-start", id: textPartId });
|
|
303
302
|
const response = await this.executeAgentLoopStreaming(systemPrompt, memoryMessages, controller, encoder, callbacks, textPartId, toolContext, context, resolvedModelString, languageModel, transport.headers, transport.providerOptions, maxOutputTokensOverride, streamAbortSignal);
|
|
304
303
|
throwIfAborted(streamAbortSignal);
|
|
305
304
|
callbacks?.onFinish?.(response);
|
|
306
305
|
throwIfAborted(streamAbortSignal);
|
|
307
|
-
sendSSE(controller, encoder, { type: "text-end", id: textPartId });
|
|
308
306
|
sendSSE(controller, encoder, { type: "message-finish" });
|
|
309
307
|
closeSSEStream(controller);
|
|
310
308
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.201";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
type SafeParseResult<T> = { success: true; data: T } | { success: false; error: z.ZodError };
|
|
4
4
|
import { createFileSystem, getEnv } from "../../../src/platform/index.js";
|
|
5
5
|
import { basename, extname, join, normalize, relative } from "../../../src/platform/compat/path/index.js";
|
|
6
|
+
import { type CommandResult, runCommand } from "../../../src/platform/compat/process.js";
|
|
6
7
|
import { withSpan } from "../../../src/observability/tracing/otlp-setup.js";
|
|
7
8
|
import { cliLogger } from "../../utils/index.js";
|
|
8
9
|
import { type ApiClient, createApiClient, resolveConfigWithAuth } from "../../shared/config.js";
|
|
@@ -485,6 +486,76 @@ export async function runKnowledgeParser(input: {
|
|
|
485
486
|
return result;
|
|
486
487
|
}
|
|
487
488
|
|
|
489
|
+
function isMissingPythonExecutableError(error: unknown): boolean {
|
|
490
|
+
if (!(error instanceof Error)) {
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const errorWithCode = error as Error & { code?: unknown };
|
|
495
|
+
if (errorWithCode.code === "ENOENT") {
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return error.name === "NotFound" ||
|
|
500
|
+
/\bENOENT\b/i.test(error.message) ||
|
|
501
|
+
/not found/i.test(error.message) ||
|
|
502
|
+
/no such file or directory/i.test(error.message);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
export async function executeKnowledgeParserCommand(input: {
|
|
506
|
+
scriptPath: string;
|
|
507
|
+
inputJsonPath: string;
|
|
508
|
+
outputJsonPath: string;
|
|
509
|
+
env?: Record<string, string>;
|
|
510
|
+
}, deps: {
|
|
511
|
+
runCommandFn?: (
|
|
512
|
+
cmd: string,
|
|
513
|
+
options: {
|
|
514
|
+
args: string[];
|
|
515
|
+
env?: Record<string, string>;
|
|
516
|
+
capture: true;
|
|
517
|
+
},
|
|
518
|
+
) => Promise<CommandResult>;
|
|
519
|
+
} = {}): Promise<void> {
|
|
520
|
+
const runCommandFn = deps.runCommandFn ?? runCommand;
|
|
521
|
+
let result: CommandResult;
|
|
522
|
+
try {
|
|
523
|
+
result = await runCommandFn("python3", {
|
|
524
|
+
args: [
|
|
525
|
+
input.scriptPath,
|
|
526
|
+
"--input-json",
|
|
527
|
+
input.inputJsonPath,
|
|
528
|
+
"--output-json",
|
|
529
|
+
input.outputJsonPath,
|
|
530
|
+
],
|
|
531
|
+
...(input.env ? { env: input.env } : {}),
|
|
532
|
+
capture: true,
|
|
533
|
+
});
|
|
534
|
+
} catch (error) {
|
|
535
|
+
if (isMissingPythonExecutableError(error)) {
|
|
536
|
+
throw new Error(
|
|
537
|
+
"python3 is required. Install python3 and the supported parser packages, or run the command inside the Veryfront sandbox.",
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
throw error;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (result.success) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const stderr = result.stderr?.trim();
|
|
548
|
+
const stdout = result.stdout?.trim();
|
|
549
|
+
|
|
550
|
+
if (result.code === 1 && !stderr && !stdout) {
|
|
551
|
+
throw new Error(
|
|
552
|
+
"python3 is required. Install python3 and the supported parser packages, or run the command inside the Veryfront sandbox.",
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
throw new Error(stderr || stdout || "parser exited unsuccessfully");
|
|
557
|
+
}
|
|
558
|
+
|
|
488
559
|
export async function runKnowledgeParsers(input: {
|
|
489
560
|
files: KnowledgeParserInput[];
|
|
490
561
|
outputDir: string;
|
|
@@ -515,27 +586,12 @@ export async function runKnowledgeParsers(input: {
|
|
|
515
586
|
);
|
|
516
587
|
await dntShim.Deno.writeTextFile(scriptPath, knowledgeIngestPythonSource);
|
|
517
588
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
stderr: "piped",
|
|
525
|
-
}).output();
|
|
526
|
-
} catch (error) {
|
|
527
|
-
if (error instanceof dntShim.Deno.errors.NotFound) {
|
|
528
|
-
throw new Error(
|
|
529
|
-
"python3 is required. Install python3 and the supported parser packages, or run the command inside the Veryfront sandbox.",
|
|
530
|
-
);
|
|
531
|
-
}
|
|
532
|
-
throw error;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
if (result.code !== 0) {
|
|
536
|
-
const stderr = new TextDecoder().decode(result.stderr).trim();
|
|
537
|
-
throw new Error(stderr || "parser exited unsuccessfully");
|
|
538
|
-
}
|
|
589
|
+
await executeKnowledgeParserCommand({
|
|
590
|
+
scriptPath,
|
|
591
|
+
inputJsonPath,
|
|
592
|
+
outputJsonPath,
|
|
593
|
+
env: input.env,
|
|
594
|
+
});
|
|
539
595
|
|
|
540
596
|
const raw = await dntShim.Deno.readTextFile(outputJsonPath);
|
|
541
597
|
const parsed = JSON.parse(raw) as KnowledgeParserResult | KnowledgeParserResult[];
|
package/src/deno.js
CHANGED
|
@@ -234,6 +234,28 @@ function createTextEvent(
|
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
function closeOpenTextEvent(state: AgUiBrowserEncoderState): AgUiBrowserEncodedEvent[] {
|
|
238
|
+
if (!state.textOpen) {
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
state.textOpen = false;
|
|
243
|
+
return [createTextEvent(getMessageId(state, { type: "text-end" }), "TextMessageEnd")];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function closeOpenReasoningEvent(state: AgUiBrowserEncoderState): AgUiBrowserEncodedEvent[] {
|
|
247
|
+
if (state.reasoningMessageId === null) {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const messageId = state.reasoningMessageId;
|
|
252
|
+
state.reasoningMessageId = null;
|
|
253
|
+
return [{
|
|
254
|
+
event: "ReasoningMessageEnd",
|
|
255
|
+
payload: { messageId },
|
|
256
|
+
}];
|
|
257
|
+
}
|
|
258
|
+
|
|
237
259
|
export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
238
260
|
state: AgUiBrowserEncoderState,
|
|
239
261
|
event: AgUiRuntimeStreamEvent,
|
|
@@ -254,33 +276,38 @@ export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
|
254
276
|
return [];
|
|
255
277
|
|
|
256
278
|
case "text-start": {
|
|
279
|
+
const events = closeOpenReasoningEvent(state);
|
|
257
280
|
if (state.textOpen) return [];
|
|
258
281
|
const messageId = getMessageId(state, event);
|
|
259
282
|
state.textOpen = true;
|
|
260
283
|
state.sawVisibleOutput = true;
|
|
261
|
-
|
|
284
|
+
events.push(createTextEvent(messageId, "TextMessageStart"));
|
|
285
|
+
return events;
|
|
262
286
|
}
|
|
263
287
|
|
|
264
288
|
case "text-delta": {
|
|
289
|
+
const events = closeOpenReasoningEvent(state);
|
|
265
290
|
const messageId = getMessageId(state, event);
|
|
266
291
|
state.sawVisibleOutput = true;
|
|
267
292
|
if (!state.textOpen) {
|
|
268
293
|
state.textOpen = true;
|
|
269
|
-
|
|
294
|
+
events.push(
|
|
270
295
|
createTextEvent(messageId, "TextMessageStart"),
|
|
271
296
|
createTextEvent(
|
|
272
297
|
messageId,
|
|
273
298
|
"TextMessageContent",
|
|
274
299
|
typeof event.delta === "string" ? event.delta : "",
|
|
275
300
|
),
|
|
276
|
-
|
|
301
|
+
);
|
|
302
|
+
return events;
|
|
277
303
|
}
|
|
278
304
|
|
|
279
|
-
|
|
305
|
+
events.push(createTextEvent(
|
|
280
306
|
messageId,
|
|
281
307
|
"TextMessageContent",
|
|
282
308
|
typeof event.delta === "string" ? event.delta : "",
|
|
283
|
-
)
|
|
309
|
+
));
|
|
310
|
+
return events;
|
|
284
311
|
}
|
|
285
312
|
|
|
286
313
|
case "text-end": {
|
|
@@ -289,13 +316,23 @@ export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
|
289
316
|
return [createTextEvent(getMessageId(state, event), "TextMessageEnd")];
|
|
290
317
|
}
|
|
291
318
|
|
|
292
|
-
case "reasoning-start":
|
|
319
|
+
case "reasoning-start": {
|
|
320
|
+
const events = closeOpenTextEvent(state);
|
|
321
|
+
events.push(...closeOpenReasoningEvent(state));
|
|
293
322
|
state.sawVisibleOutput = true;
|
|
294
|
-
|
|
323
|
+
events.push(createReasoningEvent(state, event, "ReasoningMessageStart"));
|
|
324
|
+
return events;
|
|
325
|
+
}
|
|
295
326
|
|
|
296
|
-
case "reasoning-delta":
|
|
327
|
+
case "reasoning-delta": {
|
|
328
|
+
const events = closeOpenTextEvent(state);
|
|
297
329
|
state.sawVisibleOutput = true;
|
|
298
|
-
|
|
330
|
+
if (state.reasoningMessageId === null) {
|
|
331
|
+
events.push(createReasoningEvent(state, event, "ReasoningMessageStart"));
|
|
332
|
+
}
|
|
333
|
+
events.push(createReasoningEvent(state, event, "ReasoningMessageContent"));
|
|
334
|
+
return events;
|
|
335
|
+
}
|
|
299
336
|
|
|
300
337
|
case "reasoning-end": {
|
|
301
338
|
const reasoningEvent = createReasoningEvent(state, event, "ReasoningMessageEnd");
|
|
@@ -303,15 +340,21 @@ export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
|
303
340
|
return [reasoningEvent];
|
|
304
341
|
}
|
|
305
342
|
|
|
306
|
-
case "tool-input-start":
|
|
343
|
+
case "tool-input-start": {
|
|
344
|
+
const events = [
|
|
345
|
+
...closeOpenTextEvent(state),
|
|
346
|
+
...closeOpenReasoningEvent(state),
|
|
347
|
+
];
|
|
307
348
|
state.sawVisibleOutput = true;
|
|
308
|
-
|
|
349
|
+
events.push({
|
|
309
350
|
event: "ToolCallStart",
|
|
310
351
|
payload: {
|
|
311
352
|
toolCallId: event.toolCallId,
|
|
312
353
|
toolCallName: event.toolName,
|
|
313
354
|
},
|
|
314
|
-
}
|
|
355
|
+
});
|
|
356
|
+
return events;
|
|
357
|
+
}
|
|
315
358
|
|
|
316
359
|
case "tool-input-delta":
|
|
317
360
|
state.sawVisibleOutput = true;
|
|
@@ -328,12 +371,20 @@ export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
|
328
371
|
|
|
329
372
|
case "tool-input-available": {
|
|
330
373
|
state.sawVisibleOutput = true;
|
|
331
|
-
return
|
|
374
|
+
return [
|
|
375
|
+
...closeOpenTextEvent(state),
|
|
376
|
+
...closeOpenReasoningEvent(state),
|
|
377
|
+
...completeToolInput(state, event),
|
|
378
|
+
];
|
|
332
379
|
}
|
|
333
380
|
|
|
334
381
|
case "tool-input-error": {
|
|
335
382
|
state.sawVisibleOutput = true;
|
|
336
|
-
const events =
|
|
383
|
+
const events = [
|
|
384
|
+
...closeOpenTextEvent(state),
|
|
385
|
+
...closeOpenReasoningEvent(state),
|
|
386
|
+
...completeToolInput(state, event),
|
|
387
|
+
];
|
|
337
388
|
events.push({
|
|
338
389
|
event: "ToolCallResult",
|
|
339
390
|
payload: {
|
|
@@ -349,25 +400,45 @@ export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
|
349
400
|
|
|
350
401
|
case "tool-output-available":
|
|
351
402
|
state.sawVisibleOutput = true;
|
|
352
|
-
return [
|
|
403
|
+
return [
|
|
404
|
+
...closeOpenTextEvent(state),
|
|
405
|
+
...closeOpenReasoningEvent(state),
|
|
406
|
+
createToolResultEvent(event.toolCallId, event.output),
|
|
407
|
+
];
|
|
353
408
|
|
|
354
409
|
case "tool-output-error":
|
|
355
410
|
state.sawVisibleOutput = true;
|
|
356
|
-
return [
|
|
411
|
+
return [
|
|
412
|
+
...closeOpenTextEvent(state),
|
|
413
|
+
...closeOpenReasoningEvent(state),
|
|
414
|
+
createToolResultEvent(event.toolCallId, { error: event.errorText }, true),
|
|
415
|
+
];
|
|
357
416
|
|
|
358
417
|
case "tool-output-denied":
|
|
359
418
|
state.sawVisibleOutput = true;
|
|
360
|
-
return [
|
|
419
|
+
return [
|
|
420
|
+
...closeOpenTextEvent(state),
|
|
421
|
+
...closeOpenReasoningEvent(state),
|
|
422
|
+
createToolResultEvent(event.toolCallId, { error: "Tool output denied" }, true),
|
|
423
|
+
];
|
|
361
424
|
|
|
362
425
|
case "step-start":
|
|
363
426
|
case "start-step":
|
|
364
427
|
state.sawVisibleOutput = true;
|
|
365
|
-
return [
|
|
428
|
+
return [
|
|
429
|
+
...closeOpenTextEvent(state),
|
|
430
|
+
...closeOpenReasoningEvent(state),
|
|
431
|
+
createStepEvent(state, "StepStarted"),
|
|
432
|
+
];
|
|
366
433
|
|
|
367
434
|
case "step-end":
|
|
368
435
|
case "finish-step":
|
|
369
436
|
state.sawVisibleOutput = true;
|
|
370
|
-
return [
|
|
437
|
+
return [
|
|
438
|
+
...closeOpenTextEvent(state),
|
|
439
|
+
...closeOpenReasoningEvent(state),
|
|
440
|
+
createStepEvent(state, "StepFinished"),
|
|
441
|
+
];
|
|
371
442
|
|
|
372
443
|
case "data":
|
|
373
444
|
applyDataMetadata(state, event);
|
|
@@ -375,12 +446,16 @@ export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
|
375
446
|
|
|
376
447
|
case "error":
|
|
377
448
|
state.sawTerminalError = true;
|
|
378
|
-
return [
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
449
|
+
return [
|
|
450
|
+
...closeOpenTextEvent(state),
|
|
451
|
+
...closeOpenReasoningEvent(state),
|
|
452
|
+
{
|
|
453
|
+
event: "RunError",
|
|
454
|
+
payload: {
|
|
455
|
+
message: typeof event.error === "string" ? event.error : "Agent run failed",
|
|
456
|
+
},
|
|
382
457
|
},
|
|
383
|
-
|
|
458
|
+
];
|
|
384
459
|
|
|
385
460
|
default:
|
|
386
461
|
return [];
|
|
@@ -409,13 +484,8 @@ export function finalizeAgUiBrowserEvents(
|
|
|
409
484
|
}
|
|
410
485
|
|
|
411
486
|
const events: AgUiBrowserEncodedEvent[] = [];
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
events.push({
|
|
415
|
-
event: "TextMessageEnd",
|
|
416
|
-
payload: { messageId: getMessageId(state, { type: "text-end" }) },
|
|
417
|
-
});
|
|
418
|
-
}
|
|
487
|
+
events.push(...closeOpenTextEvent(state));
|
|
488
|
+
events.push(...closeOpenReasoningEvent(state));
|
|
419
489
|
|
|
420
490
|
events.push({
|
|
421
491
|
event: "RunFinished",
|
|
@@ -24,6 +24,7 @@ export interface StreamingToolCall {
|
|
|
24
24
|
id: string;
|
|
25
25
|
name: string;
|
|
26
26
|
arguments: string;
|
|
27
|
+
inputAvailable?: boolean;
|
|
27
28
|
providerExecuted?: boolean;
|
|
28
29
|
dynamic?: boolean;
|
|
29
30
|
}
|
|
@@ -157,6 +158,136 @@ export function processStream(
|
|
|
157
158
|
): Promise<void> {
|
|
158
159
|
return withSpan("agent.runtime.processStream", async () => {
|
|
159
160
|
let eventCount = 0;
|
|
161
|
+
let textOpen = false;
|
|
162
|
+
let activeReasoningId: string | null = null;
|
|
163
|
+
|
|
164
|
+
const normalizeReasoningId = (part: { id?: string }) =>
|
|
165
|
+
typeof part.id === "string" && part.id.length > 0 ? part.id : "reasoning";
|
|
166
|
+
|
|
167
|
+
const openTextSegment = () => {
|
|
168
|
+
if (textOpen) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
textOpen = true;
|
|
173
|
+
sendSSE(controller, encoder, {
|
|
174
|
+
type: "text-start",
|
|
175
|
+
id: textPartId,
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const closeTextSegment = () => {
|
|
180
|
+
if (!textOpen) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
textOpen = false;
|
|
185
|
+
sendSSE(controller, encoder, {
|
|
186
|
+
type: "text-end",
|
|
187
|
+
id: textPartId,
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const openReasoningSegment = (reasoningId: string) => {
|
|
192
|
+
if (activeReasoningId === reasoningId) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (activeReasoningId !== null) {
|
|
197
|
+
sendSSE(controller, encoder, {
|
|
198
|
+
type: "reasoning-end",
|
|
199
|
+
id: activeReasoningId,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
activeReasoningId = reasoningId;
|
|
204
|
+
sendSSE(controller, encoder, {
|
|
205
|
+
type: "reasoning-start",
|
|
206
|
+
id: reasoningId,
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const closeReasoningSegment = () => {
|
|
211
|
+
if (activeReasoningId === null) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
sendSSE(controller, encoder, {
|
|
216
|
+
type: "reasoning-end",
|
|
217
|
+
id: activeReasoningId,
|
|
218
|
+
});
|
|
219
|
+
activeReasoningId = null;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const ensureToolLifecycle = (part: {
|
|
223
|
+
toolCallId: string;
|
|
224
|
+
toolName: string;
|
|
225
|
+
input?: unknown;
|
|
226
|
+
providerExecuted?: boolean;
|
|
227
|
+
dynamic?: boolean;
|
|
228
|
+
}) => {
|
|
229
|
+
const dynamic = part.dynamic ?? isDynamicTool(part.toolName);
|
|
230
|
+
const existing = state.toolCalls.get(part.toolCallId);
|
|
231
|
+
|
|
232
|
+
if (!existing) {
|
|
233
|
+
const normalizedInput = parseToolInputObject(part.input);
|
|
234
|
+
state.toolCalls.set(part.toolCallId, {
|
|
235
|
+
id: part.toolCallId,
|
|
236
|
+
name: part.toolName,
|
|
237
|
+
arguments: normalizeToolInputString(part.input),
|
|
238
|
+
inputAvailable: true,
|
|
239
|
+
...(part.providerExecuted !== undefined
|
|
240
|
+
? { providerExecuted: part.providerExecuted }
|
|
241
|
+
: {}),
|
|
242
|
+
...(dynamic ? { dynamic: true } : {}),
|
|
243
|
+
});
|
|
244
|
+
sendSSE(controller, encoder, {
|
|
245
|
+
type: "tool-input-start",
|
|
246
|
+
toolCallId: part.toolCallId,
|
|
247
|
+
toolName: part.toolName,
|
|
248
|
+
...(dynamic ? { dynamic: true } : {}),
|
|
249
|
+
});
|
|
250
|
+
sendSSE(controller, encoder, {
|
|
251
|
+
type: "tool-input-available",
|
|
252
|
+
toolCallId: part.toolCallId,
|
|
253
|
+
toolName: part.toolName,
|
|
254
|
+
input: normalizedInput,
|
|
255
|
+
...(part.providerExecuted !== undefined
|
|
256
|
+
? { providerExecuted: part.providerExecuted }
|
|
257
|
+
: {}),
|
|
258
|
+
...(dynamic ? { dynamic: true } : {}),
|
|
259
|
+
});
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (existing.inputAvailable) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const resolvedArguments = part.input !== undefined
|
|
268
|
+
? mergeToolCallInput(existing.arguments, normalizeToolInputString(part.input))
|
|
269
|
+
: existing.arguments;
|
|
270
|
+
const resolvedInput = parseToolInputObject(resolvedArguments);
|
|
271
|
+
existing.arguments = resolvedArguments;
|
|
272
|
+
existing.inputAvailable = true;
|
|
273
|
+
if (part.providerExecuted !== undefined) {
|
|
274
|
+
existing.providerExecuted = part.providerExecuted;
|
|
275
|
+
}
|
|
276
|
+
if (dynamic) {
|
|
277
|
+
existing.dynamic = true;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
sendSSE(controller, encoder, {
|
|
281
|
+
type: "tool-input-available",
|
|
282
|
+
toolCallId: part.toolCallId,
|
|
283
|
+
toolName: existing.name,
|
|
284
|
+
input: resolvedInput,
|
|
285
|
+
...(existing.providerExecuted !== undefined
|
|
286
|
+
? { providerExecuted: existing.providerExecuted }
|
|
287
|
+
: {}),
|
|
288
|
+
...(existing.dynamic ? { dynamic: true } : {}),
|
|
289
|
+
});
|
|
290
|
+
};
|
|
160
291
|
|
|
161
292
|
throwIfAborted(abortSignal);
|
|
162
293
|
|
|
@@ -172,6 +303,8 @@ export function processStream(
|
|
|
172
303
|
|
|
173
304
|
switch (typedPart.type) {
|
|
174
305
|
case "text-delta": {
|
|
306
|
+
closeReasoningSegment();
|
|
307
|
+
openTextSegment();
|
|
175
308
|
state.accumulatedText += typedPart.text;
|
|
176
309
|
sendSSE(controller, encoder, {
|
|
177
310
|
type: "text-delta",
|
|
@@ -183,36 +316,40 @@ export function processStream(
|
|
|
183
316
|
}
|
|
184
317
|
|
|
185
318
|
case "reasoning-start": {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
id: typeof typedPart.id === "string" ? typedPart.id : "reasoning",
|
|
189
|
-
});
|
|
319
|
+
closeTextSegment();
|
|
320
|
+
openReasoningSegment(normalizeReasoningId(typedPart));
|
|
190
321
|
break;
|
|
191
322
|
}
|
|
192
323
|
|
|
193
324
|
case "reasoning-delta": {
|
|
325
|
+
closeTextSegment();
|
|
326
|
+
openReasoningSegment(normalizeReasoningId(typedPart));
|
|
194
327
|
sendSSE(controller, encoder, {
|
|
195
328
|
type: "reasoning-delta",
|
|
196
|
-
id:
|
|
329
|
+
id: normalizeReasoningId(typedPart),
|
|
197
330
|
delta: typeof typedPart.delta === "string" ? typedPart.delta : "",
|
|
198
331
|
});
|
|
199
332
|
break;
|
|
200
333
|
}
|
|
201
334
|
|
|
202
335
|
case "reasoning-end": {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
336
|
+
closeTextSegment();
|
|
337
|
+
if (activeReasoningId === null) {
|
|
338
|
+
activeReasoningId = normalizeReasoningId(typedPart);
|
|
339
|
+
}
|
|
340
|
+
closeReasoningSegment();
|
|
207
341
|
break;
|
|
208
342
|
}
|
|
209
343
|
|
|
210
344
|
case "tool-input-start": {
|
|
345
|
+
closeTextSegment();
|
|
346
|
+
closeReasoningSegment();
|
|
211
347
|
const toolId = typedPart.id;
|
|
212
348
|
state.toolCalls.set(toolId, {
|
|
213
349
|
id: toolId,
|
|
214
350
|
name: typedPart.toolName,
|
|
215
351
|
arguments: "",
|
|
352
|
+
inputAvailable: false,
|
|
216
353
|
providerExecuted: typedPart.providerExecuted,
|
|
217
354
|
dynamic: typedPart.dynamic,
|
|
218
355
|
});
|
|
@@ -228,6 +365,7 @@ export function processStream(
|
|
|
228
365
|
}
|
|
229
366
|
|
|
230
367
|
case "tool-input-delta": {
|
|
368
|
+
closeReasoningSegment();
|
|
231
369
|
const toolId = typedPart.id;
|
|
232
370
|
const tc = state.toolCalls.get(toolId);
|
|
233
371
|
if (!tc) break;
|
|
@@ -242,6 +380,8 @@ export function processStream(
|
|
|
242
380
|
}
|
|
243
381
|
|
|
244
382
|
case "tool-call": {
|
|
383
|
+
closeTextSegment();
|
|
384
|
+
closeReasoningSegment();
|
|
245
385
|
// tool-call fires when the full tool call is available
|
|
246
386
|
const toolId = typedPart.toolCallId;
|
|
247
387
|
const inputStr = normalizeToolInputString(typedPart.input);
|
|
@@ -251,6 +391,7 @@ export function processStream(
|
|
|
251
391
|
id: toolId,
|
|
252
392
|
name: typedPart.toolName,
|
|
253
393
|
arguments: resolvedArguments,
|
|
394
|
+
inputAvailable: true,
|
|
254
395
|
providerExecuted: typedPart.providerExecuted,
|
|
255
396
|
dynamic: typedPart.dynamic,
|
|
256
397
|
});
|
|
@@ -271,6 +412,15 @@ export function processStream(
|
|
|
271
412
|
}
|
|
272
413
|
|
|
273
414
|
case "tool-result": {
|
|
415
|
+
closeTextSegment();
|
|
416
|
+
closeReasoningSegment();
|
|
417
|
+
ensureToolLifecycle({
|
|
418
|
+
toolCallId: typedPart.toolCallId,
|
|
419
|
+
toolName: typedPart.toolName,
|
|
420
|
+
input: typedPart.input,
|
|
421
|
+
providerExecuted: typedPart.providerExecuted,
|
|
422
|
+
dynamic: typedPart.dynamic,
|
|
423
|
+
});
|
|
274
424
|
const isError = typedPart.isError === true;
|
|
275
425
|
logProviderToolPart("tool-result", {
|
|
276
426
|
toolCallId: typedPart.toolCallId,
|
|
@@ -328,6 +478,15 @@ export function processStream(
|
|
|
328
478
|
}
|
|
329
479
|
|
|
330
480
|
case "tool-error": {
|
|
481
|
+
closeTextSegment();
|
|
482
|
+
closeReasoningSegment();
|
|
483
|
+
ensureToolLifecycle({
|
|
484
|
+
toolCallId: typedPart.toolCallId,
|
|
485
|
+
toolName: typedPart.toolName,
|
|
486
|
+
input: typedPart.input,
|
|
487
|
+
providerExecuted: typedPart.providerExecuted,
|
|
488
|
+
dynamic: typedPart.dynamic,
|
|
489
|
+
});
|
|
331
490
|
logProviderToolPart("tool-error", {
|
|
332
491
|
toolCallId: typedPart.toolCallId,
|
|
333
492
|
toolName: typedPart.toolName,
|
|
@@ -358,6 +517,8 @@ export function processStream(
|
|
|
358
517
|
}
|
|
359
518
|
|
|
360
519
|
case "finish": {
|
|
520
|
+
closeTextSegment();
|
|
521
|
+
closeReasoningSegment();
|
|
361
522
|
state.finishReason = typedPart.finishReason ?? null;
|
|
362
523
|
if (typedPart.totalUsage) {
|
|
363
524
|
const input = typedPart.totalUsage.inputTokens ?? 0;
|
|
@@ -373,6 +534,8 @@ export function processStream(
|
|
|
373
534
|
}
|
|
374
535
|
|
|
375
536
|
case "error": {
|
|
537
|
+
closeTextSegment();
|
|
538
|
+
closeReasoningSegment();
|
|
376
539
|
logger.warn("Runtime stream error:", typedPart.error);
|
|
377
540
|
sendSSE(controller, encoder, {
|
|
378
541
|
type: "error",
|
|
@@ -488,8 +488,6 @@ export class AgentRuntime {
|
|
|
488
488
|
model: effectiveModel,
|
|
489
489
|
},
|
|
490
490
|
});
|
|
491
|
-
sendSSE(controller, encoder, { type: "text-start", id: textPartId });
|
|
492
|
-
|
|
493
491
|
const response = await this.executeAgentLoopStreaming(
|
|
494
492
|
systemPrompt,
|
|
495
493
|
memoryMessages,
|
|
@@ -510,7 +508,6 @@ export class AgentRuntime {
|
|
|
510
508
|
callbacks?.onFinish?.(response);
|
|
511
509
|
throwIfAborted(streamAbortSignal);
|
|
512
510
|
|
|
513
|
-
sendSSE(controller, encoder, { type: "text-end", id: textPartId });
|
|
514
511
|
sendSSE(controller, encoder, { type: "message-finish" });
|
|
515
512
|
closeSSEStream(controller);
|
|
516
513
|
} catch (error) {
|