@vitest-evals/harness-ai-sdk 0.13.1 → 0.14.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 +8 -2
- package/dist/index.js +176 -116
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -119
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -108,8 +108,9 @@ describeEval("refund agent", {
|
|
|
108
108
|
|
|
109
109
|
The adapter infers:
|
|
110
110
|
|
|
111
|
-
- normalized session and tool
|
|
112
|
-
- usage diagnostics from `totalUsage
|
|
111
|
+
- normalized session transcripts and tool calls from AI SDK `steps`
|
|
112
|
+
- usage diagnostics from `totalUsage`, aggregated `steps[].usage`, or
|
|
113
|
+
top-level `usage` for non-step results
|
|
113
114
|
- typed `run.output` from explicit `run()` results that return `output`, from
|
|
114
115
|
common AI SDK provider fields such as `object` and `text`, or from a typed
|
|
115
116
|
`output` selector when the app deliberately returns a raw provider result
|
|
@@ -118,5 +119,10 @@ The adapter infers:
|
|
|
118
119
|
`output` selector
|
|
119
120
|
- replay/cassette metadata for local tools configured with `toolReplay`
|
|
120
121
|
|
|
122
|
+
Successful custom `run` entrypoints that do not return AI SDK `steps` use
|
|
123
|
+
normalized transcript events for local tool executions. Output-only custom runs
|
|
124
|
+
still get synthesized input/output messages; return a normalized `session` when
|
|
125
|
+
evals need exact transcript control beyond that.
|
|
126
|
+
|
|
121
127
|
See the workspace demo app in `apps/demo-ai-sdk` and the RFC notes in
|
|
122
128
|
`docs/harness-first-rfc.md`.
|
package/dist/index.js
CHANGED
|
@@ -112,14 +112,14 @@ function createFailedAiSdkRun(input, context, error, harnessName, startedAt) {
|
|
|
112
112
|
async function runAiSdkHarness(options, agent, input, context) {
|
|
113
113
|
const trace = createTraceRecorder(options.name ?? "ai-sdk");
|
|
114
114
|
const replayMetadataByToolCallId = /* @__PURE__ */ new Map();
|
|
115
|
-
const
|
|
115
|
+
const runtimeEvents = [];
|
|
116
116
|
const tools = createToolset({
|
|
117
117
|
input,
|
|
118
118
|
context,
|
|
119
119
|
tools: options.tools,
|
|
120
120
|
toolReplay: options.toolReplay,
|
|
121
121
|
replayMetadataByToolCallId,
|
|
122
|
-
|
|
122
|
+
runtimeEvents
|
|
123
123
|
});
|
|
124
124
|
const runtime = {
|
|
125
125
|
tools,
|
|
@@ -149,13 +149,20 @@ async function runAiSdkHarness(options, agent, input, context) {
|
|
|
149
149
|
result
|
|
150
150
|
};
|
|
151
151
|
const output = options.output ? await options.output(resultArgs) : resolveOutput(result);
|
|
152
|
-
const
|
|
152
|
+
const explicitSession = getResultSession(result);
|
|
153
|
+
const useRuntimeEvents = shouldUseRuntimeEvents(result);
|
|
154
|
+
const usage = resolveUsage(
|
|
155
|
+
result,
|
|
156
|
+
useRuntimeEvents ? runtimeEvents : [],
|
|
157
|
+
explicitSession
|
|
158
|
+
);
|
|
153
159
|
const session = resolveSession(
|
|
154
160
|
input,
|
|
155
161
|
result,
|
|
156
162
|
output,
|
|
157
163
|
replayMetadataByToolCallId,
|
|
158
|
-
|
|
164
|
+
runtimeEvents,
|
|
165
|
+
explicitSession
|
|
159
166
|
);
|
|
160
167
|
const errors = (0, import_harness.resolveHarnessRunErrors)(result);
|
|
161
168
|
const finishedAt = /* @__PURE__ */ new Date();
|
|
@@ -178,14 +185,11 @@ async function runAiSdkHarness(options, agent, input, context) {
|
|
|
178
185
|
} catch (error) {
|
|
179
186
|
const finishedAt = /* @__PURE__ */ new Date();
|
|
180
187
|
const serializedError = (0, import_harness.serializeError)(error);
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
replayMetadataByToolCallId,
|
|
187
|
-
runtimeToolCalls
|
|
188
|
-
);
|
|
188
|
+
const runtimeToolCallCount = runtimeEvents.filter(
|
|
189
|
+
(event) => event.type === "tool_call"
|
|
190
|
+
).length;
|
|
191
|
+
const usage = runtimeToolCallCount > 0 ? { toolCalls: runtimeToolCallCount } : {};
|
|
192
|
+
const session = resolveFailureSession(input, runtimeEvents);
|
|
189
193
|
const run = {
|
|
190
194
|
session,
|
|
191
195
|
output: void 0,
|
|
@@ -283,11 +287,6 @@ function finishAiSdkTrace(trace, options) {
|
|
|
283
287
|
options.result,
|
|
284
288
|
options.usage
|
|
285
289
|
);
|
|
286
|
-
const toolSpans = (0, import_harness.createToolCallSpans)((0, import_harness.toolCalls)(options.session), {
|
|
287
|
-
traceId: trace.id,
|
|
288
|
-
parentId: trace.rootSpanId,
|
|
289
|
-
spanIdPrefix: `${trace.id}:tool`
|
|
290
|
-
});
|
|
291
290
|
const finishedAt = options.finishedAt;
|
|
292
291
|
const durationMs = finishedAt.getTime() - trace.startedAt.getTime();
|
|
293
292
|
const rootError = options.errors?.[0] ? (0, import_harness.normalizeSpanError)(options.errors[0]) : void 0;
|
|
@@ -307,7 +306,7 @@ function finishAiSdkTrace(trace, options) {
|
|
|
307
306
|
...(0, import_harness.createGenAiUsageAttributes)(options.usage)
|
|
308
307
|
})
|
|
309
308
|
};
|
|
310
|
-
const spans = [rootSpan, ...modelSpans
|
|
309
|
+
const spans = [rootSpan, ...modelSpans];
|
|
311
310
|
return {
|
|
312
311
|
id: trace.id,
|
|
313
312
|
name: trace.name,
|
|
@@ -321,7 +320,7 @@ function finishAiSdkTrace(trace, options) {
|
|
|
321
320
|
};
|
|
322
321
|
}
|
|
323
322
|
function createAiSdkModelSpans(trace, result, usage) {
|
|
324
|
-
const steps =
|
|
323
|
+
const steps = readAiSdkSteps(result);
|
|
325
324
|
if (steps.length === 0) {
|
|
326
325
|
const fallback = createUsageModelSpan(trace, usage);
|
|
327
326
|
return fallback ? [fallback] : [];
|
|
@@ -376,7 +375,7 @@ function createToolset({
|
|
|
376
375
|
tools,
|
|
377
376
|
toolReplay,
|
|
378
377
|
replayMetadataByToolCallId,
|
|
379
|
-
|
|
378
|
+
runtimeEvents
|
|
380
379
|
}) {
|
|
381
380
|
return Object.fromEntries(
|
|
382
381
|
Object.entries(tools ?? {}).map(([toolName, tool]) => {
|
|
@@ -395,6 +394,14 @@ function createToolset({
|
|
|
395
394
|
execute: async (toolInput, execution) => {
|
|
396
395
|
const startedAt = /* @__PURE__ */ new Date();
|
|
397
396
|
const normalizedArgs = normalizeArguments(toolInput);
|
|
397
|
+
const call = {
|
|
398
|
+
type: "tool_call",
|
|
399
|
+
id: execution.toolCallId,
|
|
400
|
+
name: toolName,
|
|
401
|
+
...normalizedArgs ? { arguments: normalizedArgs } : {},
|
|
402
|
+
startedAt: startedAt.toISOString()
|
|
403
|
+
};
|
|
404
|
+
runtimeEvents.push(call);
|
|
398
405
|
const replayContext = {
|
|
399
406
|
input,
|
|
400
407
|
signal: context.signal,
|
|
@@ -414,7 +421,6 @@ function createToolset({
|
|
|
414
421
|
replay: void 0
|
|
415
422
|
};
|
|
416
423
|
const finishedAt = /* @__PURE__ */ new Date();
|
|
417
|
-
const normalizedResult = (0, import_harness.toJsonValue)(executionResult.result);
|
|
418
424
|
const replayMetadata = (0, import_replay.normalizeReplayMetadata)(
|
|
419
425
|
executionResult.replay
|
|
420
426
|
);
|
|
@@ -424,15 +430,20 @@ function createToolset({
|
|
|
424
430
|
executionResult.replay
|
|
425
431
|
);
|
|
426
432
|
}
|
|
427
|
-
|
|
428
|
-
|
|
433
|
+
call.finishedAt = finishedAt.toISOString();
|
|
434
|
+
call.durationMs = finishedAt.getTime() - startedAt.getTime();
|
|
435
|
+
if (replayMetadata) {
|
|
436
|
+
call.metadata = replayMetadata;
|
|
437
|
+
}
|
|
438
|
+
const normalizedResult = (0, import_harness.toJsonValue)(executionResult.result);
|
|
439
|
+
runtimeEvents.push({
|
|
440
|
+
type: "tool_result",
|
|
441
|
+
toolCallId: execution.toolCallId,
|
|
429
442
|
name: toolName,
|
|
430
|
-
...
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
435
|
-
...replayMetadata ? { metadata: replayMetadata } : {}
|
|
443
|
+
...normalizedResult !== void 0 ? { content: normalizedResult } : {},
|
|
444
|
+
startedAt: call.startedAt,
|
|
445
|
+
finishedAt: call.finishedAt,
|
|
446
|
+
durationMs: call.durationMs
|
|
436
447
|
});
|
|
437
448
|
return executionResult.result;
|
|
438
449
|
} catch (error) {
|
|
@@ -442,15 +453,19 @@ function createToolset({
|
|
|
442
453
|
if (replay2) {
|
|
443
454
|
replayMetadataByToolCallId.set(execution.toolCallId, replay2);
|
|
444
455
|
}
|
|
445
|
-
|
|
446
|
-
|
|
456
|
+
call.finishedAt = finishedAt.toISOString();
|
|
457
|
+
call.durationMs = finishedAt.getTime() - startedAt.getTime();
|
|
458
|
+
if (replayMetadata) {
|
|
459
|
+
call.metadata = replayMetadata;
|
|
460
|
+
}
|
|
461
|
+
runtimeEvents.push({
|
|
462
|
+
type: "tool_result",
|
|
463
|
+
toolCallId: execution.toolCallId,
|
|
447
464
|
name: toolName,
|
|
448
|
-
...normalizedArgs ? { arguments: normalizedArgs } : {},
|
|
449
465
|
error: normalizeError(error),
|
|
450
|
-
startedAt: startedAt
|
|
451
|
-
finishedAt: finishedAt
|
|
452
|
-
durationMs:
|
|
453
|
-
...replayMetadata ? { metadata: replayMetadata } : {}
|
|
466
|
+
startedAt: call.startedAt,
|
|
467
|
+
finishedAt: call.finishedAt,
|
|
468
|
+
durationMs: call.durationMs
|
|
454
469
|
});
|
|
455
470
|
throw error;
|
|
456
471
|
}
|
|
@@ -539,26 +554,26 @@ function toOutputValue(value) {
|
|
|
539
554
|
}
|
|
540
555
|
return void 0;
|
|
541
556
|
}
|
|
542
|
-
function resolveUsage(result,
|
|
543
|
-
const steps =
|
|
544
|
-
const
|
|
557
|
+
function resolveUsage(result, runtimeEvents = [], explicitSession) {
|
|
558
|
+
const steps = readAiSdkSteps(result);
|
|
559
|
+
const runtimeToolCallCount = countRuntimeToolCalls(runtimeEvents);
|
|
560
|
+
const explicitSessionToolCallCount = explicitSession ? countSessionToolCalls(explicitSession) : void 0;
|
|
561
|
+
const usage = readAiSdkUsage(result, steps);
|
|
545
562
|
const lastStep = steps.length > 0 ? steps[steps.length - 1] : void 0;
|
|
563
|
+
const toolCallCount = explicitSessionToolCallCount ?? (steps.length > 0 ? countStepToolCalls(steps) : runtimeToolCallCount);
|
|
546
564
|
if (!usage) {
|
|
547
|
-
if (steps.length > 0) {
|
|
548
|
-
const toolCallCount2 = countStepToolCalls(steps);
|
|
565
|
+
if (toolCallCount > 0 || steps.length > 0) {
|
|
549
566
|
return {
|
|
550
|
-
provider: lastStep?.model
|
|
551
|
-
model: lastStep?.model
|
|
552
|
-
...
|
|
567
|
+
provider: lastStep?.model?.provider,
|
|
568
|
+
model: lastStep?.model?.modelId,
|
|
569
|
+
...toolCallCount > 0 ? { toolCalls: toolCallCount } : {}
|
|
553
570
|
};
|
|
554
571
|
}
|
|
555
|
-
return
|
|
572
|
+
return {};
|
|
556
573
|
}
|
|
557
|
-
const stepToolCallCount = countStepToolCalls(steps);
|
|
558
|
-
const toolCallCount = stepToolCallCount > 0 ? stepToolCallCount : runtimeToolCallCount;
|
|
559
574
|
return {
|
|
560
|
-
provider: lastStep?.model
|
|
561
|
-
model: lastStep?.model
|
|
575
|
+
provider: lastStep?.model?.provider,
|
|
576
|
+
model: lastStep?.model?.modelId,
|
|
562
577
|
inputTokens: usage.inputTokens,
|
|
563
578
|
outputTokens: usage.outputTokens,
|
|
564
579
|
reasoningTokens: usage.outputTokenDetails?.reasoningTokens ?? usage.reasoningTokens,
|
|
@@ -571,8 +586,11 @@ function resolveUsage(result, runtimeToolCallCount = 0) {
|
|
|
571
586
|
})
|
|
572
587
|
};
|
|
573
588
|
}
|
|
589
|
+
function countRuntimeToolCalls(events) {
|
|
590
|
+
return events.filter((event) => event.type === "tool_call").length;
|
|
591
|
+
}
|
|
574
592
|
function resolveStepUsage(steps) {
|
|
575
|
-
const usages = steps.map((step) => step.usage).filter(
|
|
593
|
+
const usages = steps.map((step) => step.usage).filter(isLanguageModelUsage);
|
|
576
594
|
if (usages.length === 0) {
|
|
577
595
|
return void 0;
|
|
578
596
|
}
|
|
@@ -626,86 +644,125 @@ function countStepToolCalls(steps) {
|
|
|
626
644
|
0
|
|
627
645
|
);
|
|
628
646
|
}
|
|
629
|
-
function
|
|
647
|
+
function countSessionToolCalls(session) {
|
|
648
|
+
return session.events.filter((event) => event.type === "tool_call").length;
|
|
649
|
+
}
|
|
650
|
+
function shouldUseRuntimeEvents(result) {
|
|
630
651
|
if ((0, import_harness.isNormalizedSession)(
|
|
631
652
|
result?.session
|
|
632
653
|
)) {
|
|
633
|
-
return
|
|
654
|
+
return false;
|
|
634
655
|
}
|
|
635
|
-
|
|
636
|
-
|
|
656
|
+
return readAiSdkSteps(result).length === 0;
|
|
657
|
+
}
|
|
658
|
+
function resolveSession(input, result, output, replayMetadataByToolCallId, runtimeEvents = [], explicitSession = getResultSession(result)) {
|
|
659
|
+
if (explicitSession) {
|
|
660
|
+
return explicitSession;
|
|
637
661
|
}
|
|
638
|
-
const steps =
|
|
639
|
-
const
|
|
662
|
+
const steps = readAiSdkSteps(result);
|
|
663
|
+
const events = [
|
|
640
664
|
{
|
|
665
|
+
type: "message",
|
|
641
666
|
role: "user",
|
|
642
667
|
content: (0, import_harness.normalizeContent)(input)
|
|
643
668
|
}
|
|
644
669
|
];
|
|
645
|
-
const stepToolCallIds = /* @__PURE__ */ new Set();
|
|
646
670
|
for (const step of steps) {
|
|
647
|
-
|
|
648
|
-
stepToolCallIds.add(toolCall.toolCallId);
|
|
649
|
-
}
|
|
650
|
-
messages.push(...normalizeStep(step, replayMetadataByToolCallId));
|
|
671
|
+
events.push(...normalizeStep(step, replayMetadataByToolCallId));
|
|
651
672
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
);
|
|
655
|
-
if (unmatchedRuntimeToolCalls.length > 0) {
|
|
656
|
-
messages.push(...normalizeRuntimeToolCalls(unmatchedRuntimeToolCalls));
|
|
673
|
+
if (steps.length === 0) {
|
|
674
|
+
events.push(...runtimeEvents);
|
|
657
675
|
}
|
|
658
|
-
if (output !== void 0 && !
|
|
659
|
-
(
|
|
676
|
+
if (output !== void 0 && !events.some(
|
|
677
|
+
(event) => event.type === "message" && event.role === "assistant" && event.content !== void 0
|
|
660
678
|
)) {
|
|
661
|
-
|
|
679
|
+
events.push({
|
|
680
|
+
type: "message",
|
|
662
681
|
role: "assistant",
|
|
663
682
|
content: output
|
|
664
683
|
});
|
|
665
684
|
}
|
|
666
685
|
const lastStep = steps.length > 0 ? steps[steps.length - 1] : void 0;
|
|
667
686
|
return {
|
|
668
|
-
|
|
669
|
-
provider: lastStep?.model
|
|
670
|
-
model: lastStep?.model
|
|
687
|
+
events,
|
|
688
|
+
provider: lastStep?.model?.provider,
|
|
689
|
+
model: lastStep?.model?.modelId
|
|
671
690
|
};
|
|
672
691
|
}
|
|
673
|
-
function
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
role: "assistant",
|
|
677
|
-
toolCalls: runtimeToolCalls
|
|
678
|
-
}
|
|
679
|
-
];
|
|
680
|
-
for (const call of runtimeToolCalls) {
|
|
681
|
-
if (call.result === void 0 && !call.error) {
|
|
682
|
-
continue;
|
|
683
|
-
}
|
|
684
|
-
const content = call.result !== void 0 ? call.result : call.error && call.error.message.length > 0 ? call.error.message : void 0;
|
|
685
|
-
messages.push({
|
|
686
|
-
role: "tool",
|
|
687
|
-
...content !== void 0 ? { content } : {},
|
|
688
|
-
metadata: (0, import_harness.normalizeMetadata)({
|
|
689
|
-
name: call.name,
|
|
690
|
-
toolCallId: call.id,
|
|
691
|
-
isError: Boolean(call.error)
|
|
692
|
-
})
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
return messages;
|
|
692
|
+
function getResultSession(result) {
|
|
693
|
+
const session = result?.session;
|
|
694
|
+
return (0, import_harness.isNormalizedSession)(session) ? session : void 0;
|
|
696
695
|
}
|
|
697
|
-
function
|
|
696
|
+
function resolveFailureSession(input, runtimeEvents) {
|
|
697
|
+
return {
|
|
698
|
+
events: [
|
|
699
|
+
{
|
|
700
|
+
type: "message",
|
|
701
|
+
role: "user",
|
|
702
|
+
content: (0, import_harness.normalizeContent)(input)
|
|
703
|
+
},
|
|
704
|
+
...runtimeEvents
|
|
705
|
+
]
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
function readAiSdkSteps(result) {
|
|
698
709
|
if (!result || typeof result !== "object") {
|
|
699
710
|
return [];
|
|
700
711
|
}
|
|
701
|
-
|
|
712
|
+
if (!Object.prototype.hasOwnProperty.call(result, "steps")) {
|
|
713
|
+
return [];
|
|
714
|
+
}
|
|
715
|
+
const steps = result.steps;
|
|
716
|
+
if (!Array.isArray(steps)) {
|
|
717
|
+
return [];
|
|
718
|
+
}
|
|
719
|
+
if (steps.length > 0 && !steps.every(isAiSdkStepLike)) {
|
|
720
|
+
return [];
|
|
721
|
+
}
|
|
722
|
+
return steps;
|
|
723
|
+
}
|
|
724
|
+
function isAiSdkStepLike(step) {
|
|
725
|
+
if (!step || typeof step !== "object") {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
const record = step;
|
|
729
|
+
return Array.isArray(record.content) || Array.isArray(record.toolCalls) || Array.isArray(record.toolResults) || Boolean(record.response && typeof record.response === "object") || Boolean(record.usage && typeof record.usage === "object") || typeof record.finishReason === "string" || typeof record.stepNumber === "number" || typeof record.text === "string";
|
|
730
|
+
}
|
|
731
|
+
function readAiSdkUsage(result, steps) {
|
|
732
|
+
const totalUsage = readUsageField(result, "totalUsage");
|
|
733
|
+
if (totalUsage) {
|
|
734
|
+
return totalUsage;
|
|
735
|
+
}
|
|
736
|
+
if (steps.length > 0) {
|
|
737
|
+
return resolveStepUsage(steps);
|
|
738
|
+
}
|
|
739
|
+
return readUsageField(result, "usage");
|
|
702
740
|
}
|
|
703
|
-
function
|
|
741
|
+
function readUsageField(result, field) {
|
|
704
742
|
if (!result || typeof result !== "object") {
|
|
705
743
|
return void 0;
|
|
706
744
|
}
|
|
707
|
-
const
|
|
708
|
-
return
|
|
745
|
+
const usage = result[field];
|
|
746
|
+
return isLanguageModelUsage(usage) ? usage : void 0;
|
|
747
|
+
}
|
|
748
|
+
function isLanguageModelUsage(value) {
|
|
749
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
750
|
+
return false;
|
|
751
|
+
}
|
|
752
|
+
const usage = value;
|
|
753
|
+
return isOptionalFiniteNumber(usage.inputTokens) && isOptionalFiniteNumber(usage.outputTokens) && isOptionalFiniteNumber(usage.reasoningTokens) && isOptionalFiniteNumber(usage.totalTokens) && isOptionalFiniteNumber(usage.cachedInputTokens) && isUsageDetailObject(usage.inputTokenDetails) && isUsageDetailObject(usage.outputTokenDetails);
|
|
754
|
+
}
|
|
755
|
+
function isUsageDetailObject(value) {
|
|
756
|
+
if (value === void 0) {
|
|
757
|
+
return true;
|
|
758
|
+
}
|
|
759
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
760
|
+
return false;
|
|
761
|
+
}
|
|
762
|
+
return Object.values(value).every(isOptionalFiniteNumber);
|
|
763
|
+
}
|
|
764
|
+
function isOptionalFiniteNumber(value) {
|
|
765
|
+
return value === void 0 || typeof value === "number" && Number.isFinite(value);
|
|
709
766
|
}
|
|
710
767
|
function normalizeStep(step, replayMetadataByToolCallId) {
|
|
711
768
|
const toolResultsById = new Map(
|
|
@@ -714,12 +771,15 @@ function normalizeStep(step, replayMetadataByToolCallId) {
|
|
|
714
771
|
toolResult
|
|
715
772
|
])
|
|
716
773
|
);
|
|
774
|
+
const toolErrorsById = new Map(
|
|
775
|
+
(step.toolCalls ?? []).filter((toolCall) => toolCall.invalid || toolCall.error !== void 0).map((toolCall) => [
|
|
776
|
+
toolCall.toolCallId,
|
|
777
|
+
normalizeError(toolCall.error ?? toolCall.invalid)
|
|
778
|
+
])
|
|
779
|
+
);
|
|
717
780
|
const normalizedCalls = (step.toolCalls ?? []).map(
|
|
718
781
|
(toolCall) => normalizeToolCall(toolCall, toolResultsById, replayMetadataByToolCallId)
|
|
719
782
|
);
|
|
720
|
-
const normalizedCallsById = new Map(
|
|
721
|
-
normalizedCalls.map((toolCall) => [toolCall.id, toolCall])
|
|
722
|
-
);
|
|
723
783
|
const assistantMetadata = (0, import_harness.normalizeMetadata)({
|
|
724
784
|
stepNumber: step.stepNumber,
|
|
725
785
|
finishReason: step.finishReason,
|
|
@@ -727,24 +787,25 @@ function normalizeStep(step, replayMetadataByToolCallId) {
|
|
|
727
787
|
reasoningText: step.reasoningText,
|
|
728
788
|
response: step.response
|
|
729
789
|
});
|
|
730
|
-
const
|
|
731
|
-
if (step.text ||
|
|
732
|
-
|
|
790
|
+
const events = [];
|
|
791
|
+
if (step.text || assistantMetadata) {
|
|
792
|
+
events.push({
|
|
793
|
+
type: "message",
|
|
733
794
|
role: "assistant",
|
|
734
795
|
...step.text ? { content: step.text } : {},
|
|
735
|
-
...normalizedCalls.length > 0 ? { toolCalls: normalizedCalls } : {},
|
|
736
796
|
...assistantMetadata ? { metadata: assistantMetadata } : {}
|
|
737
797
|
});
|
|
738
798
|
}
|
|
799
|
+
events.push(...normalizedCalls);
|
|
739
800
|
for (const toolResult of step.toolResults ?? []) {
|
|
740
801
|
const content = toolResult.output === void 0 ? void 0 : (0, import_harness.normalizeContent)(toolResult.output);
|
|
741
|
-
|
|
742
|
-
|
|
802
|
+
events.push({
|
|
803
|
+
type: "tool_result",
|
|
804
|
+
toolCallId: toolResult.toolCallId,
|
|
805
|
+
name: toolResult.toolName,
|
|
743
806
|
...content !== void 0 ? { content } : {},
|
|
807
|
+
...toolErrorsById.has(toolResult.toolCallId) ? { error: toolErrorsById.get(toolResult.toolCallId) } : {},
|
|
744
808
|
metadata: (0, import_harness.normalizeMetadata)({
|
|
745
|
-
name: toolResult.toolName,
|
|
746
|
-
toolCallId: toolResult.toolCallId,
|
|
747
|
-
isError: Boolean(normalizedCallsById.get(toolResult.toolCallId)?.error),
|
|
748
809
|
preliminary: toolResult.preliminary,
|
|
749
810
|
providerExecuted: toolResult.providerExecuted,
|
|
750
811
|
title: toolResult.title,
|
|
@@ -752,27 +813,26 @@ function normalizeStep(step, replayMetadataByToolCallId) {
|
|
|
752
813
|
})
|
|
753
814
|
});
|
|
754
815
|
}
|
|
755
|
-
return
|
|
816
|
+
return events;
|
|
756
817
|
}
|
|
757
818
|
function normalizeToolCall(toolCall, toolResultsById, replayMetadataByToolCallId) {
|
|
758
819
|
const toolResult = toolResultsById.get(toolCall.toolCallId);
|
|
759
820
|
const normalizedArguments = normalizeArguments(toolCall.input);
|
|
760
|
-
const normalizedResult = toolResult !== void 0 ? (0, import_harness.toJsonValue)(toolResult.output) : void 0;
|
|
761
821
|
const errorValue = toolCall.invalid || toolCall.error !== void 0 ? normalizeError(toolCall.error ?? toolCall.invalid) : void 0;
|
|
762
822
|
const replayMetadata = (0, import_replay.normalizeReplayMetadata)(
|
|
763
823
|
replayMetadataByToolCallId.get(toolCall.toolCallId)
|
|
764
824
|
);
|
|
765
825
|
return {
|
|
826
|
+
type: "tool_call",
|
|
766
827
|
id: toolCall.toolCallId,
|
|
767
828
|
name: toolCall.toolName,
|
|
768
829
|
...normalizedArguments ? { arguments: normalizedArguments } : {},
|
|
769
|
-
...toolResult && normalizedResult !== void 0 ? { result: normalizedResult } : {},
|
|
770
|
-
...errorValue ? { error: errorValue } : {},
|
|
771
830
|
metadata: (0, import_harness.normalizeMetadata)({
|
|
772
831
|
providerExecuted: toolCall.providerExecuted ?? toolResult?.providerExecuted,
|
|
773
832
|
title: toolCall.title ?? toolResult?.title,
|
|
774
833
|
dynamic: toolCall.dynamic,
|
|
775
834
|
invalid: toolCall.invalid,
|
|
835
|
+
...errorValue ? { error: errorValue } : {},
|
|
776
836
|
preliminary: toolResult?.preliminary,
|
|
777
837
|
providerMetadata: toolCall.providerMetadata ?? toolResult?.providerMetadata,
|
|
778
838
|
...replayMetadata ?? {}
|