@ai-sdk/harness 1.0.118 → 1.0.119
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/CHANGELOG.md +10 -0
- package/dist/agent/index.d.ts +25 -3
- package/dist/agent/index.js +66 -23
- package/dist/agent/index.js.map +1 -1
- package/package.json +3 -3
- package/src/agent/harness-agent-session.ts +15 -0
- package/src/agent/harness-agent-settings.ts +17 -4
- package/src/agent/harness-agent.ts +25 -1
- package/src/agent/internal/get-own.ts +8 -0
- package/src/agent/internal/run-prompt.ts +31 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.119",
|
|
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.17",
|
|
48
48
|
"@ai-sdk/provider-utils": "5.0.45",
|
|
49
|
-
"ai": "7.0.
|
|
49
|
+
"ai": "7.0.109"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"ws": "^8.21.0",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@ai-sdk/otel": "1.0.
|
|
61
|
+
"@ai-sdk/otel": "1.0.109",
|
|
62
62
|
"@opentelemetry/sdk-trace-base": "2.7.1",
|
|
63
63
|
"@types/node": "22.19.19",
|
|
64
64
|
"@types/ws": "^8.5.13",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Context,
|
|
3
3
|
Experimental_SandboxSession as SandboxSession,
|
|
4
|
+
InferToolSetContext,
|
|
4
5
|
ToolApprovalResponse,
|
|
5
6
|
ToolResultPart,
|
|
6
7
|
ToolSet,
|
|
@@ -65,6 +66,7 @@ type ActivePromptControl = {
|
|
|
65
66
|
type ActiveTurnSettings = {
|
|
66
67
|
readonly persisted: HarnessV1TurnSettings;
|
|
67
68
|
readonly tools: ToolSet;
|
|
69
|
+
readonly toolsContext: Record<string, Context | undefined>;
|
|
68
70
|
readonly activeTools: ToolSet;
|
|
69
71
|
readonly builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
70
72
|
};
|
|
@@ -119,6 +121,9 @@ export class HarnessAgentSession {
|
|
|
119
121
|
| undefined;
|
|
120
122
|
private activeTurnSettings: ActiveTurnSettings | undefined;
|
|
121
123
|
private persistedTurnSettings: HarnessV1TurnSettings | undefined;
|
|
124
|
+
private readonly resumedToolsContext:
|
|
125
|
+
| Record<string, Context | undefined>
|
|
126
|
+
| undefined;
|
|
122
127
|
|
|
123
128
|
/**
|
|
124
129
|
* Whether this session was created from `resumeFrom` or `continueFrom`.
|
|
@@ -137,6 +142,7 @@ export class HarnessAgentSession {
|
|
|
137
142
|
pendingToolApprovals?: readonly HarnessAgentPendingToolApproval[];
|
|
138
143
|
pendingToolResults?: readonly HarnessAgentPendingToolResult[];
|
|
139
144
|
turnSettings?: HarnessV1TurnSettings;
|
|
145
|
+
resumedToolsContext?: Record<string, Context | undefined>;
|
|
140
146
|
turnState?: HarnessAgentTurnState;
|
|
141
147
|
}) {
|
|
142
148
|
this.sessionId = options.sessionId;
|
|
@@ -153,6 +159,7 @@ export class HarnessAgentSession {
|
|
|
153
159
|
this.pendingToolResults.set(pendingResult.toolCallId, pendingResult);
|
|
154
160
|
}
|
|
155
161
|
this.persistedTurnSettings = options.turnSettings;
|
|
162
|
+
this.resumedToolsContext = options.resumedToolsContext;
|
|
156
163
|
this.turnState =
|
|
157
164
|
options.turnState ??
|
|
158
165
|
(this.pendingToolApprovals.size > 0
|
|
@@ -201,6 +208,7 @@ export class HarnessAgentSession {
|
|
|
201
208
|
skills: ReadonlyArray<HarnessV1Skill>;
|
|
202
209
|
instructions: string | undefined;
|
|
203
210
|
tools: TOOLS;
|
|
211
|
+
toolsContext: InferToolSetContext<TOOLS>;
|
|
204
212
|
activeTools: ToolSet;
|
|
205
213
|
toolSpecs: HarnessAgentToolSpec[];
|
|
206
214
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -225,6 +233,7 @@ export class HarnessAgentSession {
|
|
|
225
233
|
this.activeTurnSettings = {
|
|
226
234
|
persisted: this.persistedTurnSettings,
|
|
227
235
|
tools: options.tools,
|
|
236
|
+
toolsContext: options.toolsContext,
|
|
228
237
|
activeTools: options.activeTools,
|
|
229
238
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
230
239
|
};
|
|
@@ -239,6 +248,7 @@ export class HarnessAgentSession {
|
|
|
239
248
|
skills: options.skills,
|
|
240
249
|
instructions: options.instructions,
|
|
241
250
|
tools: options.tools,
|
|
251
|
+
toolsContext: options.toolsContext,
|
|
242
252
|
activeTools: options.activeTools,
|
|
243
253
|
toolSpecs: options.toolSpecs,
|
|
244
254
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
@@ -302,6 +312,7 @@ export class HarnessAgentSession {
|
|
|
302
312
|
skills: ReadonlyArray<HarnessV1Skill>;
|
|
303
313
|
instructions: string | undefined;
|
|
304
314
|
tools: TOOLS;
|
|
315
|
+
toolsContext: InferToolSetContext<TOOLS>;
|
|
305
316
|
activeTools: ToolSet;
|
|
306
317
|
toolSpecs: HarnessAgentToolSpec[];
|
|
307
318
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -322,6 +333,7 @@ export class HarnessAgentSession {
|
|
|
322
333
|
skills: options.skills,
|
|
323
334
|
instructions: options.instructions,
|
|
324
335
|
tools: options.tools,
|
|
336
|
+
toolsContext: options.toolsContext,
|
|
325
337
|
activeTools: options.activeTools,
|
|
326
338
|
toolSpecs: options.toolSpecs,
|
|
327
339
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
@@ -337,6 +349,7 @@ export class HarnessAgentSession {
|
|
|
337
349
|
skills: turnSettings.persisted.skills,
|
|
338
350
|
instructions: turnSettings.persisted.instructions,
|
|
339
351
|
tools: turnSettings.tools as TOOLS,
|
|
352
|
+
toolsContext: turnSettings.toolsContext as InferToolSetContext<TOOLS>,
|
|
340
353
|
activeTools: turnSettings.activeTools,
|
|
341
354
|
toolSpecs: [...turnSettings.persisted.tools],
|
|
342
355
|
builtinToolFiltering: turnSettings.builtinToolFiltering,
|
|
@@ -778,6 +791,7 @@ export class HarnessAgentSession {
|
|
|
778
791
|
skills: ReadonlyArray<HarnessV1Skill>;
|
|
779
792
|
instructions: string | undefined;
|
|
780
793
|
tools: ToolSet;
|
|
794
|
+
toolsContext: Record<string, Context | undefined>;
|
|
781
795
|
activeTools: ToolSet;
|
|
782
796
|
toolSpecs: HarnessAgentToolSpec[];
|
|
783
797
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -811,6 +825,7 @@ export class HarnessAgentSession {
|
|
|
811
825
|
this.activeTurnSettings = {
|
|
812
826
|
persisted,
|
|
813
827
|
tools: options.tools,
|
|
828
|
+
toolsContext: this.resumedToolsContext ?? options.toolsContext,
|
|
814
829
|
activeTools,
|
|
815
830
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
816
831
|
};
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
Context,
|
|
14
14
|
Experimental_SandboxSession as SandboxSession,
|
|
15
15
|
FlexibleSchema,
|
|
16
|
+
InferToolSetContext,
|
|
16
17
|
MaybePromiseLike,
|
|
17
18
|
SystemModelMessage,
|
|
18
19
|
ToolSet,
|
|
@@ -34,6 +35,7 @@ import type {
|
|
|
34
35
|
TelemetryOptions,
|
|
35
36
|
ToolApprovalStatus,
|
|
36
37
|
} from 'ai';
|
|
38
|
+
import type { ToolsContextSettings } from 'ai/internal';
|
|
37
39
|
import type { HarnessAllTools } from './harness-agent-tool-types';
|
|
38
40
|
|
|
39
41
|
export type HarnessAgentToolApprovalConfiguration = Readonly<
|
|
@@ -150,6 +152,13 @@ export type HarnessAgentSettings<
|
|
|
150
152
|
*/
|
|
151
153
|
readonly tools?: TUserTools;
|
|
152
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Per-tool context passed to host-executed tools. Each entry is validated
|
|
157
|
+
* against the matching tool's `contextSchema` before execution.
|
|
158
|
+
* `prepareCall` can replace it for each new turn.
|
|
159
|
+
*/
|
|
160
|
+
readonly toolsContext?: InferToolSetContext<TUserTools>;
|
|
161
|
+
|
|
153
162
|
/**
|
|
154
163
|
* Skills made available to the underlying runtime. Each adapter decides how
|
|
155
164
|
* to surface skills. `prepareCall` can replace them between completed turns.
|
|
@@ -225,7 +234,9 @@ export type HarnessAgentSettings<
|
|
|
225
234
|
CALL_OPTIONS
|
|
226
235
|
>,
|
|
227
236
|
'model' | 'skills' | 'instructions' | 'tools'
|
|
228
|
-
|
|
237
|
+
> & {
|
|
238
|
+
toolsContext: InferToolSetContext<TUserTools>;
|
|
239
|
+
},
|
|
229
240
|
) => MaybePromiseLike<
|
|
230
241
|
Pick<
|
|
231
242
|
HarnessAgentSettings<
|
|
@@ -236,8 +247,9 @@ export type HarnessAgentSettings<
|
|
|
236
247
|
CALL_OPTIONS
|
|
237
248
|
>,
|
|
238
249
|
'model' | 'skills' | 'instructions' | 'tools'
|
|
239
|
-
> &
|
|
240
|
-
|
|
250
|
+
> & {
|
|
251
|
+
toolsContext: InferToolSetContext<TUserTools>;
|
|
252
|
+
} & Omit<Prompt, 'system' | 'instructions' | 'allowSystemInMessages'>
|
|
241
253
|
>;
|
|
242
254
|
|
|
243
255
|
/**
|
|
@@ -376,4 +388,5 @@ export type HarnessAgentSettings<
|
|
|
376
388
|
* stderr default — wire this to capture diagnostics in code.
|
|
377
389
|
*/
|
|
378
390
|
readonly onLog?: (event: HarnessDiagnostic) => void;
|
|
379
|
-
} &
|
|
391
|
+
} & ToolsContextSettings<TUserTools> &
|
|
392
|
+
HarnessAgentToolFilteringSettings<HarnessAllTools<THarness, TUserTools>>;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
asArray,
|
|
11
11
|
asSchema,
|
|
12
12
|
generateId,
|
|
13
|
+
type InferToolSetContext,
|
|
13
14
|
normalizeHeaders,
|
|
14
15
|
validateTypes,
|
|
15
16
|
type Context,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
type ToolResultPart,
|
|
21
22
|
type ToolSet,
|
|
22
23
|
} from '@ai-sdk/provider-utils';
|
|
23
|
-
import { mergeCallbacks } from 'ai/internal';
|
|
24
|
+
import { mergeCallbacks, type ToolsContextSettings } from 'ai/internal';
|
|
24
25
|
import type {
|
|
25
26
|
Agent,
|
|
26
27
|
AgentCallParameters,
|
|
@@ -99,6 +100,7 @@ type PreparedHarnessAgentTurnSettings<
|
|
|
99
100
|
skills: ReadonlyArray<HarnessAgentSkill>;
|
|
100
101
|
instructions: string | undefined;
|
|
101
102
|
tools: HarnessAllTools<THarness, TUserTools>;
|
|
103
|
+
toolsContext: InferToolSetContext<HarnessAllTools<THarness, TUserTools>>;
|
|
102
104
|
activeTools: TUserTools;
|
|
103
105
|
toolSpecs: HarnessAgentToolSpec[];
|
|
104
106
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -314,6 +316,13 @@ export class HarnessAgent<
|
|
|
314
316
|
* handing it to the adapter.
|
|
315
317
|
*/
|
|
316
318
|
continueFrom?: HarnessAgentContinueTurnState;
|
|
319
|
+
/**
|
|
320
|
+
* Rebinds host-only tool context for an unfinished turn resumed with
|
|
321
|
+
* `continueFrom` (directly or through `resumeFrom`). Tool context is not
|
|
322
|
+
* serialized into lifecycle state because it may contain credentials or
|
|
323
|
+
* non-serializable host objects.
|
|
324
|
+
*/
|
|
325
|
+
toolsContext?: ToolsContextSettings<TUserTools>['toolsContext'];
|
|
317
326
|
/**
|
|
318
327
|
* Existing sandbox session to run the harness in. When provided, the
|
|
319
328
|
* caller retains ownership of the sandbox lifecycle.
|
|
@@ -356,6 +365,11 @@ export class HarnessAgent<
|
|
|
356
365
|
|
|
357
366
|
const effectiveContinueFrom =
|
|
358
367
|
validatedContinueFrom ?? validatedResumeFrom?.continueFrom;
|
|
368
|
+
if (options?.toolsContext != null && effectiveContinueFrom == null) {
|
|
369
|
+
throw new Error(
|
|
370
|
+
'HarnessAgent.createSession: `toolsContext` can only rebind an unfinished turn from `continueFrom` or `resumeFrom`.',
|
|
371
|
+
);
|
|
372
|
+
}
|
|
359
373
|
const isResumedSession =
|
|
360
374
|
validatedResumeFrom != null || effectiveContinueFrom != null;
|
|
361
375
|
|
|
@@ -552,6 +566,7 @@ export class HarnessAgent<
|
|
|
552
566
|
pendingToolApprovals: effectiveContinueFrom?.pendingToolApprovals,
|
|
553
567
|
pendingToolResults: effectiveContinueFrom?.pendingToolResults,
|
|
554
568
|
turnSettings: effectiveContinueFrom?.turnSettings,
|
|
569
|
+
resumedToolsContext: options?.toolsContext,
|
|
555
570
|
turnState:
|
|
556
571
|
effectiveContinueFrom == null
|
|
557
572
|
? 'idle'
|
|
@@ -785,6 +800,7 @@ export class HarnessAgent<
|
|
|
785
800
|
skills: input.turnSettings.skills,
|
|
786
801
|
instructions: input.turnSettings.instructions,
|
|
787
802
|
tools: input.turnSettings.tools,
|
|
803
|
+
toolsContext: input.turnSettings.toolsContext,
|
|
788
804
|
activeTools: input.turnSettings.activeTools,
|
|
789
805
|
toolSpecs: input.turnSettings.toolSpecs,
|
|
790
806
|
builtinToolFiltering: input.turnSettings.builtinToolFiltering,
|
|
@@ -943,6 +959,8 @@ export class HarnessAgent<
|
|
|
943
959
|
skills: this.settings.skills,
|
|
944
960
|
instructions: this.settings.instructions,
|
|
945
961
|
tools: this.settings.tools,
|
|
962
|
+
toolsContext:
|
|
963
|
+
this.settings.toolsContext ?? ({} as InferToolSetContext<TUserTools>),
|
|
946
964
|
...promptOptions,
|
|
947
965
|
};
|
|
948
966
|
const preparedCallArgs =
|
|
@@ -972,6 +990,7 @@ export class HarnessAgent<
|
|
|
972
990
|
skills: preparedCallArgs.skills,
|
|
973
991
|
instructions: preparedCallArgs.instructions,
|
|
974
992
|
tools: preparedCallArgs.tools,
|
|
993
|
+
toolsContext: preparedCallArgs.toolsContext,
|
|
975
994
|
}),
|
|
976
995
|
};
|
|
977
996
|
}
|
|
@@ -986,6 +1005,7 @@ export class HarnessAgent<
|
|
|
986
1005
|
skills: this.settings.skills,
|
|
987
1006
|
instructions: this.settings.instructions,
|
|
988
1007
|
tools: this.settings.tools,
|
|
1008
|
+
toolsContext: this.settings.toolsContext,
|
|
989
1009
|
}),
|
|
990
1010
|
toolApprovalContinuations: options.toolApprovalContinuations ?? [],
|
|
991
1011
|
toolResultContinuations: options.toolResultContinuations ?? [],
|
|
@@ -997,6 +1017,7 @@ export class HarnessAgent<
|
|
|
997
1017
|
skills?: ReadonlyArray<HarnessAgentSkill>;
|
|
998
1018
|
instructions?: string | SystemModelMessage;
|
|
999
1019
|
tools?: TUserTools;
|
|
1020
|
+
toolsContext?: InferToolSetContext<TUserTools>;
|
|
1000
1021
|
}): PreparedHarnessAgentTurnSettings<THarness, TUserTools> {
|
|
1001
1022
|
const userTools = options.tools ?? ({} as TUserTools);
|
|
1002
1023
|
assertNoReservedQuestionTool({
|
|
@@ -1022,6 +1043,9 @@ export class HarnessAgent<
|
|
|
1022
1043
|
? options.instructions
|
|
1023
1044
|
: options.instructions?.content,
|
|
1024
1045
|
tools,
|
|
1046
|
+
toolsContext: (options.toolsContext ?? {}) as InferToolSetContext<
|
|
1047
|
+
HarnessAllTools<THarness, TUserTools>
|
|
1048
|
+
>,
|
|
1025
1049
|
activeTools: toolFiltering.activeUserTools,
|
|
1026
1050
|
toolSpecs: this._toToolSpecs(toolFiltering.activeUserTools),
|
|
1027
1051
|
builtinToolFiltering: toolFiltering.builtinToolFiltering,
|
|
@@ -32,7 +32,11 @@ import {
|
|
|
32
32
|
type LanguageModelV4ToolCall,
|
|
33
33
|
type LanguageModelV4Usage,
|
|
34
34
|
} from '@ai-sdk/provider';
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
asLanguageModelUsage,
|
|
37
|
+
parseToolCall,
|
|
38
|
+
validateToolContext,
|
|
39
|
+
} from 'ai/internal';
|
|
36
40
|
import type {
|
|
37
41
|
ContentPart,
|
|
38
42
|
OutputInterface as Output,
|
|
@@ -47,6 +51,7 @@ import type {
|
|
|
47
51
|
} from 'ai';
|
|
48
52
|
import type { HarnessAgentToolApprovalConfiguration } from '../harness-agent-settings';
|
|
49
53
|
import { HarnessStreamTextResult } from './harness-stream-text-result';
|
|
54
|
+
import { getOwn } from './get-own';
|
|
50
55
|
import { translateStreamPart } from './translate-stream-part';
|
|
51
56
|
import { createToolInputWorkDirStripper, stripWorkDir } from './strip-work-dir';
|
|
52
57
|
import {
|
|
@@ -112,6 +117,7 @@ export function runPrompt<
|
|
|
112
117
|
skills?: ReadonlyArray<HarnessV1Skill>;
|
|
113
118
|
instructions: string | undefined;
|
|
114
119
|
tools: TOOLS;
|
|
120
|
+
toolsContext?: InferToolSetContext<TOOLS>;
|
|
115
121
|
activeTools?: ToolSet;
|
|
116
122
|
toolSpecs: HarnessV1ToolSpec[];
|
|
117
123
|
builtinToolFiltering?: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -147,7 +153,7 @@ export function runPrompt<
|
|
|
147
153
|
done: Promise<void>;
|
|
148
154
|
} {
|
|
149
155
|
const callId = generateId();
|
|
150
|
-
const toolsContext = {} as InferToolSetContext<TOOLS
|
|
156
|
+
const toolsContext = input.toolsContext ?? ({} as InferToolSetContext<TOOLS>);
|
|
151
157
|
const result = new HarnessStreamTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>({
|
|
152
158
|
tools: input.tools,
|
|
153
159
|
runtimeContext: input.runtimeContext,
|
|
@@ -701,6 +707,7 @@ export function runPrompt<
|
|
|
701
707
|
const execution = await maybeExecuteHostTool({
|
|
702
708
|
event: rawToolCall,
|
|
703
709
|
tools: activeTools,
|
|
710
|
+
toolsContext,
|
|
704
711
|
wrappedExecuteTool: lifecycle.executeTool,
|
|
705
712
|
sandboxSession: input.sandboxSession,
|
|
706
713
|
abortSignal: input.abortSignal,
|
|
@@ -1260,6 +1267,7 @@ export function runPrompt<
|
|
|
1260
1267
|
const execution = await maybeExecuteHostTool({
|
|
1261
1268
|
event: toolCall,
|
|
1262
1269
|
tools: activeTools,
|
|
1270
|
+
toolsContext,
|
|
1263
1271
|
wrappedExecuteTool: lifecycle.executeTool,
|
|
1264
1272
|
sandboxSession: input.sandboxSession,
|
|
1265
1273
|
abortSignal: input.abortSignal,
|
|
@@ -1426,6 +1434,7 @@ function hasTool(input: { tools: ToolSet; toolName: string }): boolean {
|
|
|
1426
1434
|
async function maybeExecuteHostTool<TOOLS extends ToolSet>(input: {
|
|
1427
1435
|
event: { toolCallId: string; toolName: string; input: string };
|
|
1428
1436
|
tools: TOOLS;
|
|
1437
|
+
toolsContext: InferToolSetContext<TOOLS>;
|
|
1429
1438
|
wrappedExecuteTool: TurnLifecycle<ToolSet, Context>['executeTool'];
|
|
1430
1439
|
sandboxSession: SandboxSession;
|
|
1431
1440
|
abortSignal: AbortSignal | undefined;
|
|
@@ -1444,6 +1453,25 @@ async function maybeExecuteHostTool<TOOLS extends ToolSet>(input: {
|
|
|
1444
1453
|
const parsed = await safeParseJSON({ text: input.event.input });
|
|
1445
1454
|
const args = parsed.success ? parsed.value : input.event.input;
|
|
1446
1455
|
|
|
1456
|
+
let context: unknown;
|
|
1457
|
+
try {
|
|
1458
|
+
context = await validateToolContext({
|
|
1459
|
+
toolName: input.event.toolName,
|
|
1460
|
+
context: getOwn(input.toolsContext, input.event.toolName),
|
|
1461
|
+
contextSchema: tool.contextSchema,
|
|
1462
|
+
});
|
|
1463
|
+
} catch (err) {
|
|
1464
|
+
// Context is host-only and can contain credentials. Keep the detailed
|
|
1465
|
+
// validation error in the host-facing outcome, but never send its value or
|
|
1466
|
+
// schema diagnostics back to the runtime/model.
|
|
1467
|
+
await input.submitToolResult({
|
|
1468
|
+
toolCallId: input.event.toolCallId,
|
|
1469
|
+
output: { error: 'Tool context validation failed.' },
|
|
1470
|
+
isError: true,
|
|
1471
|
+
});
|
|
1472
|
+
return { executed: true, outcome: { ok: false, error: err } };
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1447
1475
|
try {
|
|
1448
1476
|
/*
|
|
1449
1477
|
* Normalize the tool's return value through `executeTool`, the same helper
|
|
@@ -1466,7 +1494,7 @@ async function maybeExecuteHostTool<TOOLS extends ToolSet>(input: {
|
|
|
1466
1494
|
toolCallId: input.event.toolCallId,
|
|
1467
1495
|
messages: [],
|
|
1468
1496
|
abortSignal: input.abortSignal,
|
|
1469
|
-
context:
|
|
1497
|
+
context: context as never,
|
|
1470
1498
|
experimental_sandbox: input.sandboxSession,
|
|
1471
1499
|
},
|
|
1472
1500
|
});
|