@ai-sdk/harness 1.0.117 → 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 +22 -0
- package/dist/agent/index.d.ts +25 -3
- package/dist/agent/index.js +130 -41
- package/dist/agent/index.js.map +1 -1
- package/dist/utils/index.d.ts +19 -3
- package/dist/utils/index.js +220 -53
- package/dist/utils/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/src/agent/internal/strip-work-dir.ts +91 -20
- package/src/utils/index.ts +2 -0
- package/src/utils/sandbox-channel.ts +220 -57
- package/src/utils/sleep.ts +30 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @ai-sdk/harness
|
|
2
2
|
|
|
3
|
+
## 1.0.119
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 125f493: fix(harness): forward validated `toolsContext` to host-executed tools in alignment with `ToolLoopAgent`
|
|
8
|
+
- Updated dependencies [0343bb1]
|
|
9
|
+
- Updated dependencies [2b105fa]
|
|
10
|
+
- Updated dependencies [125f493]
|
|
11
|
+
- ai@7.0.109
|
|
12
|
+
|
|
13
|
+
## 1.0.118
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- d975097: feat(harness): add `AbortSignal` to `SandboxChannel.connect`, plus a `sleep()` helper function
|
|
18
|
+
- b2baeba: fix(harness): preserve work directory text inside longer path segments
|
|
19
|
+
- Updated dependencies [3f6852a]
|
|
20
|
+
- Updated dependencies [6317504]
|
|
21
|
+
- Updated dependencies [3cb2dcd]
|
|
22
|
+
- Updated dependencies [ccf98e7]
|
|
23
|
+
- ai@7.0.108
|
|
24
|
+
|
|
3
25
|
## 1.0.117
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
|
|
2
|
-
import { Experimental_SandboxSession, UserModelMessage, ToolResultPart, ProviderOptions, ToolSet, FlexibleSchema, Tool, Context, SystemModelMessage, MaybePromiseLike, Arrayable, ToolApprovalResponse, ModelMessage } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { Experimental_SandboxSession, UserModelMessage, ToolResultPart, ProviderOptions, ToolSet, FlexibleSchema, Tool, Context, InferToolSetContext, SystemModelMessage, MaybePromiseLike, Arrayable, ToolApprovalResponse, ModelMessage } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { ToolsContextSettings } from 'ai/internal';
|
|
3
4
|
import { OutputInterface, AgentCallParameters, Prompt, StopCondition, GenerateTextOnStartCallback, GenerateTextOnStepStartCallback, OnLanguageModelCallStartCallback, OnLanguageModelCallEndCallback, OnToolExecutionStartCallback, OnToolExecutionEndCallback, GenerateTextOnStepEndCallback, GenerateTextOnEndCallback, ToolApprovalStatus, TelemetryOptions, ActiveTools, StreamTextResult, Agent, GenerateTextResult, AgentStreamParameters, Telemetry } from 'ai';
|
|
4
5
|
import { z } from 'zod/v4';
|
|
5
6
|
import { JSONSchema7, JSONValue, LanguageModelV4StreamPart, LanguageModelV4ToolCall, LanguageModelV4ToolApprovalRequest, LanguageModelV4ToolResult, LanguageModelV4FinishReason, LanguageModelV4Usage, AISDKError } from '@ai-sdk/provider';
|
|
@@ -1344,6 +1345,12 @@ type HarnessAgentSettings<THarness extends HarnessAgentAdapter<any> = HarnessAge
|
|
|
1344
1345
|
* declare a tool with the same name as a builtin to override.
|
|
1345
1346
|
*/
|
|
1346
1347
|
readonly tools?: TUserTools;
|
|
1348
|
+
/**
|
|
1349
|
+
* Per-tool context passed to host-executed tools. Each entry is validated
|
|
1350
|
+
* against the matching tool's `contextSchema` before execution.
|
|
1351
|
+
* `prepareCall` can replace it for each new turn.
|
|
1352
|
+
*/
|
|
1353
|
+
readonly toolsContext?: InferToolSetContext<TUserTools>;
|
|
1347
1354
|
/**
|
|
1348
1355
|
* Skills made available to the underlying runtime. Each adapter decides how
|
|
1349
1356
|
* to surface skills. `prepareCall` can replace them between completed turns.
|
|
@@ -1383,7 +1390,11 @@ type HarnessAgentSettings<THarness extends HarnessAgentAdapter<any> = HarnessAge
|
|
|
1383
1390
|
* })
|
|
1384
1391
|
* ```
|
|
1385
1392
|
*/
|
|
1386
|
-
readonly prepareCall?: (options: Omit<AgentCallParameters<CALL_OPTIONS, HarnessAllTools<THarness, TUserTools>, RUNTIME_CONTEXT>, 'abortSignal' | 'timeout' | 'onStart' | 'experimental_onStart' | 'onStepStart' | 'experimental_onStepStart' | 'onToolExecutionStart' | 'experimental_onToolCallStart' | 'onToolExecutionEnd' | 'experimental_onToolCallFinish' | 'onStepEnd' | 'onStepFinish' | 'onEnd' | 'onFinish' | 'experimental_sandbox'> & Pick<HarnessAgentSettings<THarness, TUserTools, RUNTIME_CONTEXT, NoInfer<OUTPUT>, CALL_OPTIONS>, 'model' | 'skills' | 'instructions' | 'tools'>
|
|
1393
|
+
readonly prepareCall?: (options: Omit<AgentCallParameters<CALL_OPTIONS, HarnessAllTools<THarness, TUserTools>, RUNTIME_CONTEXT>, 'abortSignal' | 'timeout' | 'onStart' | 'experimental_onStart' | 'onStepStart' | 'experimental_onStepStart' | 'onToolExecutionStart' | 'experimental_onToolCallStart' | 'onToolExecutionEnd' | 'experimental_onToolCallFinish' | 'onStepEnd' | 'onStepFinish' | 'onEnd' | 'onFinish' | 'experimental_sandbox'> & Pick<HarnessAgentSettings<THarness, TUserTools, RUNTIME_CONTEXT, NoInfer<OUTPUT>, CALL_OPTIONS>, 'model' | 'skills' | 'instructions' | 'tools'> & {
|
|
1394
|
+
toolsContext: InferToolSetContext<TUserTools>;
|
|
1395
|
+
}) => MaybePromiseLike<Pick<HarnessAgentSettings<THarness, TUserTools, RUNTIME_CONTEXT, NoInfer<OUTPUT>, CALL_OPTIONS>, 'model' | 'skills' | 'instructions' | 'tools'> & {
|
|
1396
|
+
toolsContext: InferToolSetContext<TUserTools>;
|
|
1397
|
+
} & Omit<Prompt, 'system' | 'instructions' | 'allowSystemInMessages'>>;
|
|
1387
1398
|
/**
|
|
1388
1399
|
* Optional specification for generating typed output. The same output
|
|
1389
1400
|
* requirement is active for every turn run by this agent.
|
|
@@ -1478,7 +1489,7 @@ type HarnessAgentSettings<THarness extends HarnessAgentAdapter<any> = HarnessAge
|
|
|
1478
1489
|
* stderr default — wire this to capture diagnostics in code.
|
|
1479
1490
|
*/
|
|
1480
1491
|
readonly onLog?: (event: HarnessDiagnostic) => void;
|
|
1481
|
-
} & HarnessAgentToolFilteringSettings<HarnessAllTools<THarness, TUserTools>>;
|
|
1492
|
+
} & ToolsContextSettings<TUserTools> & HarnessAgentToolFilteringSettings<HarnessAllTools<THarness, TUserTools>>;
|
|
1482
1493
|
|
|
1483
1494
|
type HarnessAgentLifecycleCallbacks<TOOLS extends ToolSet, RUNTIME_CONTEXT extends Context, OUTPUT extends OutputInterface> = {
|
|
1484
1495
|
onStart?: GenerateTextOnStartCallback<TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
@@ -1533,6 +1544,7 @@ declare class HarnessAgentSession {
|
|
|
1533
1544
|
private suspendedTurnState;
|
|
1534
1545
|
private activeTurnSettings;
|
|
1535
1546
|
private persistedTurnSettings;
|
|
1547
|
+
private readonly resumedToolsContext;
|
|
1536
1548
|
/**
|
|
1537
1549
|
* Whether this session was created from `resumeFrom` or `continueFrom`.
|
|
1538
1550
|
* Captured at construction so it survives lifecycle cleanup.
|
|
@@ -1549,6 +1561,7 @@ declare class HarnessAgentSession {
|
|
|
1549
1561
|
pendingToolApprovals?: readonly HarnessAgentPendingToolApproval[];
|
|
1550
1562
|
pendingToolResults?: readonly HarnessAgentPendingToolResult[];
|
|
1551
1563
|
turnSettings?: HarnessV1TurnSettings;
|
|
1564
|
+
resumedToolsContext?: Record<string, Context | undefined>;
|
|
1552
1565
|
turnState?: HarnessAgentTurnState;
|
|
1553
1566
|
});
|
|
1554
1567
|
hasUnfinishedTurn(): boolean;
|
|
@@ -1558,6 +1571,7 @@ declare class HarnessAgentSession {
|
|
|
1558
1571
|
skills: ReadonlyArray<HarnessV1Skill>;
|
|
1559
1572
|
instructions: string | undefined;
|
|
1560
1573
|
tools: TOOLS;
|
|
1574
|
+
toolsContext: InferToolSetContext<TOOLS>;
|
|
1561
1575
|
activeTools: ToolSet;
|
|
1562
1576
|
toolSpecs: HarnessAgentToolSpec[];
|
|
1563
1577
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -1574,6 +1588,7 @@ declare class HarnessAgentSession {
|
|
|
1574
1588
|
skills: ReadonlyArray<HarnessV1Skill>;
|
|
1575
1589
|
instructions: string | undefined;
|
|
1576
1590
|
tools: TOOLS;
|
|
1591
|
+
toolsContext: InferToolSetContext<TOOLS>;
|
|
1577
1592
|
activeTools: ToolSet;
|
|
1578
1593
|
toolSpecs: HarnessAgentToolSpec[];
|
|
1579
1594
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -1756,6 +1771,13 @@ declare class HarnessAgent<THarness extends HarnessAgentAdapter<any> = HarnessAg
|
|
|
1756
1771
|
* handing it to the adapter.
|
|
1757
1772
|
*/
|
|
1758
1773
|
continueFrom?: HarnessAgentContinueTurnState;
|
|
1774
|
+
/**
|
|
1775
|
+
* Rebinds host-only tool context for an unfinished turn resumed with
|
|
1776
|
+
* `continueFrom` (directly or through `resumeFrom`). Tool context is not
|
|
1777
|
+
* serialized into lifecycle state because it may contain credentials or
|
|
1778
|
+
* non-serializable host objects.
|
|
1779
|
+
*/
|
|
1780
|
+
toolsContext?: ToolsContextSettings<TUserTools>['toolsContext'];
|
|
1759
1781
|
/**
|
|
1760
1782
|
* Existing sandbox session to run the harness in. When provided, the
|
|
1761
1783
|
* caller retains ownership of the sandbox lifecycle.
|
package/dist/agent/index.js
CHANGED
|
@@ -164,7 +164,11 @@ import {
|
|
|
164
164
|
import {
|
|
165
165
|
getErrorMessage
|
|
166
166
|
} from "@ai-sdk/provider";
|
|
167
|
-
import {
|
|
167
|
+
import {
|
|
168
|
+
asLanguageModelUsage as asLanguageModelUsage2,
|
|
169
|
+
parseToolCall,
|
|
170
|
+
validateToolContext
|
|
171
|
+
} from "ai/internal";
|
|
168
172
|
|
|
169
173
|
// src/agent/internal/harness-stream-text-result.ts
|
|
170
174
|
import {
|
|
@@ -851,6 +855,11 @@ function notSupportedYet(feature) {
|
|
|
851
855
|
);
|
|
852
856
|
}
|
|
853
857
|
|
|
858
|
+
// src/agent/internal/get-own.ts
|
|
859
|
+
function getOwn(obj, key) {
|
|
860
|
+
return obj != null && Object.prototype.hasOwnProperty.call(obj, key) ? obj[key] : void 0;
|
|
861
|
+
}
|
|
862
|
+
|
|
854
863
|
// src/agent/internal/translate-stream-part.ts
|
|
855
864
|
import { generateId } from "@ai-sdk/provider-utils";
|
|
856
865
|
function translateStreamPart(event, options = {}) {
|
|
@@ -1014,30 +1023,44 @@ function translateStreamPart(event, options = {}) {
|
|
|
1014
1023
|
function createToolInputWorkDirStripper({
|
|
1015
1024
|
sessionWorkDir
|
|
1016
1025
|
}) {
|
|
1017
|
-
const
|
|
1026
|
+
const stateByToolCallId = /* @__PURE__ */ new Map();
|
|
1018
1027
|
return (part) => {
|
|
1019
1028
|
var _a4;
|
|
1020
1029
|
if (sessionWorkDir.length === 0) return [part];
|
|
1021
1030
|
if (part.type === "tool-input-start") {
|
|
1022
|
-
|
|
1031
|
+
stateByToolCallId.set(part.id, {
|
|
1032
|
+
pending: "",
|
|
1033
|
+
precedingCharacter: void 0
|
|
1034
|
+
});
|
|
1023
1035
|
return [part];
|
|
1024
1036
|
}
|
|
1025
1037
|
if (part.type === "tool-input-delta") {
|
|
1038
|
+
const state2 = (_a4 = stateByToolCallId.get(part.id)) != null ? _a4 : {
|
|
1039
|
+
pending: "",
|
|
1040
|
+
precedingCharacter: void 0
|
|
1041
|
+
};
|
|
1042
|
+
const value = state2.pending + part.delta;
|
|
1026
1043
|
const stripped2 = stripStreamingString({
|
|
1027
|
-
value
|
|
1044
|
+
value,
|
|
1028
1045
|
workDir: sessionWorkDir,
|
|
1029
|
-
final: false
|
|
1046
|
+
final: false,
|
|
1047
|
+
precedingCharacter: state2.precedingCharacter
|
|
1048
|
+
});
|
|
1049
|
+
const pendingStart = value.length - stripped2.pending.length;
|
|
1050
|
+
stateByToolCallId.set(part.id, {
|
|
1051
|
+
pending: stripped2.pending,
|
|
1052
|
+
precedingCharacter: stripped2.pending.length > 0 ? pendingStart > 0 ? value[pendingStart - 1] : state2.precedingCharacter : value.length > 0 ? value[value.length - 1] : state2.precedingCharacter
|
|
1030
1053
|
});
|
|
1031
|
-
pendingByToolCallId.set(part.id, stripped2.pending);
|
|
1032
1054
|
return stripped2.output.length === 0 ? [] : [{ ...part, delta: stripped2.output }];
|
|
1033
1055
|
}
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
if (
|
|
1056
|
+
const state = stateByToolCallId.get(part.id);
|
|
1057
|
+
stateByToolCallId.delete(part.id);
|
|
1058
|
+
if (state == null || state.pending.length === 0) return [part];
|
|
1037
1059
|
const stripped = stripStreamingString({
|
|
1038
|
-
value: pending,
|
|
1060
|
+
value: state.pending,
|
|
1039
1061
|
workDir: sessionWorkDir,
|
|
1040
|
-
final: true
|
|
1062
|
+
final: true,
|
|
1063
|
+
precedingCharacter: state.precedingCharacter
|
|
1041
1064
|
});
|
|
1042
1065
|
return stripped.output.length === 0 ? [part] : [
|
|
1043
1066
|
{ type: "tool-input-delta", id: part.id, delta: stripped.output },
|
|
@@ -1064,34 +1087,59 @@ function stripWorkDir(part, sessionWorkDir) {
|
|
|
1064
1087
|
}
|
|
1065
1088
|
}
|
|
1066
1089
|
function stripString(value, workDir) {
|
|
1067
|
-
return
|
|
1090
|
+
return stripStreamingString({
|
|
1091
|
+
value,
|
|
1092
|
+
workDir,
|
|
1093
|
+
final: true,
|
|
1094
|
+
precedingCharacter: void 0
|
|
1095
|
+
}).output;
|
|
1068
1096
|
}
|
|
1069
1097
|
function stripStreamingString({
|
|
1070
1098
|
value,
|
|
1071
1099
|
workDir,
|
|
1072
|
-
final
|
|
1100
|
+
final,
|
|
1101
|
+
precedingCharacter
|
|
1073
1102
|
}) {
|
|
1074
1103
|
let remaining = value;
|
|
1075
1104
|
let output = "";
|
|
1105
|
+
let characterBeforeRemaining = precedingCharacter;
|
|
1076
1106
|
while (remaining.length > 0) {
|
|
1077
1107
|
const matchIndex = remaining.indexOf(workDir);
|
|
1078
1108
|
if (matchIndex >= 0) {
|
|
1079
|
-
output += remaining.slice(0, matchIndex);
|
|
1080
1109
|
const followingIndex = matchIndex + workDir.length;
|
|
1081
|
-
|
|
1082
|
-
|
|
1110
|
+
const hasPathBoundary = isPathBoundary(
|
|
1111
|
+
remaining,
|
|
1112
|
+
matchIndex,
|
|
1113
|
+
characterBeforeRemaining
|
|
1114
|
+
);
|
|
1115
|
+
if (hasPathBoundary && followingIndex === remaining.length && !final) {
|
|
1116
|
+
return {
|
|
1117
|
+
output: output + remaining.slice(0, matchIndex),
|
|
1118
|
+
pending: remaining.slice(matchIndex)
|
|
1119
|
+
};
|
|
1083
1120
|
}
|
|
1084
|
-
|
|
1121
|
+
const isPath = hasPathBoundary && (followingIndex === remaining.length || remaining[followingIndex] === "/" || isPathTerminator(remaining[followingIndex]));
|
|
1122
|
+
if (!isPath) {
|
|
1123
|
+
output += remaining.slice(0, followingIndex);
|
|
1124
|
+
characterBeforeRemaining = remaining[followingIndex - 1];
|
|
1125
|
+
remaining = remaining.slice(followingIndex);
|
|
1126
|
+
} else if (remaining[followingIndex] === "/") {
|
|
1127
|
+
output += remaining.slice(0, matchIndex);
|
|
1128
|
+
characterBeforeRemaining = remaining[followingIndex];
|
|
1085
1129
|
remaining = remaining.slice(followingIndex + 1);
|
|
1086
1130
|
} else {
|
|
1087
|
-
output += ".";
|
|
1131
|
+
output += remaining.slice(0, matchIndex) + ".";
|
|
1088
1132
|
remaining = remaining.slice(followingIndex);
|
|
1089
1133
|
}
|
|
1090
1134
|
continue;
|
|
1091
1135
|
}
|
|
1092
1136
|
if (final) return { output: output + remaining, pending: "" };
|
|
1093
1137
|
let pendingLength = Math.min(remaining.length, workDir.length - 1);
|
|
1094
|
-
while (pendingLength > 0 && !workDir.startsWith(remaining.slice(-pendingLength))
|
|
1138
|
+
while (pendingLength > 0 && (!workDir.startsWith(remaining.slice(-pendingLength)) || !isPathBoundary(
|
|
1139
|
+
remaining,
|
|
1140
|
+
remaining.length - pendingLength,
|
|
1141
|
+
characterBeforeRemaining
|
|
1142
|
+
))) {
|
|
1095
1143
|
pendingLength -= 1;
|
|
1096
1144
|
}
|
|
1097
1145
|
const outputLength = remaining.length - pendingLength;
|
|
@@ -1102,6 +1150,13 @@ function stripStreamingString({
|
|
|
1102
1150
|
}
|
|
1103
1151
|
return { output, pending: "" };
|
|
1104
1152
|
}
|
|
1153
|
+
function isPathBoundary(value, index, precedingCharacter) {
|
|
1154
|
+
const character = index === 0 ? precedingCharacter : value[index - 1];
|
|
1155
|
+
return character === void 0 || /[\s"'`=]/.test(character);
|
|
1156
|
+
}
|
|
1157
|
+
function isPathTerminator(character) {
|
|
1158
|
+
return character === void 0 || /[\s"'`;|&<>()]/.test(character);
|
|
1159
|
+
}
|
|
1105
1160
|
function stripDeep(value, workDir) {
|
|
1106
1161
|
if (typeof value === "string") return stripString(value, workDir);
|
|
1107
1162
|
if (Array.isArray(value)) return value.map((item) => stripDeep(item, workDir));
|
|
@@ -1479,29 +1534,29 @@ function unwrapToolResultOutput(toolResult) {
|
|
|
1479
1534
|
}
|
|
1480
1535
|
}
|
|
1481
1536
|
function runPrompt(input) {
|
|
1482
|
-
var _a4, _b4, _c, _d, _e, _f, _g, _h, _i;
|
|
1537
|
+
var _a4, _b4, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1483
1538
|
const callId = generateId2();
|
|
1484
|
-
const toolsContext = {};
|
|
1539
|
+
const toolsContext = (_a4 = input.toolsContext) != null ? _a4 : {};
|
|
1485
1540
|
const result = new HarnessStreamTextResult({
|
|
1486
1541
|
tools: input.tools,
|
|
1487
1542
|
runtimeContext: input.runtimeContext,
|
|
1488
1543
|
toolsContext,
|
|
1489
1544
|
harnessId: input.harness.harnessId,
|
|
1490
1545
|
callId,
|
|
1491
|
-
modelId: (
|
|
1546
|
+
modelId: (_b4 = input.model) != null ? _b4 : "",
|
|
1492
1547
|
output: input.output
|
|
1493
1548
|
});
|
|
1494
|
-
const pendingToolApprovals = (
|
|
1495
|
-
const pendingToolResults = (
|
|
1496
|
-
const onPendingToolApproval = (
|
|
1549
|
+
const pendingToolApprovals = (_c = input.pendingToolApprovals) != null ? _c : [];
|
|
1550
|
+
const pendingToolResults = (_d = input.pendingToolResults) != null ? _d : [];
|
|
1551
|
+
const onPendingToolApproval = (_e = input.onPendingToolApproval) != null ? _e : (() => {
|
|
1497
1552
|
});
|
|
1498
|
-
const onToolApprovalSettled = (
|
|
1553
|
+
const onToolApprovalSettled = (_f = input.onToolApprovalSettled) != null ? _f : (() => {
|
|
1499
1554
|
});
|
|
1500
|
-
const onPendingToolResult = (
|
|
1555
|
+
const onPendingToolResult = (_g = input.onPendingToolResult) != null ? _g : (() => {
|
|
1501
1556
|
});
|
|
1502
|
-
const onToolResultSettled = (
|
|
1557
|
+
const onToolResultSettled = (_h = input.onToolResultSettled) != null ? _h : (() => {
|
|
1503
1558
|
});
|
|
1504
|
-
const activeTools = (
|
|
1559
|
+
const activeTools = (_i = input.activeTools) != null ? _i : input.tools;
|
|
1505
1560
|
const activeToolNames = Object.keys(input.tools).filter(
|
|
1506
1561
|
(toolName) => Object.prototype.hasOwnProperty.call(activeTools, toolName) || Object.prototype.hasOwnProperty.call(
|
|
1507
1562
|
input.harness.builtinTools,
|
|
@@ -1514,7 +1569,7 @@ function runPrompt(input) {
|
|
|
1514
1569
|
const lifecycle = createTurnLifecycle({
|
|
1515
1570
|
callId,
|
|
1516
1571
|
telemetry: input.telemetry,
|
|
1517
|
-
callbacks: (
|
|
1572
|
+
callbacks: (_j = input.callbacks) != null ? _j : {},
|
|
1518
1573
|
harnessId: input.harness.harnessId,
|
|
1519
1574
|
modelId: input.model,
|
|
1520
1575
|
instructions: input.instructions,
|
|
@@ -1541,7 +1596,7 @@ function runPrompt(input) {
|
|
|
1541
1596
|
result.fail(err);
|
|
1542
1597
|
};
|
|
1543
1598
|
const done = (async () => {
|
|
1544
|
-
var _a5, _b5, _c2, _d2, _e2, _f2, _g2, _h2, _i2,
|
|
1599
|
+
var _a5, _b5, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k, _l, _m, _n, _o;
|
|
1545
1600
|
let bridge;
|
|
1546
1601
|
try {
|
|
1547
1602
|
bridge = await toHarnessStream({
|
|
@@ -1926,6 +1981,7 @@ function runPrompt(input) {
|
|
|
1926
1981
|
const execution = await maybeExecuteHostTool({
|
|
1927
1982
|
event: rawToolCall,
|
|
1928
1983
|
tools: activeTools,
|
|
1984
|
+
toolsContext,
|
|
1929
1985
|
wrappedExecuteTool: lifecycle.executeTool,
|
|
1930
1986
|
sandboxSession: input.sandboxSession,
|
|
1931
1987
|
abortSignal: input.abortSignal,
|
|
@@ -2177,7 +2233,7 @@ function runPrompt(input) {
|
|
|
2177
2233
|
toolName: toolCall.toolName,
|
|
2178
2234
|
input: (_i2 = rawToolCall == null ? void 0 : rawToolCall.input) != null ? _i2 : JSON.stringify(toolCall.input),
|
|
2179
2235
|
kind: "builtin",
|
|
2180
|
-
providerExecuted: (
|
|
2236
|
+
providerExecuted: (_j2 = rawToolCall == null ? void 0 : rawToolCall.providerExecuted) != null ? _j2 : true,
|
|
2181
2237
|
...(rawToolCall == null ? void 0 : rawToolCall.nativeName) !== void 0 ? { nativeName: rawToolCall.nativeName } : {}
|
|
2182
2238
|
};
|
|
2183
2239
|
pendingApprovalsByApprovalId.set(
|
|
@@ -2372,6 +2428,7 @@ function runPrompt(input) {
|
|
|
2372
2428
|
const execution = await maybeExecuteHostTool({
|
|
2373
2429
|
event: toolCall,
|
|
2374
2430
|
tools: activeTools,
|
|
2431
|
+
toolsContext,
|
|
2375
2432
|
wrappedExecuteTool: lifecycle.executeTool,
|
|
2376
2433
|
sandboxSession: input.sandboxSession,
|
|
2377
2434
|
abortSignal: input.abortSignal,
|
|
@@ -2483,6 +2540,21 @@ async function maybeExecuteHostTool(input) {
|
|
|
2483
2540
|
if (!isExecutableTool(tool)) return { executed: false };
|
|
2484
2541
|
const parsed = await safeParseJSON2({ text: input.event.input });
|
|
2485
2542
|
const args = parsed.success ? parsed.value : input.event.input;
|
|
2543
|
+
let context;
|
|
2544
|
+
try {
|
|
2545
|
+
context = await validateToolContext({
|
|
2546
|
+
toolName: input.event.toolName,
|
|
2547
|
+
context: getOwn(input.toolsContext, input.event.toolName),
|
|
2548
|
+
contextSchema: tool.contextSchema
|
|
2549
|
+
});
|
|
2550
|
+
} catch (err) {
|
|
2551
|
+
await input.submitToolResult({
|
|
2552
|
+
toolCallId: input.event.toolCallId,
|
|
2553
|
+
output: { error: "Tool context validation failed." },
|
|
2554
|
+
isError: true
|
|
2555
|
+
});
|
|
2556
|
+
return { executed: true, outcome: { ok: false, error: err } };
|
|
2557
|
+
}
|
|
2486
2558
|
try {
|
|
2487
2559
|
const output = await input.wrappedExecuteTool({
|
|
2488
2560
|
toolCallId: input.event.toolCallId,
|
|
@@ -2495,7 +2567,7 @@ async function maybeExecuteHostTool(input) {
|
|
|
2495
2567
|
toolCallId: input.event.toolCallId,
|
|
2496
2568
|
messages: [],
|
|
2497
2569
|
abortSignal: input.abortSignal,
|
|
2498
|
-
context
|
|
2570
|
+
context,
|
|
2499
2571
|
experimental_sandbox: input.sandboxSession
|
|
2500
2572
|
}
|
|
2501
2573
|
});
|
|
@@ -2584,6 +2656,7 @@ var HarnessAgentSession = class {
|
|
|
2584
2656
|
this.pendingToolResults.set(pendingResult.toolCallId, pendingResult);
|
|
2585
2657
|
}
|
|
2586
2658
|
this.persistedTurnSettings = options.turnSettings;
|
|
2659
|
+
this.resumedToolsContext = options.resumedToolsContext;
|
|
2587
2660
|
this.turnState = (_d = options.turnState) != null ? _d : this.pendingToolApprovals.size > 0 ? "awaiting-approval" : this.pendingToolResults.size > 0 ? "awaiting-tool-result" : "idle";
|
|
2588
2661
|
this.isResume = options.underlyingSession.isResume;
|
|
2589
2662
|
}
|
|
@@ -2624,6 +2697,7 @@ var HarnessAgentSession = class {
|
|
|
2624
2697
|
this.activeTurnSettings = {
|
|
2625
2698
|
persisted: this.persistedTurnSettings,
|
|
2626
2699
|
tools: options.tools,
|
|
2700
|
+
toolsContext: options.toolsContext,
|
|
2627
2701
|
activeTools: options.activeTools,
|
|
2628
2702
|
builtinToolFiltering: options.builtinToolFiltering
|
|
2629
2703
|
};
|
|
@@ -2638,6 +2712,7 @@ var HarnessAgentSession = class {
|
|
|
2638
2712
|
skills: options.skills,
|
|
2639
2713
|
instructions: options.instructions,
|
|
2640
2714
|
tools: options.tools,
|
|
2715
|
+
toolsContext: options.toolsContext,
|
|
2641
2716
|
activeTools: options.activeTools,
|
|
2642
2717
|
toolSpecs: options.toolSpecs,
|
|
2643
2718
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
@@ -2697,6 +2772,7 @@ var HarnessAgentSession = class {
|
|
|
2697
2772
|
skills: options.skills,
|
|
2698
2773
|
instructions: options.instructions,
|
|
2699
2774
|
tools: options.tools,
|
|
2775
|
+
toolsContext: options.toolsContext,
|
|
2700
2776
|
activeTools: options.activeTools,
|
|
2701
2777
|
toolSpecs: options.toolSpecs,
|
|
2702
2778
|
builtinToolFiltering: options.builtinToolFiltering
|
|
@@ -2712,6 +2788,7 @@ var HarnessAgentSession = class {
|
|
|
2712
2788
|
skills: turnSettings.persisted.skills,
|
|
2713
2789
|
instructions: turnSettings.persisted.instructions,
|
|
2714
2790
|
tools: turnSettings.tools,
|
|
2791
|
+
toolsContext: turnSettings.toolsContext,
|
|
2715
2792
|
activeTools: turnSettings.activeTools,
|
|
2716
2793
|
toolSpecs: [...turnSettings.persisted.tools],
|
|
2717
2794
|
builtinToolFiltering: turnSettings.builtinToolFiltering,
|
|
@@ -3076,7 +3153,7 @@ var HarnessAgentSession = class {
|
|
|
3076
3153
|
this.turnState = "idle";
|
|
3077
3154
|
}
|
|
3078
3155
|
resolveActiveTurnSettings(options) {
|
|
3079
|
-
var _a4;
|
|
3156
|
+
var _a4, _b4;
|
|
3080
3157
|
if (this.activeTurnSettings != null) {
|
|
3081
3158
|
return this.activeTurnSettings;
|
|
3082
3159
|
}
|
|
@@ -3100,6 +3177,7 @@ var HarnessAgentSession = class {
|
|
|
3100
3177
|
this.activeTurnSettings = {
|
|
3101
3178
|
persisted,
|
|
3102
3179
|
tools: options.tools,
|
|
3180
|
+
toolsContext: (_b4 = this.resumedToolsContext) != null ? _b4 : options.toolsContext,
|
|
3103
3181
|
activeTools,
|
|
3104
3182
|
builtinToolFiltering: options.builtinToolFiltering
|
|
3105
3183
|
};
|
|
@@ -3722,6 +3800,11 @@ var HarnessAgent = class {
|
|
|
3722
3800
|
});
|
|
3723
3801
|
}
|
|
3724
3802
|
const effectiveContinueFrom = validatedContinueFrom != null ? validatedContinueFrom : validatedResumeFrom == null ? void 0 : validatedResumeFrom.continueFrom;
|
|
3803
|
+
if ((options == null ? void 0 : options.toolsContext) != null && effectiveContinueFrom == null) {
|
|
3804
|
+
throw new Error(
|
|
3805
|
+
"HarnessAgent.createSession: `toolsContext` can only rebind an unfinished turn from `continueFrom` or `resumeFrom`."
|
|
3806
|
+
);
|
|
3807
|
+
}
|
|
3725
3808
|
const isResumedSession = validatedResumeFrom != null || effectiveContinueFrom != null;
|
|
3726
3809
|
let sandboxSession;
|
|
3727
3810
|
let sessionWorkDir;
|
|
@@ -3884,6 +3967,7 @@ var HarnessAgent = class {
|
|
|
3884
3967
|
pendingToolApprovals: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.pendingToolApprovals,
|
|
3885
3968
|
pendingToolResults: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.pendingToolResults,
|
|
3886
3969
|
turnSettings: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.turnSettings,
|
|
3970
|
+
resumedToolsContext: options == null ? void 0 : options.toolsContext,
|
|
3887
3971
|
turnState: effectiveContinueFrom == null ? "idle" : effectiveContinueFrom.pendingToolApprovals != null && effectiveContinueFrom.pendingToolApprovals.length > 0 ? "awaiting-approval" : effectiveContinueFrom.pendingToolResults != null && effectiveContinueFrom.pendingToolResults.length > 0 ? "awaiting-tool-result" : "suspended"
|
|
3888
3972
|
});
|
|
3889
3973
|
} catch (error) {
|
|
@@ -4007,6 +4091,7 @@ var HarnessAgent = class {
|
|
|
4007
4091
|
skills: input.turnSettings.skills,
|
|
4008
4092
|
instructions: input.turnSettings.instructions,
|
|
4009
4093
|
tools: input.turnSettings.tools,
|
|
4094
|
+
toolsContext: input.turnSettings.toolsContext,
|
|
4010
4095
|
activeTools: input.turnSettings.activeTools,
|
|
4011
4096
|
toolSpecs: input.turnSettings.toolSpecs,
|
|
4012
4097
|
builtinToolFiltering: input.turnSettings.builtinToolFiltering,
|
|
@@ -4089,7 +4174,7 @@ var HarnessAgent = class {
|
|
|
4089
4174
|
throw new Error("HarnessAgent: either `prompt` or `messages` is required.");
|
|
4090
4175
|
}
|
|
4091
4176
|
async _preparePromptTurnInput(options) {
|
|
4092
|
-
var _a4, _b4, _c;
|
|
4177
|
+
var _a4, _b4, _c, _d;
|
|
4093
4178
|
let callOptions = options;
|
|
4094
4179
|
if (this.settings.callOptionsSchema != null && options.options !== void 0) {
|
|
4095
4180
|
const validatedOptions = await validateTypes({
|
|
@@ -4126,12 +4211,13 @@ var HarnessAgent = class {
|
|
|
4126
4211
|
skills: this.settings.skills,
|
|
4127
4212
|
instructions: this.settings.instructions,
|
|
4128
4213
|
tools: this.settings.tools,
|
|
4214
|
+
toolsContext: (_a4 = this.settings.toolsContext) != null ? _a4 : {},
|
|
4129
4215
|
...promptOptions
|
|
4130
4216
|
};
|
|
4131
|
-
const preparedCallArgs = (
|
|
4132
|
-
|
|
4217
|
+
const preparedCallArgs = (_d = await ((_c = (_b4 = this.settings).prepareCall) == null ? void 0 : _c.call(
|
|
4218
|
+
_b4,
|
|
4133
4219
|
baseCallArgs
|
|
4134
|
-
))) != null ?
|
|
4220
|
+
))) != null ? _d : baseCallArgs;
|
|
4135
4221
|
if (this._resolveContinueTurnInput(preparedCallArgs) != null) {
|
|
4136
4222
|
throw new Error(
|
|
4137
4223
|
"HarnessAgent.prepareCall must return a fresh user prompt, not a tool continuation."
|
|
@@ -4143,7 +4229,8 @@ var HarnessAgent = class {
|
|
|
4143
4229
|
model: preparedCallArgs.model,
|
|
4144
4230
|
skills: preparedCallArgs.skills,
|
|
4145
4231
|
instructions: preparedCallArgs.instructions,
|
|
4146
|
-
tools: preparedCallArgs.tools
|
|
4232
|
+
tools: preparedCallArgs.tools,
|
|
4233
|
+
toolsContext: preparedCallArgs.toolsContext
|
|
4147
4234
|
})
|
|
4148
4235
|
};
|
|
4149
4236
|
}
|
|
@@ -4154,14 +4241,15 @@ var HarnessAgent = class {
|
|
|
4154
4241
|
model: this.settings.model,
|
|
4155
4242
|
skills: this.settings.skills,
|
|
4156
4243
|
instructions: this.settings.instructions,
|
|
4157
|
-
tools: this.settings.tools
|
|
4244
|
+
tools: this.settings.tools,
|
|
4245
|
+
toolsContext: this.settings.toolsContext
|
|
4158
4246
|
}),
|
|
4159
4247
|
toolApprovalContinuations: (_a4 = options.toolApprovalContinuations) != null ? _a4 : [],
|
|
4160
4248
|
toolResultContinuations: (_b4 = options.toolResultContinuations) != null ? _b4 : []
|
|
4161
4249
|
};
|
|
4162
4250
|
}
|
|
4163
4251
|
_prepareTurnSettings(options) {
|
|
4164
|
-
var _a4, _b4, _c;
|
|
4252
|
+
var _a4, _b4, _c, _d;
|
|
4165
4253
|
const userTools = (_a4 = options.tools) != null ? _a4 : {};
|
|
4166
4254
|
assertNoReservedQuestionTool({
|
|
4167
4255
|
harness: this.settings.harness,
|
|
@@ -4183,6 +4271,7 @@ var HarnessAgent = class {
|
|
|
4183
4271
|
skills: (_b4 = options.skills) != null ? _b4 : [],
|
|
4184
4272
|
instructions: typeof options.instructions === "string" ? options.instructions : (_c = options.instructions) == null ? void 0 : _c.content,
|
|
4185
4273
|
tools,
|
|
4274
|
+
toolsContext: (_d = options.toolsContext) != null ? _d : {},
|
|
4186
4275
|
activeTools: toolFiltering.activeUserTools,
|
|
4187
4276
|
toolSpecs: this._toToolSpecs(toolFiltering.activeUserTools),
|
|
4188
4277
|
builtinToolFiltering: toolFiltering.builtinToolFiltering
|