@ai-sdk/harness 1.0.39 → 1.0.40
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 +19 -4
- package/dist/agent/index.js +140 -45
- package/dist/agent/index.js.map +1 -1
- package/dist/bridge/index.js +8 -1
- package/dist/bridge/index.js.map +1 -1
- package/dist/utils/index.d.ts +5 -1
- package/dist/utils/index.js +37 -5
- package/dist/utils/index.js.map +1 -1
- package/package.json +2 -2
- package/src/agent/harness-agent-session.ts +38 -8
- package/src/agent/harness-agent-settings.ts +25 -1
- package/src/agent/harness-agent.ts +17 -2
- package/src/agent/internal/run-prompt.ts +92 -21
- package/src/agent/internal/turn-telemetry.ts +18 -4
- package/src/bridge/index.ts +11 -1
- package/src/utils/sandbox-channel.ts +61 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @ai-sdk/harness
|
|
2
2
|
|
|
3
|
+
## 1.0.40
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 59a2306: fix(harness): execute host tools through telemetry context wrappers
|
|
8
|
+
- 5f65e61: feat(harness): add support for `stopWhen` control to `HarnessAgent` (e.g. `isStepCount(1)`)
|
|
9
|
+
- Updated dependencies [7f6650b]
|
|
10
|
+
- Updated dependencies [106ea59]
|
|
11
|
+
- ai@7.0.35
|
|
12
|
+
|
|
3
13
|
## 1.0.39
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
|
|
2
|
-
import { Experimental_SandboxSession, UserModelMessage, ToolSet, FlexibleSchema, Tool, ToolApprovalResponse, ModelMessage
|
|
3
|
-
import { ToolApprovalStatus, TelemetryOptions, ActiveTools, StreamTextResult, Agent, AgentCallParameters, GenerateTextResult, AgentStreamParameters, Telemetry } from 'ai';
|
|
2
|
+
import { Experimental_SandboxSession, UserModelMessage, ToolSet, FlexibleSchema, Tool, Context, Arrayable, ToolApprovalResponse, ModelMessage } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { StopCondition, ToolApprovalStatus, TelemetryOptions, ActiveTools, StreamTextResult, Agent, AgentCallParameters, GenerateTextResult, AgentStreamParameters, Telemetry } from 'ai';
|
|
4
4
|
import { z } from 'zod/v4';
|
|
5
5
|
import { JSONValue, LanguageModelV4ToolCall, LanguageModelV4ToolApprovalRequest, LanguageModelV4ToolResult, LanguageModelV4FinishReason, LanguageModelV4Usage, JSONSchema7, AISDKError } from '@ai-sdk/provider';
|
|
6
6
|
|
|
@@ -1143,7 +1143,7 @@ type HarnessAgentToolFilteringSettings<TOOLS extends ToolSet> = {
|
|
|
1143
1143
|
*/
|
|
1144
1144
|
readonly inactiveTools?: HarnessTools<TOOLS>;
|
|
1145
1145
|
};
|
|
1146
|
-
type HarnessAgentSettings<THarness extends HarnessAgentAdapter<any> = HarnessAgentAdapter, TUserTools extends ToolSet = {}> = {
|
|
1146
|
+
type HarnessAgentSettings<THarness extends HarnessAgentAdapter<any> = HarnessAgentAdapter, TUserTools extends ToolSet = {}, RUNTIME_CONTEXT extends Context = Context> = {
|
|
1147
1147
|
/**
|
|
1148
1148
|
* The harness adapter driving the underlying agent runtime. Its
|
|
1149
1149
|
* `builtinTools` are merged with the user-defined `tools` and exposed to
|
|
@@ -1177,6 +1177,16 @@ type HarnessAgentSettings<THarness extends HarnessAgentAdapter<any> = HarnessAge
|
|
|
1177
1177
|
* later turns or when resuming a previously ended session.
|
|
1178
1178
|
*/
|
|
1179
1179
|
readonly instructions?: string;
|
|
1180
|
+
/**
|
|
1181
|
+
* Conditions that stop the current result after a completed harness tool
|
|
1182
|
+
* step that can continue into another model step. The underlying turn remains
|
|
1183
|
+
* unfinished and can be suspended and continued.
|
|
1184
|
+
*
|
|
1185
|
+
* A terminal text-only step finishes naturally and is not stopped early.
|
|
1186
|
+
*
|
|
1187
|
+
* When omitted, the harness runs until the turn naturally finishes or pauses.
|
|
1188
|
+
*/
|
|
1189
|
+
readonly stopWhen?: Arrayable<StopCondition<NoInfer<HarnessAllTools<THarness, TUserTools>>, RUNTIME_CONTEXT>>;
|
|
1180
1190
|
/**
|
|
1181
1191
|
* Built-in tool permission mode. Defaults to `'allow-all'`, preserving the
|
|
1182
1192
|
* existing bypass-permissions behavior unless users opt in.
|
|
@@ -1303,6 +1313,7 @@ declare class HarnessAgentSession {
|
|
|
1303
1313
|
private turnState;
|
|
1304
1314
|
private turnSequence;
|
|
1305
1315
|
private activeTurnSequence;
|
|
1316
|
+
private suspendedTurnState;
|
|
1306
1317
|
/**
|
|
1307
1318
|
* Whether this session was created from `resumeFrom` or `continueFrom`.
|
|
1308
1319
|
* Captured at construction so it survives lifecycle cleanup.
|
|
@@ -1332,6 +1343,7 @@ declare class HarnessAgentSession {
|
|
|
1332
1343
|
runtimeContext: RUNTIME_CONTEXT;
|
|
1333
1344
|
abortSignal: AbortSignal | undefined;
|
|
1334
1345
|
telemetry: TelemetryOptions | undefined;
|
|
1346
|
+
stopConditions: ReadonlyArray<StopCondition<TOOLS, RUNTIME_CONTEXT>>;
|
|
1335
1347
|
}): HarnessAgentTurnResult<TOOLS, RUNTIME_CONTEXT>;
|
|
1336
1348
|
continueTurn<TOOLS extends ToolSet, RUNTIME_CONTEXT extends Context>(options: {
|
|
1337
1349
|
instructions: string | undefined;
|
|
@@ -1342,6 +1354,7 @@ declare class HarnessAgentSession {
|
|
|
1342
1354
|
runtimeContext: RUNTIME_CONTEXT;
|
|
1343
1355
|
abortSignal: AbortSignal | undefined;
|
|
1344
1356
|
telemetry: TelemetryOptions | undefined;
|
|
1357
|
+
stopConditions: ReadonlyArray<StopCondition<TOOLS, RUNTIME_CONTEXT>>;
|
|
1345
1358
|
toolApprovalContinuations?: readonly HarnessAgentToolApprovalContinuation[] | undefined;
|
|
1346
1359
|
toolResultContinuations?: readonly HarnessAgentToolResultContinuation[] | undefined;
|
|
1347
1360
|
}): HarnessAgentTurnResult<TOOLS, RUNTIME_CONTEXT>;
|
|
@@ -1392,6 +1405,7 @@ declare class HarnessAgentSession {
|
|
|
1392
1405
|
private getPendingToolResults;
|
|
1393
1406
|
private addPendingToolState;
|
|
1394
1407
|
private suspendCurrentTurn;
|
|
1408
|
+
private captureStopConditionBoundary;
|
|
1395
1409
|
private toResumeStateWithContinuation;
|
|
1396
1410
|
private requirePromptableTurn;
|
|
1397
1411
|
private requireContinuableTurn;
|
|
@@ -1461,11 +1475,12 @@ declare class HarnessAgent<THarness extends HarnessAgentAdapter<any> = HarnessAg
|
|
|
1461
1475
|
*/
|
|
1462
1476
|
readonly tools: HarnessAllTools<THarness, TUserTools>;
|
|
1463
1477
|
private readonly settings;
|
|
1478
|
+
private readonly stopConditions;
|
|
1464
1479
|
private readonly sandboxConfig;
|
|
1465
1480
|
private readonly activeUserTools;
|
|
1466
1481
|
private readonly builtinToolFiltering;
|
|
1467
1482
|
private readonly permissionMode;
|
|
1468
|
-
constructor(settings: HarnessAgentSettings<THarness, TUserTools>);
|
|
1483
|
+
constructor(settings: HarnessAgentSettings<THarness, TUserTools, RUNTIME_CONTEXT>);
|
|
1469
1484
|
/** Identifier of the harness backing this agent. */
|
|
1470
1485
|
get harnessId(): string;
|
|
1471
1486
|
/**
|
package/dist/agent/index.js
CHANGED
|
@@ -40,6 +40,7 @@ var HarnessCapabilityUnsupportedError = class extends (_b2 = HarnessError, _a2 =
|
|
|
40
40
|
|
|
41
41
|
// src/agent/harness-agent.ts
|
|
42
42
|
import {
|
|
43
|
+
asArray as asArray2,
|
|
43
44
|
asSchema,
|
|
44
45
|
generateId as generateId5
|
|
45
46
|
} from "@ai-sdk/provider-utils";
|
|
@@ -181,7 +182,7 @@ import {
|
|
|
181
182
|
executeTool,
|
|
182
183
|
generateId as generateId4,
|
|
183
184
|
isExecutableTool,
|
|
184
|
-
safeParseJSON
|
|
185
|
+
safeParseJSON as safeParseJSON2
|
|
185
186
|
} from "@ai-sdk/provider-utils";
|
|
186
187
|
import {
|
|
187
188
|
getErrorMessage
|
|
@@ -924,7 +925,10 @@ var NOOP = {
|
|
|
924
925
|
},
|
|
925
926
|
stepFinish() {
|
|
926
927
|
},
|
|
927
|
-
toolStart() {
|
|
928
|
+
async toolStart() {
|
|
929
|
+
},
|
|
930
|
+
async executeTool({ execute }) {
|
|
931
|
+
return await execute();
|
|
928
932
|
},
|
|
929
933
|
toolEnd() {
|
|
930
934
|
},
|
|
@@ -1083,11 +1087,12 @@ function createTurnTelemetry(opts) {
|
|
|
1083
1087
|
stepOpen = false;
|
|
1084
1088
|
stepNumber += 1;
|
|
1085
1089
|
},
|
|
1086
|
-
toolStart(call) {
|
|
1090
|
+
async toolStart(call) {
|
|
1087
1091
|
var _a4;
|
|
1088
1092
|
ensureStepOpen();
|
|
1093
|
+
if (openTools.has(call.toolCallId)) return;
|
|
1089
1094
|
openTools.set(call.toolCallId, call);
|
|
1090
|
-
(_a4 = dispatcher.onToolExecutionStart) == null ? void 0 : _a4.call(
|
|
1095
|
+
await ((_a4 = dispatcher.onToolExecutionStart) == null ? void 0 : _a4.call(
|
|
1091
1096
|
dispatcher,
|
|
1092
1097
|
cast({
|
|
1093
1098
|
callId,
|
|
@@ -1101,7 +1106,11 @@ function createTurnTelemetry(opts) {
|
|
|
1101
1106
|
},
|
|
1102
1107
|
toolContext: void 0
|
|
1103
1108
|
})
|
|
1104
|
-
);
|
|
1109
|
+
));
|
|
1110
|
+
},
|
|
1111
|
+
async executeTool({ toolCallId, execute }) {
|
|
1112
|
+
if (dispatcher.executeTool == null) return await execute();
|
|
1113
|
+
return await dispatcher.executeTool({ callId, toolCallId, execute });
|
|
1105
1114
|
},
|
|
1106
1115
|
toolEnd(toolCallId, output) {
|
|
1107
1116
|
var _a4;
|
|
@@ -1263,6 +1272,20 @@ function logBridgeError({
|
|
|
1263
1272
|
}
|
|
1264
1273
|
}
|
|
1265
1274
|
|
|
1275
|
+
// src/utils/sandbox-channel.ts
|
|
1276
|
+
import {
|
|
1277
|
+
safeParseJSON,
|
|
1278
|
+
safeValidateTypes as safeValidateTypes2
|
|
1279
|
+
} from "@ai-sdk/provider-utils";
|
|
1280
|
+
var sandboxChannelEventCheckpointSymbol = /* @__PURE__ */ Symbol.for(
|
|
1281
|
+
"vercel.ai.harness.sandboxChannelEventCheckpoint"
|
|
1282
|
+
);
|
|
1283
|
+
function pinSandboxChannelEventCheckpoint(event) {
|
|
1284
|
+
var _a3;
|
|
1285
|
+
if (event == null || typeof event !== "object") return void 0;
|
|
1286
|
+
return (_a3 = event[sandboxChannelEventCheckpointSymbol]) == null ? void 0 : _a3.pin();
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1266
1289
|
// src/agent/internal/run-prompt.ts
|
|
1267
1290
|
function runPrompt(input) {
|
|
1268
1291
|
var _a3, _b3, _c, _d, _e, _f, _g;
|
|
@@ -1306,7 +1329,7 @@ function runPrompt(input) {
|
|
|
1306
1329
|
result.fail(err);
|
|
1307
1330
|
};
|
|
1308
1331
|
const done = (async () => {
|
|
1309
|
-
var _a4, _b4, _c2, _d2, _e2, _f2, _g2, _h, _i, _j;
|
|
1332
|
+
var _a4, _b4, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k;
|
|
1310
1333
|
let bridge;
|
|
1311
1334
|
try {
|
|
1312
1335
|
bridge = await toHarnessStream({
|
|
@@ -1370,7 +1393,14 @@ function runPrompt(input) {
|
|
|
1370
1393
|
);
|
|
1371
1394
|
const settledHostToolCallIds = /* @__PURE__ */ new Set();
|
|
1372
1395
|
let closingResumedStep = false;
|
|
1396
|
+
let pendingStopBoundary;
|
|
1373
1397
|
let finalFinish;
|
|
1398
|
+
const completedSteps = [];
|
|
1399
|
+
const releasePendingStopBoundary = () => {
|
|
1400
|
+
var _a5;
|
|
1401
|
+
(_a5 = pendingStopBoundary == null ? void 0 : pendingStopBoundary.releaseCheckpoint) == null ? void 0 : _a5.call(pendingStopBoundary);
|
|
1402
|
+
pendingStopBoundary = void 0;
|
|
1403
|
+
};
|
|
1374
1404
|
let stepText = "";
|
|
1375
1405
|
let stepReasoning = "";
|
|
1376
1406
|
let stepToolCalls = [];
|
|
@@ -1411,12 +1441,14 @@ function runPrompt(input) {
|
|
|
1411
1441
|
content: buildStepContent()
|
|
1412
1442
|
});
|
|
1413
1443
|
resetStepContent();
|
|
1414
|
-
|
|
1444
|
+
const step = result.finishStep({
|
|
1415
1445
|
finishReason: input2.finishReason,
|
|
1416
1446
|
usage: input2.usage,
|
|
1417
1447
|
providerMetadata: input2.providerMetadata,
|
|
1418
1448
|
warnings: []
|
|
1419
1449
|
});
|
|
1450
|
+
completedSteps.push(step);
|
|
1451
|
+
return step;
|
|
1420
1452
|
};
|
|
1421
1453
|
const finishForHostInputPause = async (options) => {
|
|
1422
1454
|
if (options.completeCurrentStep) {
|
|
@@ -1517,9 +1549,16 @@ function runPrompt(input) {
|
|
|
1517
1549
|
toolName: approval.toolName,
|
|
1518
1550
|
input: approval.input
|
|
1519
1551
|
};
|
|
1552
|
+
telemetry.start(input.session.modelId);
|
|
1553
|
+
await telemetry.toolStart({
|
|
1554
|
+
toolCallId: rawToolCall.toolCallId,
|
|
1555
|
+
toolName: rawToolCall.toolName,
|
|
1556
|
+
input: rawToolCall.input
|
|
1557
|
+
});
|
|
1520
1558
|
const execution = await maybeExecuteHostTool({
|
|
1521
1559
|
event: rawToolCall,
|
|
1522
1560
|
tools: activeTools,
|
|
1561
|
+
wrappedExecuteTool: telemetry.executeTool,
|
|
1523
1562
|
sandboxSession: input.sandboxSession,
|
|
1524
1563
|
abortSignal: input.abortSignal,
|
|
1525
1564
|
control,
|
|
@@ -1577,10 +1616,31 @@ function runPrompt(input) {
|
|
|
1577
1616
|
}
|
|
1578
1617
|
while (true) {
|
|
1579
1618
|
const { value, done: done2 } = await reader.read();
|
|
1580
|
-
if (done2)
|
|
1619
|
+
if (done2) {
|
|
1620
|
+
releasePendingStopBoundary();
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1581
1623
|
if (value == null) continue;
|
|
1624
|
+
if (pendingStopBoundary != null) {
|
|
1625
|
+
if (value.type === "finish") {
|
|
1626
|
+
releasePendingStopBoundary();
|
|
1627
|
+
} else if ((await Promise.all(
|
|
1628
|
+
input.stopConditions.map(
|
|
1629
|
+
(condition) => condition({ steps: completedSteps })
|
|
1630
|
+
)
|
|
1631
|
+
)).some(Boolean)) {
|
|
1632
|
+
await ((_c2 = input.onStopConditionMet) == null ? void 0 : _c2.call(input));
|
|
1633
|
+
const { finishReason, usage } = pendingStopBoundary;
|
|
1634
|
+
releasePendingStopBoundary();
|
|
1635
|
+
telemetry.end({ finishReason, usage });
|
|
1636
|
+
await result.finish();
|
|
1637
|
+
return;
|
|
1638
|
+
} else {
|
|
1639
|
+
releasePendingStopBoundary();
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1582
1642
|
if (value.type === "stream-start") {
|
|
1583
|
-
telemetry.start((
|
|
1643
|
+
telemetry.start((_d2 = value.modelId) != null ? _d2 : input.session.modelId);
|
|
1584
1644
|
}
|
|
1585
1645
|
if (value.type !== "stream-start" && value.type !== "finish-step" && value.type !== "finish" && value.type !== "error") {
|
|
1586
1646
|
telemetry.ensureStepOpen();
|
|
@@ -1606,7 +1666,7 @@ function runPrompt(input) {
|
|
|
1606
1666
|
const rawToolCall = rawToolCallsByToolCallId.get(
|
|
1607
1667
|
displayValue.toolCallId
|
|
1608
1668
|
);
|
|
1609
|
-
const toolName = (
|
|
1669
|
+
const toolName = (_e2 = rawToolCall == null ? void 0 : rawToolCall.toolName) != null ? _e2 : toolCall.toolName;
|
|
1610
1670
|
if (!isHarnessV1BuiltinToolIncluded({
|
|
1611
1671
|
toolName,
|
|
1612
1672
|
toolFiltering: input.builtinToolFiltering
|
|
@@ -1662,7 +1722,7 @@ function runPrompt(input) {
|
|
|
1662
1722
|
toolName: value.toolName,
|
|
1663
1723
|
input: value.input
|
|
1664
1724
|
});
|
|
1665
|
-
telemetry.toolStart({
|
|
1725
|
+
await telemetry.toolStart({
|
|
1666
1726
|
toolCallId: value.toolCallId,
|
|
1667
1727
|
toolName: value.toolName,
|
|
1668
1728
|
input: value.input
|
|
@@ -1682,13 +1742,13 @@ function runPrompt(input) {
|
|
|
1682
1742
|
);
|
|
1683
1743
|
}
|
|
1684
1744
|
const rawToolCall = rawToolCallsByToolCallId.get(value.toolCallId);
|
|
1685
|
-
const pendingApproval = (
|
|
1745
|
+
const pendingApproval = (_h = pendingApprovalsByApprovalId.get(value.approvalId)) != null ? _h : {
|
|
1686
1746
|
approvalId: value.approvalId,
|
|
1687
1747
|
toolCallId: value.toolCallId,
|
|
1688
1748
|
toolName: toolCall.toolName,
|
|
1689
|
-
input: (
|
|
1749
|
+
input: (_f2 = rawToolCall == null ? void 0 : rawToolCall.input) != null ? _f2 : JSON.stringify(toolCall.input),
|
|
1690
1750
|
kind: "builtin",
|
|
1691
|
-
providerExecuted: (
|
|
1751
|
+
providerExecuted: (_g2 = rawToolCall == null ? void 0 : rawToolCall.providerExecuted) != null ? _g2 : true,
|
|
1692
1752
|
...(rawToolCall == null ? void 0 : rawToolCall.nativeName) !== void 0 ? { nativeName: rawToolCall.nativeName } : {}
|
|
1693
1753
|
};
|
|
1694
1754
|
pendingApprovalsByApprovalId.set(
|
|
@@ -1725,6 +1785,13 @@ function runPrompt(input) {
|
|
|
1725
1785
|
usage: value.usage,
|
|
1726
1786
|
providerMetadata: value.harnessMetadata
|
|
1727
1787
|
});
|
|
1788
|
+
if (input.stopConditions != null && input.stopConditions.length > 0) {
|
|
1789
|
+
pendingStopBoundary = {
|
|
1790
|
+
finishReason: value.finishReason,
|
|
1791
|
+
usage: value.usage,
|
|
1792
|
+
releaseCheckpoint: pinSandboxChannelEventCheckpoint(value)
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1728
1795
|
}
|
|
1729
1796
|
if (value.type === "finish") {
|
|
1730
1797
|
finalFinish = value;
|
|
@@ -1784,7 +1851,7 @@ function runPrompt(input) {
|
|
|
1784
1851
|
telemetry.toolEnd(toolCall.toolCallId, { ok: true, output });
|
|
1785
1852
|
continue;
|
|
1786
1853
|
}
|
|
1787
|
-
const pendingApproval = (
|
|
1854
|
+
const pendingApproval = (_i = pendingApprovalsByToolCallId.get(toolCall.toolCallId)) != null ? _i : customToolApprovalDecision.type === "request" ? {
|
|
1788
1855
|
approvalId: generateId4(),
|
|
1789
1856
|
toolCallId: toolCall.toolCallId,
|
|
1790
1857
|
toolName: toolCall.toolName,
|
|
@@ -1833,6 +1900,7 @@ function runPrompt(input) {
|
|
|
1833
1900
|
const execution = await maybeExecuteHostTool({
|
|
1834
1901
|
event: toolCall,
|
|
1835
1902
|
tools: activeTools,
|
|
1903
|
+
wrappedExecuteTool: telemetry.executeTool,
|
|
1836
1904
|
sandboxSession: input.sandboxSession,
|
|
1837
1905
|
abortSignal: input.abortSignal,
|
|
1838
1906
|
control,
|
|
@@ -1865,9 +1933,9 @@ function runPrompt(input) {
|
|
|
1865
1933
|
}
|
|
1866
1934
|
}
|
|
1867
1935
|
if (finalFinish != null) {
|
|
1868
|
-
(
|
|
1936
|
+
(_j = input.onTurnFinished) == null ? void 0 : _j.call(input);
|
|
1869
1937
|
} else {
|
|
1870
|
-
(
|
|
1938
|
+
(_k = input.onTurnFailed) == null ? void 0 : _k.call(input);
|
|
1871
1939
|
}
|
|
1872
1940
|
await result.finish(
|
|
1873
1941
|
finalFinish ? {
|
|
@@ -1886,6 +1954,7 @@ function runPrompt(input) {
|
|
|
1886
1954
|
});
|
|
1887
1955
|
settleFailure(err);
|
|
1888
1956
|
} finally {
|
|
1957
|
+
releasePendingStopBoundary();
|
|
1889
1958
|
reader.releaseLock();
|
|
1890
1959
|
}
|
|
1891
1960
|
})();
|
|
@@ -1907,28 +1976,34 @@ function hasTool(input) {
|
|
|
1907
1976
|
async function maybeExecuteHostTool(input) {
|
|
1908
1977
|
const tool = input.tools[input.event.toolName];
|
|
1909
1978
|
if (!isExecutableTool(tool)) return { executed: false };
|
|
1910
|
-
const parsed = await
|
|
1979
|
+
const parsed = await safeParseJSON2({ text: input.event.input });
|
|
1911
1980
|
const args = parsed.success ? parsed.value : input.event.input;
|
|
1912
1981
|
try {
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1982
|
+
const output = await input.wrappedExecuteTool({
|
|
1983
|
+
toolCallId: input.event.toolCallId,
|
|
1984
|
+
execute: async () => {
|
|
1985
|
+
let output2;
|
|
1986
|
+
const stream = executeTool({
|
|
1987
|
+
tool,
|
|
1988
|
+
input: args,
|
|
1989
|
+
options: {
|
|
1990
|
+
toolCallId: input.event.toolCallId,
|
|
1991
|
+
messages: [],
|
|
1992
|
+
abortSignal: input.abortSignal,
|
|
1993
|
+
context: void 0,
|
|
1994
|
+
experimental_sandbox: input.sandboxSession
|
|
1995
|
+
}
|
|
1996
|
+
});
|
|
1997
|
+
for await (const part of stream) {
|
|
1998
|
+
if (part.type === "preliminary") {
|
|
1999
|
+
input.onPreliminaryResult(part.output);
|
|
2000
|
+
} else {
|
|
2001
|
+
output2 = part.output;
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
return output2;
|
|
1923
2005
|
}
|
|
1924
2006
|
});
|
|
1925
|
-
for await (const part of stream) {
|
|
1926
|
-
if (part.type === "preliminary") {
|
|
1927
|
-
input.onPreliminaryResult(part.output);
|
|
1928
|
-
} else {
|
|
1929
|
-
output = part.output;
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
2007
|
await input.control.submitToolResult({
|
|
1933
2008
|
toolCallId: input.event.toolCallId,
|
|
1934
2009
|
output
|
|
@@ -2046,6 +2121,7 @@ var HarnessAgentSession = class {
|
|
|
2046
2121
|
runtimeContext: options.runtimeContext,
|
|
2047
2122
|
abortSignal: options.abortSignal,
|
|
2048
2123
|
telemetry: options.telemetry,
|
|
2124
|
+
stopConditions: options.stopConditions,
|
|
2049
2125
|
toolApproval: this.toolApproval,
|
|
2050
2126
|
pendingToolApprovals: this.getPendingToolApprovals(),
|
|
2051
2127
|
pendingToolResults: this.getPendingToolResults(),
|
|
@@ -2068,7 +2144,8 @@ var HarnessAgentSession = class {
|
|
|
2068
2144
|
},
|
|
2069
2145
|
onTurnFailed: () => {
|
|
2070
2146
|
this.finishTrackedTurn({ turnId });
|
|
2071
|
-
}
|
|
2147
|
+
},
|
|
2148
|
+
onStopConditionMet: () => this.captureStopConditionBoundary({ session, turnId })
|
|
2072
2149
|
});
|
|
2073
2150
|
return turn;
|
|
2074
2151
|
} catch (error) {
|
|
@@ -2096,6 +2173,7 @@ var HarnessAgentSession = class {
|
|
|
2096
2173
|
runtimeContext: options.runtimeContext,
|
|
2097
2174
|
abortSignal: options.abortSignal,
|
|
2098
2175
|
telemetry: options.telemetry,
|
|
2176
|
+
stopConditions: options.stopConditions,
|
|
2099
2177
|
toolApproval: this.toolApproval,
|
|
2100
2178
|
pendingToolApprovals: this.getPendingToolApprovals(),
|
|
2101
2179
|
pendingToolResults: this.getPendingToolResults(),
|
|
@@ -2120,7 +2198,8 @@ var HarnessAgentSession = class {
|
|
|
2120
2198
|
},
|
|
2121
2199
|
onTurnFailed: () => {
|
|
2122
2200
|
this.finishTrackedTurn({ turnId });
|
|
2123
|
-
}
|
|
2201
|
+
},
|
|
2202
|
+
onStopConditionMet: () => this.captureStopConditionBoundary({ session, turnId })
|
|
2124
2203
|
});
|
|
2125
2204
|
return turn;
|
|
2126
2205
|
} catch (error) {
|
|
@@ -2286,14 +2365,25 @@ var HarnessAgentSession = class {
|
|
|
2286
2365
|
};
|
|
2287
2366
|
}
|
|
2288
2367
|
async suspendCurrentTurn(options) {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2368
|
+
var _a3;
|
|
2369
|
+
(_a3 = this.suspendedTurnState) != null ? _a3 : this.suspendedTurnState = (async () => {
|
|
2370
|
+
const raw = await options.session.doSuspendTurn();
|
|
2371
|
+
const validated = await validateLifecycleStateData({
|
|
2372
|
+
harness: this.harness,
|
|
2373
|
+
state: raw,
|
|
2374
|
+
expectedType: "continue-turn"
|
|
2375
|
+
});
|
|
2376
|
+
return this.addPendingToolState(validated);
|
|
2377
|
+
})();
|
|
2378
|
+
const state = await this.suspendedTurnState;
|
|
2295
2379
|
this.turnState = "suspended";
|
|
2296
|
-
return
|
|
2380
|
+
return state;
|
|
2381
|
+
}
|
|
2382
|
+
async captureStopConditionBoundary(options) {
|
|
2383
|
+
if (this.sessionState !== "active" || this.activeTurnSequence !== options.turnId) {
|
|
2384
|
+
return;
|
|
2385
|
+
}
|
|
2386
|
+
await this.suspendCurrentTurn({ session: options.session });
|
|
2297
2387
|
}
|
|
2298
2388
|
toResumeStateWithContinuation(options) {
|
|
2299
2389
|
const { continueFrom } = options;
|
|
@@ -2342,6 +2432,7 @@ var HarnessAgentSession = class {
|
|
|
2342
2432
|
startTrackedTurn() {
|
|
2343
2433
|
const turnId = ++this.turnSequence;
|
|
2344
2434
|
this.activeTurnSequence = turnId;
|
|
2435
|
+
this.suspendedTurnState = void 0;
|
|
2345
2436
|
this.turnState = "running";
|
|
2346
2437
|
return turnId;
|
|
2347
2438
|
}
|
|
@@ -2350,6 +2441,7 @@ var HarnessAgentSession = class {
|
|
|
2350
2441
|
if (this.activeTurnSequence !== options.turnId) return;
|
|
2351
2442
|
this.pendingToolApprovals.clear();
|
|
2352
2443
|
this.pendingToolResults.clear();
|
|
2444
|
+
this.suspendedTurnState = void 0;
|
|
2353
2445
|
this.turnState = "idle";
|
|
2354
2446
|
}
|
|
2355
2447
|
endLocalHandle(options) {
|
|
@@ -2870,6 +2962,7 @@ var HarnessAgent = class {
|
|
|
2870
2962
|
const sandboxConfig = resolveSandboxConfig(settings);
|
|
2871
2963
|
validateSandboxBootstrapSettings(sandboxConfig);
|
|
2872
2964
|
this.settings = settings;
|
|
2965
|
+
this.stopConditions = settings.stopWhen == null ? [] : asArray2(settings.stopWhen);
|
|
2873
2966
|
this.sandboxConfig = sandboxConfig;
|
|
2874
2967
|
this.id = settings.id;
|
|
2875
2968
|
const userTools = (_a3 = settings.tools) != null ? _a3 : {};
|
|
@@ -3117,6 +3210,7 @@ var HarnessAgent = class {
|
|
|
3117
3210
|
runtimeContext: input.runtimeContext,
|
|
3118
3211
|
abortSignal: input.abortSignal,
|
|
3119
3212
|
telemetry: this.settings.telemetry,
|
|
3213
|
+
stopConditions: this.stopConditions,
|
|
3120
3214
|
toolApprovalContinuations: input.turnInput.toolApprovalContinuations,
|
|
3121
3215
|
toolResultContinuations: input.turnInput.toolResultContinuations
|
|
3122
3216
|
});
|
|
@@ -3130,7 +3224,8 @@ var HarnessAgent = class {
|
|
|
3130
3224
|
builtinToolFiltering: this.builtinToolFiltering,
|
|
3131
3225
|
runtimeContext: input.runtimeContext,
|
|
3132
3226
|
abortSignal: input.abortSignal,
|
|
3133
|
-
telemetry: this.settings.telemetry
|
|
3227
|
+
telemetry: this.settings.telemetry,
|
|
3228
|
+
stopConditions: this.stopConditions
|
|
3134
3229
|
});
|
|
3135
3230
|
}
|
|
3136
3231
|
async _acquireSandbox(input) {
|