@ai-sdk/harness 1.0.73 → 1.0.75
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.75",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@ai-sdk/provider": "4.0.7",
|
|
48
48
|
"@ai-sdk/provider-utils": "5.0.27",
|
|
49
|
-
"ai": "7.0.
|
|
49
|
+
"ai": "7.0.68"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"ws": "^8.21.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"typescript": "5.8.3",
|
|
66
66
|
"ws": "^8.21.0",
|
|
67
67
|
"zod": "3.25.76",
|
|
68
|
-
"@ai-sdk/otel": "1.0.
|
|
68
|
+
"@ai-sdk/otel": "1.0.68",
|
|
69
69
|
"@vercel/ai-tsconfig": "0.0.0"
|
|
70
70
|
},
|
|
71
71
|
"engines": {
|
|
@@ -824,21 +824,10 @@ export class HarnessStreamTextResult<
|
|
|
824
824
|
return;
|
|
825
825
|
}
|
|
826
826
|
case 'tool-call':
|
|
827
|
-
this.currentStepContent.push({
|
|
828
|
-
...(part as object),
|
|
829
|
-
} as ContentPart<TOOLS>);
|
|
830
|
-
return;
|
|
831
827
|
case 'tool-approval-request':
|
|
832
|
-
this.currentStepContent.push({
|
|
833
|
-
...(part as object),
|
|
834
|
-
} as ContentPart<TOOLS>);
|
|
835
|
-
return;
|
|
836
828
|
case 'tool-approval-response':
|
|
837
|
-
this.currentStepContent.push({
|
|
838
|
-
...(part as object),
|
|
839
|
-
} as ContentPart<TOOLS>);
|
|
840
|
-
return;
|
|
841
829
|
case 'tool-result':
|
|
830
|
+
case 'tool-error':
|
|
842
831
|
this.currentStepContent.push({
|
|
843
832
|
...(part as object),
|
|
844
833
|
} as ContentPart<TOOLS>);
|
|
@@ -219,6 +219,19 @@ export function runPrompt<
|
|
|
219
219
|
string,
|
|
220
220
|
Extract<HarnessV1StreamPart, { type: 'tool-call' }>
|
|
221
221
|
>();
|
|
222
|
+
/*
|
|
223
|
+
* Host results are echoed back as `tool-result` events too, so the event
|
|
224
|
+
* alone cannot say who ran the tool — classify by the originating
|
|
225
|
+
* `tool-call`. Only an explicit `true` counts: `LanguageModelV4ToolCall`
|
|
226
|
+
* defines an omitted flag as client-executed. A call missing from the map
|
|
227
|
+
* arrived in an earlier slice, where nothing here can classify it.
|
|
228
|
+
*/
|
|
229
|
+
const translateOptions = {
|
|
230
|
+
isProviderExecuted: (toolCallId: string): boolean => {
|
|
231
|
+
const rawToolCall = rawToolCallsByToolCallId.get(toolCallId);
|
|
232
|
+
return rawToolCall == null || rawToolCall.providerExecuted === true;
|
|
233
|
+
},
|
|
234
|
+
};
|
|
222
235
|
const pendingApprovalsByApprovalId = new Map(
|
|
223
236
|
pendingToolApprovals.map(approval => [approval.approvalId, approval]),
|
|
224
237
|
);
|
|
@@ -709,7 +722,10 @@ export function runPrompt<
|
|
|
709
722
|
}
|
|
710
723
|
|
|
711
724
|
// Forward to consumer as soon as possible.
|
|
712
|
-
for (const part of translateStreamPart<TOOLS>(
|
|
725
|
+
for (const part of translateStreamPart<TOOLS>(
|
|
726
|
+
displayValue,
|
|
727
|
+
translateOptions,
|
|
728
|
+
)) {
|
|
713
729
|
result.enqueue(part);
|
|
714
730
|
}
|
|
715
731
|
|
|
@@ -14,6 +14,8 @@ import { generateId, type ToolSet } from '@ai-sdk/provider-utils';
|
|
|
14
14
|
* - tool-call events are not translated here — validation against the
|
|
15
15
|
* merged tool set is async and handled by `validateToolCall` in
|
|
16
16
|
* `run-prompt.ts`
|
|
17
|
+
* - a failed `tool-result` from a provider-executed tool becomes a
|
|
18
|
+
* `tool-error` (see `isProviderExecuted`)
|
|
17
19
|
* - the harness `raw` part is forwarded as the AI SDK `raw` part
|
|
18
20
|
*
|
|
19
21
|
* Returns an array of zero or more AI SDK parts. Most harness events project
|
|
@@ -26,6 +28,17 @@ import { generateId, type ToolSet } from '@ai-sdk/provider-utils';
|
|
|
26
28
|
*/
|
|
27
29
|
export function translateStreamPart<TOOLS extends ToolSet>(
|
|
28
30
|
event: HarnessV1StreamPart,
|
|
31
|
+
options: {
|
|
32
|
+
/**
|
|
33
|
+
* Whether the tool call that produced this event ran inside the harness
|
|
34
|
+
* runtime. Host tools travel the same `tool-result` events and their
|
|
35
|
+
* failures are echoed back with `isError`, so the event alone cannot say
|
|
36
|
+
* who ran the tool — only the originating `tool-call` can, and correlating
|
|
37
|
+
* the two is the caller's job. Omit the callback to treat every failure as
|
|
38
|
+
* provider-executed.
|
|
39
|
+
*/
|
|
40
|
+
isProviderExecuted?: (toolCallId: string) => boolean;
|
|
41
|
+
} = {},
|
|
29
42
|
): ReadonlyArray<TextStreamPart<TOOLS>> {
|
|
30
43
|
switch (event.type) {
|
|
31
44
|
case 'stream-start':
|
|
@@ -101,6 +114,32 @@ export function translateStreamPart<TOOLS extends ToolSet>(
|
|
|
101
114
|
return [];
|
|
102
115
|
|
|
103
116
|
case 'tool-result':
|
|
117
|
+
if (
|
|
118
|
+
event.isError === true &&
|
|
119
|
+
(options.isProviderExecuted?.(event.toolCallId) ?? true)
|
|
120
|
+
) {
|
|
121
|
+
/*
|
|
122
|
+
* `providerExecuted` decides whether the message survives:
|
|
123
|
+
* `toUIMessageChunk` forwards the real error text only for
|
|
124
|
+
* provider-executed errors, and replaces every other one with the
|
|
125
|
+
* generic `onError` string.
|
|
126
|
+
*/
|
|
127
|
+
return [
|
|
128
|
+
{
|
|
129
|
+
type: 'tool-error',
|
|
130
|
+
toolCallId: event.toolCallId,
|
|
131
|
+
toolName: event.toolName,
|
|
132
|
+
input: undefined,
|
|
133
|
+
error: event.result,
|
|
134
|
+
providerExecuted: true,
|
|
135
|
+
...(event.dynamic !== undefined ? { dynamic: event.dynamic } : {}),
|
|
136
|
+
...(event.providerMetadata !== undefined
|
|
137
|
+
? { providerMetadata: event.providerMetadata }
|
|
138
|
+
: {}),
|
|
139
|
+
} as TextStreamPart<TOOLS>,
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
104
143
|
return [
|
|
105
144
|
{
|
|
106
145
|
type: 'tool-result',
|