@ai-sdk/harness 1.0.124 → 1.0.127
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 +26 -0
- package/README.md +9 -8
- package/agent/index.ts +2 -0
- package/dist/agent/index.d.ts +31 -19
- package/dist/agent/index.js +340 -248
- package/dist/agent/index.js.map +1 -1
- package/dist/index.d.ts +39 -17
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +7 -14
- package/dist/utils/index.js +63 -97
- package/dist/utils/index.js.map +1 -1
- package/package.json +4 -4
- package/src/agent/create-harness-sandbox-template.ts +80 -0
- package/src/agent/harness-agent-settings.ts +1 -0
- package/src/agent/harness-agent-types.ts +2 -0
- package/src/agent/harness-agent.ts +23 -0
- package/src/agent/internal/on-bootstrap-marker.ts +70 -0
- package/src/agent/internal/prepared-sandbox-identity.ts +42 -0
- package/src/agent/internal/sandbox-bootstrap.ts +19 -0
- package/src/agent/prepare-harness-sandbox-template.ts +5 -2
- package/src/agent/prepare-sandbox-for-harness.ts +7 -51
- package/src/v1/harness-v1-network-sandbox-session.ts +7 -14
- package/src/v1/harness-v1-sandbox-provider.ts +3 -2
- package/src/v1/harness-v1-sandbox-session-create-options.ts +14 -0
- package/src/v1/harness-v1-sandbox-session-resume-options.ts +10 -0
- package/src/v1/harness-v1-sandbox-template.ts +9 -0
- package/src/v1/index.ts +3 -0
package/dist/agent/index.js
CHANGED
|
@@ -521,7 +521,7 @@ var HarnessStreamTextResult = class {
|
|
|
521
521
|
]) {
|
|
522
522
|
try {
|
|
523
523
|
dp.reject(error);
|
|
524
|
-
} catch
|
|
524
|
+
} catch {
|
|
525
525
|
}
|
|
526
526
|
}
|
|
527
527
|
}
|
|
@@ -644,11 +644,10 @@ var HarnessStreamTextResult = class {
|
|
|
644
644
|
);
|
|
645
645
|
}
|
|
646
646
|
get elementStream() {
|
|
647
|
-
|
|
648
|
-
const transform = (_a4 = this.outputSpecification) == null ? void 0 : _a4.createElementStreamTransform();
|
|
647
|
+
const transform = this.outputSpecification?.createElementStreamTransform();
|
|
649
648
|
if (transform == null) {
|
|
650
649
|
throw notSupportedYet(
|
|
651
|
-
`element streams in ${
|
|
650
|
+
`element streams in ${this.outputSpecification?.name ?? "text"} mode`
|
|
652
651
|
);
|
|
653
652
|
}
|
|
654
653
|
return createAsyncIterableStream(
|
|
@@ -807,7 +806,6 @@ function createOutputTransformStream(output) {
|
|
|
807
806
|
};
|
|
808
807
|
return new TransformStream({
|
|
809
808
|
async transform(chunk, controller) {
|
|
810
|
-
var _a4;
|
|
811
809
|
if (chunk.type === "finish-step" && textChunk.length > 0) {
|
|
812
810
|
publishTextChunk({ controller });
|
|
813
811
|
}
|
|
@@ -834,7 +832,7 @@ function createOutputTransformStream(output) {
|
|
|
834
832
|
}
|
|
835
833
|
text += chunk.text;
|
|
836
834
|
textChunk += chunk.text;
|
|
837
|
-
textProviderMetadata =
|
|
835
|
+
textProviderMetadata = chunk.providerMetadata ?? textProviderMetadata;
|
|
838
836
|
if (chunk.text.length === 0 && chunk.providerMetadata != null) {
|
|
839
837
|
controller.enqueue({ part: chunk, partialOutput: void 0 });
|
|
840
838
|
return;
|
|
@@ -880,7 +878,6 @@ function getOwn(obj, key) {
|
|
|
880
878
|
// src/agent/internal/translate-stream-part.ts
|
|
881
879
|
import { generateId } from "@ai-sdk/provider-utils";
|
|
882
880
|
function translateStreamPart(event, options = {}) {
|
|
883
|
-
var _a4, _b4;
|
|
884
881
|
switch (event.type) {
|
|
885
882
|
case "stream-start":
|
|
886
883
|
return [];
|
|
@@ -943,7 +940,7 @@ function translateStreamPart(event, options = {}) {
|
|
|
943
940
|
case "tool-approval-request":
|
|
944
941
|
return [];
|
|
945
942
|
case "tool-result":
|
|
946
|
-
if (event.isError === true && (
|
|
943
|
+
if (event.isError === true && (options.isProviderExecuted?.(event.toolCallId) ?? true)) {
|
|
947
944
|
return [
|
|
948
945
|
{
|
|
949
946
|
type: "tool-error",
|
|
@@ -1042,7 +1039,6 @@ function createToolInputWorkDirStripper({
|
|
|
1042
1039
|
}) {
|
|
1043
1040
|
const stateByToolCallId = /* @__PURE__ */ new Map();
|
|
1044
1041
|
return (part) => {
|
|
1045
|
-
var _a4;
|
|
1046
1042
|
if (sessionWorkDir.length === 0) return [part];
|
|
1047
1043
|
if (part.type === "tool-input-start") {
|
|
1048
1044
|
stateByToolCallId.set(part.id, {
|
|
@@ -1052,7 +1048,7 @@ function createToolInputWorkDirStripper({
|
|
|
1052
1048
|
return [part];
|
|
1053
1049
|
}
|
|
1054
1050
|
if (part.type === "tool-input-delta") {
|
|
1055
|
-
const state2 =
|
|
1051
|
+
const state2 = stateByToolCallId.get(part.id) ?? {
|
|
1056
1052
|
pending: "",
|
|
1057
1053
|
precedingCharacter: void 0
|
|
1058
1054
|
};
|
|
@@ -1231,15 +1227,14 @@ import { createTelemetryDispatcher } from "ai/internal";
|
|
|
1231
1227
|
async function notify(event, ...callbacks) {
|
|
1232
1228
|
await Promise.allSettled(
|
|
1233
1229
|
callbacks.map(async (callback) => {
|
|
1234
|
-
await
|
|
1230
|
+
await callback?.(event);
|
|
1235
1231
|
})
|
|
1236
1232
|
);
|
|
1237
1233
|
}
|
|
1238
1234
|
function createTurnLifecycle(options) {
|
|
1239
|
-
var _a4;
|
|
1240
1235
|
const telemetry = options.telemetry == null ? {} : createTelemetryDispatcher({ telemetry: options.telemetry });
|
|
1241
1236
|
const provider = `harness:${options.harnessId}`;
|
|
1242
|
-
let modelId =
|
|
1237
|
+
let modelId = options.modelId ?? "";
|
|
1243
1238
|
let started = false;
|
|
1244
1239
|
let stepOpen = false;
|
|
1245
1240
|
let stepNumber = 0;
|
|
@@ -1381,7 +1376,6 @@ function createTurnLifecycle(options) {
|
|
|
1381
1376
|
);
|
|
1382
1377
|
},
|
|
1383
1378
|
async stepEnd(step) {
|
|
1384
|
-
var _a5, _b4, _c;
|
|
1385
1379
|
if (!stepOpen) return;
|
|
1386
1380
|
completedSteps.push(step);
|
|
1387
1381
|
const telemetryStepEndEvent = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
@@ -1412,8 +1406,8 @@ function createTurnLifecycle(options) {
|
|
|
1412
1406
|
dynamicToolResults: step.dynamicToolResults
|
|
1413
1407
|
});
|
|
1414
1408
|
await Promise.allSettled([
|
|
1415
|
-
|
|
1416
|
-
|
|
1409
|
+
options.callbacks.onStepEnd?.(step),
|
|
1410
|
+
telemetry.onStepEnd?.(telemetryStepEndEvent)
|
|
1417
1411
|
]);
|
|
1418
1412
|
stepOpen = false;
|
|
1419
1413
|
stepNumber += 1;
|
|
@@ -1445,10 +1439,7 @@ function createTurnLifecycle(options) {
|
|
|
1445
1439
|
rawFinishReason: finalStep.rawFinishReason,
|
|
1446
1440
|
usage,
|
|
1447
1441
|
totalUsage: usage,
|
|
1448
|
-
warnings: steps.flatMap((step) =>
|
|
1449
|
-
var _a5;
|
|
1450
|
-
return (_a5 = step.warnings) != null ? _a5 : [];
|
|
1451
|
-
}),
|
|
1442
|
+
warnings: steps.flatMap((step) => step.warnings ?? []),
|
|
1452
1443
|
request: finalStep.request,
|
|
1453
1444
|
response: finalStep.response,
|
|
1454
1445
|
providerMetadata: finalStep.providerMetadata,
|
|
@@ -1471,11 +1462,10 @@ function createTurnLifecycle(options) {
|
|
|
1471
1462
|
});
|
|
1472
1463
|
},
|
|
1473
1464
|
async error(error) {
|
|
1474
|
-
var _a5;
|
|
1475
1465
|
if (ended) return;
|
|
1476
1466
|
if (!started) await start();
|
|
1477
1467
|
ended = true;
|
|
1478
|
-
await
|
|
1468
|
+
await telemetry.onError?.(error);
|
|
1479
1469
|
}
|
|
1480
1470
|
};
|
|
1481
1471
|
}
|
|
@@ -1483,16 +1473,14 @@ function createTurnLifecycle(options) {
|
|
|
1483
1473
|
// src/agent/internal/permission-mode.ts
|
|
1484
1474
|
var DEFAULT_PERMISSION_MODE = "allow-all";
|
|
1485
1475
|
function resolvePermissionMode(input) {
|
|
1486
|
-
|
|
1487
|
-
return (_a4 = input.permissionMode) != null ? _a4 : DEFAULT_PERMISSION_MODE;
|
|
1476
|
+
return input.permissionMode ?? DEFAULT_PERMISSION_MODE;
|
|
1488
1477
|
}
|
|
1489
1478
|
function permissionModeNeedsBuiltinSupport(input) {
|
|
1490
1479
|
return input.permissionMode !== "allow-all";
|
|
1491
1480
|
}
|
|
1492
1481
|
function resolveCustomToolApproval(input) {
|
|
1493
|
-
var _a4;
|
|
1494
1482
|
const status = normalizeToolApprovalStatus({
|
|
1495
|
-
status:
|
|
1483
|
+
status: input.toolApproval?.[input.toolName]
|
|
1496
1484
|
});
|
|
1497
1485
|
switch (status.type) {
|
|
1498
1486
|
case "not-applicable":
|
|
@@ -1518,24 +1506,23 @@ function stringifyUnknown(value) {
|
|
|
1518
1506
|
if (typeof value === "string") return value;
|
|
1519
1507
|
try {
|
|
1520
1508
|
return JSON.stringify(value);
|
|
1521
|
-
} catch
|
|
1509
|
+
} catch {
|
|
1522
1510
|
return String(value);
|
|
1523
1511
|
}
|
|
1524
1512
|
}
|
|
1525
1513
|
function formatBridgeError(error) {
|
|
1526
|
-
var _a4, _b4;
|
|
1527
1514
|
if (error instanceof Error) {
|
|
1528
|
-
return
|
|
1515
|
+
return error.stack ?? `${error.name}: ${error.message}`;
|
|
1529
1516
|
}
|
|
1530
1517
|
if (isSerializedError(error)) {
|
|
1531
|
-
return
|
|
1518
|
+
return error.stack ?? `${error.name ? `${error.name}: ` : ""}${error.message}`;
|
|
1532
1519
|
}
|
|
1533
1520
|
return stringifyUnknown(error);
|
|
1534
1521
|
}
|
|
1535
1522
|
function writeToStderr(line) {
|
|
1536
1523
|
try {
|
|
1537
1524
|
process.stderr.write(line);
|
|
1538
|
-
} catch
|
|
1525
|
+
} catch {
|
|
1539
1526
|
}
|
|
1540
1527
|
}
|
|
1541
1528
|
function logBridgeError({
|
|
@@ -1564,9 +1551,8 @@ var sandboxChannelEventCheckpointSymbol = /* @__PURE__ */ Symbol.for(
|
|
|
1564
1551
|
"vercel.ai.harness.sandboxChannelEventCheckpoint"
|
|
1565
1552
|
);
|
|
1566
1553
|
function pinSandboxChannelEventCheckpoint(event) {
|
|
1567
|
-
var _a4;
|
|
1568
1554
|
if (event == null || typeof event !== "object") return void 0;
|
|
1569
|
-
return
|
|
1555
|
+
return event[sandboxChannelEventCheckpointSymbol]?.pin();
|
|
1570
1556
|
}
|
|
1571
1557
|
|
|
1572
1558
|
// src/agent/internal/run-prompt.ts
|
|
@@ -1591,29 +1577,28 @@ function unwrapToolResultOutput(toolResult) {
|
|
|
1591
1577
|
}
|
|
1592
1578
|
}
|
|
1593
1579
|
function runPrompt(input) {
|
|
1594
|
-
var _a4, _b4, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1595
1580
|
const callId = generateId2();
|
|
1596
|
-
const toolsContext =
|
|
1581
|
+
const toolsContext = input.toolsContext ?? {};
|
|
1597
1582
|
const result = new HarnessStreamTextResult({
|
|
1598
1583
|
tools: input.tools,
|
|
1599
1584
|
runtimeContext: input.runtimeContext,
|
|
1600
1585
|
toolsContext,
|
|
1601
1586
|
harnessId: input.harness.harnessId,
|
|
1602
1587
|
callId,
|
|
1603
|
-
modelId:
|
|
1588
|
+
modelId: input.model ?? "",
|
|
1604
1589
|
output: input.output
|
|
1605
1590
|
});
|
|
1606
|
-
const pendingToolApprovals =
|
|
1607
|
-
const pendingToolResults =
|
|
1608
|
-
const onPendingToolApproval =
|
|
1591
|
+
const pendingToolApprovals = input.pendingToolApprovals ?? [];
|
|
1592
|
+
const pendingToolResults = input.pendingToolResults ?? [];
|
|
1593
|
+
const onPendingToolApproval = input.onPendingToolApproval ?? (() => {
|
|
1609
1594
|
});
|
|
1610
|
-
const onToolApprovalSettled =
|
|
1595
|
+
const onToolApprovalSettled = input.onToolApprovalSettled ?? (() => {
|
|
1611
1596
|
});
|
|
1612
|
-
const onPendingToolResult =
|
|
1597
|
+
const onPendingToolResult = input.onPendingToolResult ?? (() => {
|
|
1613
1598
|
});
|
|
1614
|
-
const onToolResultSettled =
|
|
1599
|
+
const onToolResultSettled = input.onToolResultSettled ?? (() => {
|
|
1615
1600
|
});
|
|
1616
|
-
const activeTools =
|
|
1601
|
+
const activeTools = input.activeTools ?? input.tools;
|
|
1617
1602
|
const activeToolNames = Object.keys(input.tools).filter(
|
|
1618
1603
|
(toolName) => Object.prototype.hasOwnProperty.call(activeTools, toolName) || Object.prototype.hasOwnProperty.call(
|
|
1619
1604
|
input.harness.builtinTools,
|
|
@@ -1626,7 +1611,7 @@ function runPrompt(input) {
|
|
|
1626
1611
|
const lifecycle = createTurnLifecycle({
|
|
1627
1612
|
callId,
|
|
1628
1613
|
telemetry: input.telemetry,
|
|
1629
|
-
callbacks:
|
|
1614
|
+
callbacks: input.callbacks ?? {},
|
|
1630
1615
|
harnessId: input.harness.harnessId,
|
|
1631
1616
|
modelId: input.model,
|
|
1632
1617
|
instructions: input.instructions,
|
|
@@ -1639,11 +1624,10 @@ function runPrompt(input) {
|
|
|
1639
1624
|
output: input.output
|
|
1640
1625
|
});
|
|
1641
1626
|
const settleFailure = (err) => {
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
(_b5 = input.onTurnFailed) == null ? void 0 : _b5.call(input);
|
|
1627
|
+
if (!input.isTurnSuspending?.()) {
|
|
1628
|
+
input.onTurnFailed?.();
|
|
1645
1629
|
}
|
|
1646
|
-
if (
|
|
1630
|
+
if (input.abortSignal?.aborted) {
|
|
1647
1631
|
result.abort({
|
|
1648
1632
|
error: err,
|
|
1649
1633
|
...input.abortSignal.reason !== void 0 ? { reason: getErrorMessage(input.abortSignal.reason) } : {}
|
|
@@ -1653,23 +1637,18 @@ function runPrompt(input) {
|
|
|
1653
1637
|
result.fail(err);
|
|
1654
1638
|
};
|
|
1655
1639
|
const done = (async () => {
|
|
1656
|
-
var _a5, _b5, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k, _l, _m, _n, _o;
|
|
1657
1640
|
let bridge;
|
|
1658
1641
|
try {
|
|
1659
1642
|
bridge = await toHarnessStream({
|
|
1660
|
-
invoke: input.mode === "continue" ? (emit) => {
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
emit
|
|
1670
|
-
});
|
|
1671
|
-
} : (emit) => {
|
|
1672
|
-
var _a6;
|
|
1643
|
+
invoke: input.mode === "continue" ? (emit) => input.session.doContinueTurn({
|
|
1644
|
+
model: input.model,
|
|
1645
|
+
skills: input.skills ?? [],
|
|
1646
|
+
responseFormat: input.responseFormat,
|
|
1647
|
+
tools: input.toolSpecs,
|
|
1648
|
+
instructions: input.instructions,
|
|
1649
|
+
abortSignal: input.abortSignal,
|
|
1650
|
+
emit
|
|
1651
|
+
}) : (emit) => {
|
|
1673
1652
|
if (input.prompt == null) {
|
|
1674
1653
|
throw new Error(
|
|
1675
1654
|
'runPrompt: `prompt` is required for mode "prompt".'
|
|
@@ -1678,7 +1657,7 @@ function runPrompt(input) {
|
|
|
1678
1657
|
return input.session.doPromptTurn({
|
|
1679
1658
|
prompt: input.prompt,
|
|
1680
1659
|
model: input.model,
|
|
1681
|
-
skills:
|
|
1660
|
+
skills: input.skills ?? [],
|
|
1682
1661
|
responseFormat: input.responseFormat,
|
|
1683
1662
|
tools: input.toolSpecs,
|
|
1684
1663
|
instructions: input.instructions,
|
|
@@ -1699,7 +1678,7 @@ function runPrompt(input) {
|
|
|
1699
1678
|
return;
|
|
1700
1679
|
}
|
|
1701
1680
|
const { stream, control } = bridge;
|
|
1702
|
-
|
|
1681
|
+
input.onPromptControlAvailable?.(control);
|
|
1703
1682
|
const reader = stream.getReader();
|
|
1704
1683
|
const stripToolInputWorkDir = createToolInputWorkDirStripper({
|
|
1705
1684
|
sessionWorkDir: input.sessionWorkDir
|
|
@@ -1719,7 +1698,7 @@ function runPrompt(input) {
|
|
|
1719
1698
|
pendingToolApprovals.map((approval) => [approval.toolCallId, approval])
|
|
1720
1699
|
);
|
|
1721
1700
|
const continuationsByApprovalId = new Map(
|
|
1722
|
-
(
|
|
1701
|
+
(input.toolApprovalContinuations ?? []).map((continuation) => [
|
|
1723
1702
|
continuation.approvalId,
|
|
1724
1703
|
continuation
|
|
1725
1704
|
])
|
|
@@ -1731,7 +1710,7 @@ function runPrompt(input) {
|
|
|
1731
1710
|
])
|
|
1732
1711
|
);
|
|
1733
1712
|
const continuationsByToolCallId = new Map(
|
|
1734
|
-
(
|
|
1713
|
+
(input.toolResultContinuations ?? []).map((continuation) => [
|
|
1735
1714
|
continuation.toolCallId,
|
|
1736
1715
|
continuation
|
|
1737
1716
|
])
|
|
@@ -1760,8 +1739,7 @@ function runPrompt(input) {
|
|
|
1760
1739
|
}
|
|
1761
1740
|
};
|
|
1762
1741
|
const releasePendingStopBoundary = () => {
|
|
1763
|
-
|
|
1764
|
-
(_a6 = pendingStopBoundary == null ? void 0 : pendingStopBoundary.releaseCheckpoint) == null ? void 0 : _a6.call(pendingStopBoundary);
|
|
1742
|
+
pendingStopBoundary?.releaseCheckpoint?.();
|
|
1765
1743
|
pendingStopBoundary = void 0;
|
|
1766
1744
|
};
|
|
1767
1745
|
let stepText = "";
|
|
@@ -1772,7 +1750,6 @@ function runPrompt(input) {
|
|
|
1772
1750
|
let bufferedToolOutcomes = [];
|
|
1773
1751
|
const toolExecutions = /* @__PURE__ */ new Map();
|
|
1774
1752
|
const publishToolExecutions = async () => {
|
|
1775
|
-
var _a6;
|
|
1776
1753
|
for (const execution of toolExecutions.values()) {
|
|
1777
1754
|
if (execution.toolOutput == null) continue;
|
|
1778
1755
|
await lifecycle.toolExecutionStart({
|
|
@@ -1781,7 +1758,7 @@ function runPrompt(input) {
|
|
|
1781
1758
|
await lifecycle.toolExecutionEnd({
|
|
1782
1759
|
toolCall: execution.toolCall,
|
|
1783
1760
|
toolOutput: execution.toolOutput,
|
|
1784
|
-
toolExecutionMs:
|
|
1761
|
+
toolExecutionMs: execution.toolExecutionMs ?? 0
|
|
1785
1762
|
});
|
|
1786
1763
|
}
|
|
1787
1764
|
for (const publish of bufferedToolOutcomes) publish();
|
|
@@ -1896,8 +1873,7 @@ function runPrompt(input) {
|
|
|
1896
1873
|
});
|
|
1897
1874
|
};
|
|
1898
1875
|
const recordPendingToolResult = (options) => {
|
|
1899
|
-
|
|
1900
|
-
const pendingResult = (_a6 = pendingResultsByToolCallId.get(options.toolCall.toolCallId)) != null ? _a6 : {
|
|
1876
|
+
const pendingResult = pendingResultsByToolCallId.get(options.toolCall.toolCallId) ?? {
|
|
1901
1877
|
toolCallId: options.toolCall.toolCallId,
|
|
1902
1878
|
toolName: options.toolCall.toolName,
|
|
1903
1879
|
input: options.toolCall.input,
|
|
@@ -1936,11 +1912,10 @@ function runPrompt(input) {
|
|
|
1936
1912
|
});
|
|
1937
1913
|
};
|
|
1938
1914
|
const submitToolResult = async (submission) => {
|
|
1939
|
-
|
|
1940
|
-
if (!((_a6 = input.isTurnSuspending) == null ? void 0 : _a6.call(input))) {
|
|
1915
|
+
if (!input.isTurnSuspending?.()) {
|
|
1941
1916
|
return control.submitToolResult(submission);
|
|
1942
1917
|
}
|
|
1943
|
-
const toolCall =
|
|
1918
|
+
const toolCall = rawToolCallsByToolCallId.get(submission.toolCallId) ?? pendingResultsByToolCallId.get(submission.toolCallId) ?? pendingToolApprovals.find(
|
|
1944
1919
|
(approval) => approval.toolCallId === submission.toolCallId
|
|
1945
1920
|
);
|
|
1946
1921
|
if (toolCall == null) {
|
|
@@ -1984,8 +1959,7 @@ function runPrompt(input) {
|
|
|
1984
1959
|
pendingResultsByToolCallId.delete(pendingResult.toolCallId);
|
|
1985
1960
|
};
|
|
1986
1961
|
const processPendingApprovalContinuation = async (approval, continuation) => {
|
|
1987
|
-
|
|
1988
|
-
const rawToolCall = (_a6 = approval.kind === "builtin" ? rawToolCallsByToolCallId.get(approval.toolCallId) : void 0) != null ? _a6 : {
|
|
1962
|
+
const rawToolCall = (approval.kind === "builtin" ? rawToolCallsByToolCallId.get(approval.toolCallId) : void 0) ?? {
|
|
1989
1963
|
type: "tool-call",
|
|
1990
1964
|
toolCallId: approval.toolCallId,
|
|
1991
1965
|
toolName: approval.toolName,
|
|
@@ -2165,7 +2139,7 @@ function runPrompt(input) {
|
|
|
2165
2139
|
(condition) => condition({ steps: completedSteps })
|
|
2166
2140
|
)
|
|
2167
2141
|
)).some(Boolean)) {
|
|
2168
|
-
await
|
|
2142
|
+
await input.onStopConditionMet?.();
|
|
2169
2143
|
const { usage } = pendingStopBoundary;
|
|
2170
2144
|
releasePendingStopBoundary();
|
|
2171
2145
|
await lifecycle.end({
|
|
@@ -2179,7 +2153,7 @@ function runPrompt(input) {
|
|
|
2179
2153
|
}
|
|
2180
2154
|
}
|
|
2181
2155
|
if (value.type === "stream-start") {
|
|
2182
|
-
const modelId =
|
|
2156
|
+
const modelId = value.modelId ?? input.model;
|
|
2183
2157
|
if (modelId != null) result.setModelId(modelId);
|
|
2184
2158
|
await lifecycle.start(modelId);
|
|
2185
2159
|
}
|
|
@@ -2223,7 +2197,7 @@ function runPrompt(input) {
|
|
|
2223
2197
|
const rawToolCall = rawToolCallsByToolCallId.get(
|
|
2224
2198
|
displayValue.toolCallId
|
|
2225
2199
|
);
|
|
2226
|
-
const toolName =
|
|
2200
|
+
const toolName = rawToolCall?.toolName ?? toolCall.toolName;
|
|
2227
2201
|
if (!isHarnessV1BuiltinToolIncluded({
|
|
2228
2202
|
toolName,
|
|
2229
2203
|
toolFiltering: input.builtinToolFiltering
|
|
@@ -2246,7 +2220,7 @@ function runPrompt(input) {
|
|
|
2246
2220
|
if (value.type === "error" && displayValue.type === "error") {
|
|
2247
2221
|
await waitForOutstandingHostToolExecutions();
|
|
2248
2222
|
await lifecycle.error(value.error);
|
|
2249
|
-
if (!
|
|
2223
|
+
if (!input.abortSignal?.aborted) {
|
|
2250
2224
|
logBridgeError({
|
|
2251
2225
|
harnessId: input.harness.harnessId,
|
|
2252
2226
|
sessionId: input.session.sessionId,
|
|
@@ -2295,7 +2269,7 @@ function runPrompt(input) {
|
|
|
2295
2269
|
}
|
|
2296
2270
|
if (value.type === "tool-call") {
|
|
2297
2271
|
observedStepToolCallCount += 1;
|
|
2298
|
-
expectedStepToolCallCount
|
|
2272
|
+
expectedStepToolCallCount ??= value.stepToolCallCount;
|
|
2299
2273
|
const toolCall = toolCallsByToolCallId.get(value.toolCallId);
|
|
2300
2274
|
if (toolCall != null) {
|
|
2301
2275
|
stepToolCalls.push(toolCall);
|
|
@@ -2317,7 +2291,7 @@ function runPrompt(input) {
|
|
|
2317
2291
|
output: value.result
|
|
2318
2292
|
};
|
|
2319
2293
|
}
|
|
2320
|
-
if (
|
|
2294
|
+
if (rawToolCallsByToolCallId.get(value.toolCallId)?.providerExecuted === true && execution?.toolOutput != null) {
|
|
2321
2295
|
stepProviderToolResults.push(
|
|
2322
2296
|
execution.toolOutput
|
|
2323
2297
|
);
|
|
@@ -2331,14 +2305,14 @@ function runPrompt(input) {
|
|
|
2331
2305
|
);
|
|
2332
2306
|
}
|
|
2333
2307
|
const rawToolCall = rawToolCallsByToolCallId.get(value.toolCallId);
|
|
2334
|
-
const pendingApproval =
|
|
2308
|
+
const pendingApproval = pendingApprovalsByApprovalId.get(value.approvalId) ?? {
|
|
2335
2309
|
approvalId: value.approvalId,
|
|
2336
2310
|
toolCallId: value.toolCallId,
|
|
2337
2311
|
toolName: toolCall.toolName,
|
|
2338
|
-
input:
|
|
2312
|
+
input: rawToolCall?.input ?? JSON.stringify(toolCall.input),
|
|
2339
2313
|
kind: "builtin",
|
|
2340
|
-
providerExecuted:
|
|
2341
|
-
...
|
|
2314
|
+
providerExecuted: rawToolCall?.providerExecuted ?? true,
|
|
2315
|
+
...rawToolCall?.nativeName !== void 0 ? { nativeName: rawToolCall.nativeName } : {}
|
|
2342
2316
|
};
|
|
2343
2317
|
pendingApprovalsByApprovalId.set(
|
|
2344
2318
|
pendingApproval.approvalId,
|
|
@@ -2492,7 +2466,7 @@ function runPrompt(input) {
|
|
|
2492
2466
|
}
|
|
2493
2467
|
continue;
|
|
2494
2468
|
}
|
|
2495
|
-
const pendingApproval =
|
|
2469
|
+
const pendingApproval = pendingApprovalsByToolCallId.get(toolCall.toolCallId) ?? (customToolApprovalDecision.type === "request" ? {
|
|
2496
2470
|
approvalId: generateId2(),
|
|
2497
2471
|
toolCallId: toolCall.toolCallId,
|
|
2498
2472
|
toolName: toolCall.toolName,
|
|
@@ -2500,7 +2474,7 @@ function runPrompt(input) {
|
|
|
2500
2474
|
kind: "custom",
|
|
2501
2475
|
providerExecuted: false,
|
|
2502
2476
|
...toolCall.nativeName !== void 0 ? { nativeName: toolCall.nativeName } : {}
|
|
2503
|
-
} : void 0;
|
|
2477
|
+
} : void 0);
|
|
2504
2478
|
if (pendingApproval != null) {
|
|
2505
2479
|
pendingApprovalsByApprovalId.set(
|
|
2506
2480
|
pendingApproval.approvalId,
|
|
@@ -2603,16 +2577,16 @@ function runPrompt(input) {
|
|
|
2603
2577
|
}
|
|
2604
2578
|
}
|
|
2605
2579
|
await waitForOutstandingHostToolExecutions();
|
|
2606
|
-
const isTurnSuspending =
|
|
2580
|
+
const isTurnSuspending = input.isTurnSuspending?.() === true;
|
|
2607
2581
|
if (isTurnSuspending) {
|
|
2608
2582
|
await publishToolExecutions();
|
|
2609
2583
|
if (finalFinish == null) {
|
|
2610
2584
|
result.discardCurrentStepContent();
|
|
2611
2585
|
}
|
|
2612
2586
|
} else if (finalFinish != null) {
|
|
2613
|
-
|
|
2587
|
+
input.onTurnFinished?.();
|
|
2614
2588
|
} else {
|
|
2615
|
-
|
|
2589
|
+
input.onTurnFailed?.();
|
|
2616
2590
|
}
|
|
2617
2591
|
await result.finish(
|
|
2618
2592
|
finalFinish ? {
|
|
@@ -2624,7 +2598,7 @@ function runPrompt(input) {
|
|
|
2624
2598
|
} catch (err) {
|
|
2625
2599
|
try {
|
|
2626
2600
|
await waitForOutstandingHostToolExecutions();
|
|
2627
|
-
} catch
|
|
2601
|
+
} catch {
|
|
2628
2602
|
}
|
|
2629
2603
|
await lifecycle.error(err);
|
|
2630
2604
|
logBridgeError({
|
|
@@ -2788,23 +2762,22 @@ var HarnessAgentSession = class {
|
|
|
2788
2762
|
this.sessionState = "active";
|
|
2789
2763
|
this.turnSequence = 0;
|
|
2790
2764
|
this.activeTurnSequence = 0;
|
|
2791
|
-
var _a4, _b4, _c, _d;
|
|
2792
2765
|
this.sessionId = options.sessionId;
|
|
2793
2766
|
this.harness = options.harness;
|
|
2794
2767
|
this.underlyingSession = options.underlyingSession;
|
|
2795
2768
|
this.sandboxSession = options.sandboxSession;
|
|
2796
|
-
this.ownsSandboxLifecycle =
|
|
2769
|
+
this.ownsSandboxLifecycle = options.ownsSandboxLifecycle ?? true;
|
|
2797
2770
|
this.sessionWorkDir = options.sessionWorkDir;
|
|
2798
2771
|
this.toolApproval = options.toolApproval;
|
|
2799
|
-
for (const approval of
|
|
2772
|
+
for (const approval of options.pendingToolApprovals ?? []) {
|
|
2800
2773
|
this.pendingToolApprovals.set(approval.approvalId, approval);
|
|
2801
2774
|
}
|
|
2802
|
-
for (const pendingResult of
|
|
2775
|
+
for (const pendingResult of options.pendingToolResults ?? []) {
|
|
2803
2776
|
this.pendingToolResults.set(pendingResult.toolCallId, pendingResult);
|
|
2804
2777
|
}
|
|
2805
2778
|
this.persistedTurnSettings = options.turnSettings;
|
|
2806
2779
|
this.resumedToolsContext = options.resumedToolsContext;
|
|
2807
|
-
this.turnState =
|
|
2780
|
+
this.turnState = options.turnState ?? (this.pendingToolApprovals.size > 0 ? "awaiting-approval" : this.pendingToolResults.size > 0 ? "awaiting-tool-result" : "idle");
|
|
2808
2781
|
this.isResume = options.underlyingSession.isResume;
|
|
2809
2782
|
}
|
|
2810
2783
|
/**
|
|
@@ -3171,9 +3144,8 @@ var HarnessAgentSession = class {
|
|
|
3171
3144
|
};
|
|
3172
3145
|
}
|
|
3173
3146
|
async suspendCurrentTurn(options) {
|
|
3174
|
-
var _a4;
|
|
3175
3147
|
this.clearActivePromptControl();
|
|
3176
|
-
|
|
3148
|
+
this.suspendedTurnState ??= (async () => {
|
|
3177
3149
|
const raw = await options.session.doSuspendTurn();
|
|
3178
3150
|
const validated = await validateLifecycleStateData({
|
|
3179
3151
|
harness: this.harness,
|
|
@@ -3265,14 +3237,14 @@ var HarnessAgentSession = class {
|
|
|
3265
3237
|
}
|
|
3266
3238
|
setPromptControl(options) {
|
|
3267
3239
|
const activePromptControl = this.activePromptControl;
|
|
3268
|
-
if (this.sessionState !== "active" || this.turnState !== "running" || this.activeTurnSequence !== options.turnId ||
|
|
3240
|
+
if (this.sessionState !== "active" || this.turnState !== "running" || this.activeTurnSequence !== options.turnId || activePromptControl?.turnId !== options.turnId) {
|
|
3269
3241
|
return;
|
|
3270
3242
|
}
|
|
3271
3243
|
this.settleActivePromptControl(options.control);
|
|
3272
3244
|
}
|
|
3273
3245
|
async waitForPromptControl(options) {
|
|
3274
3246
|
const activePromptControl = this.activePromptControl;
|
|
3275
|
-
if (
|
|
3247
|
+
if (activePromptControl?.turnId !== options.turnId) return;
|
|
3276
3248
|
await activePromptControl.promise;
|
|
3277
3249
|
}
|
|
3278
3250
|
settleActivePromptControl(control) {
|
|
@@ -3300,11 +3272,10 @@ var HarnessAgentSession = class {
|
|
|
3300
3272
|
this.turnState = "idle";
|
|
3301
3273
|
}
|
|
3302
3274
|
resolveActiveTurnSettings(options) {
|
|
3303
|
-
var _a4, _b4;
|
|
3304
3275
|
if (this.activeTurnSettings != null) {
|
|
3305
3276
|
return this.activeTurnSettings;
|
|
3306
3277
|
}
|
|
3307
|
-
const persisted =
|
|
3278
|
+
const persisted = this.persistedTurnSettings ?? {
|
|
3308
3279
|
...options.model == null ? {} : { model: options.model },
|
|
3309
3280
|
skills: options.skills,
|
|
3310
3281
|
...options.instructions == null ? {} : { instructions: options.instructions },
|
|
@@ -3324,7 +3295,7 @@ var HarnessAgentSession = class {
|
|
|
3324
3295
|
this.activeTurnSettings = {
|
|
3325
3296
|
persisted,
|
|
3326
3297
|
tools: options.tools,
|
|
3327
|
-
toolsContext:
|
|
3298
|
+
toolsContext: this.resumedToolsContext ?? options.toolsContext,
|
|
3328
3299
|
activeTools,
|
|
3329
3300
|
builtinToolFiltering: options.builtinToolFiltering
|
|
3330
3301
|
};
|
|
@@ -3349,7 +3320,7 @@ var HarnessAgentSession = class {
|
|
|
3349
3320
|
// src/agent/harness-agent-tool-approval-continuation.ts
|
|
3350
3321
|
function collectHarnessAgentToolApprovalContinuations(input) {
|
|
3351
3322
|
const lastMessage = input.messages.at(-1);
|
|
3352
|
-
if (
|
|
3323
|
+
if (lastMessage?.role !== "tool") return [];
|
|
3353
3324
|
const toolCallIds = /* @__PURE__ */ new Set();
|
|
3354
3325
|
const approvalRequestsByApprovalId = /* @__PURE__ */ new Map();
|
|
3355
3326
|
for (const message of input.messages) {
|
|
@@ -3393,7 +3364,7 @@ function collectHarnessAgentToolApprovalContinuations(input) {
|
|
|
3393
3364
|
// src/agent/harness-agent-tool-result-continuation.ts
|
|
3394
3365
|
function collectHarnessAgentToolResultContinuations(input) {
|
|
3395
3366
|
const lastMessage = input.messages.at(-1);
|
|
3396
|
-
if (
|
|
3367
|
+
if (lastMessage?.role !== "tool") return [];
|
|
3397
3368
|
return lastMessage.content.filter((part) => part.type === "tool-result");
|
|
3398
3369
|
}
|
|
3399
3370
|
|
|
@@ -3518,7 +3489,7 @@ function resolveBootstrapPath({
|
|
|
3518
3489
|
}
|
|
3519
3490
|
|
|
3520
3491
|
// src/agent/internal/sandbox-bootstrap.ts
|
|
3521
|
-
import { posix as
|
|
3492
|
+
import { posix as posix6 } from "path";
|
|
3522
3493
|
|
|
3523
3494
|
// src/utils/resolve-sandbox-default-working-directory.ts
|
|
3524
3495
|
import { posix as posix4 } from "path";
|
|
@@ -3566,6 +3537,59 @@ async function resolveSandboxHomeDir({
|
|
|
3566
3537
|
return homeDir;
|
|
3567
3538
|
}
|
|
3568
3539
|
|
|
3540
|
+
// src/agent/internal/on-bootstrap-marker.ts
|
|
3541
|
+
import { posix as posix5 } from "path";
|
|
3542
|
+
async function onBootstrapMarkerPath({
|
|
3543
|
+
session,
|
|
3544
|
+
bootstrapHash,
|
|
3545
|
+
abortSignal
|
|
3546
|
+
}) {
|
|
3547
|
+
const digest = new Uint8Array(
|
|
3548
|
+
await crypto.subtle.digest(
|
|
3549
|
+
"SHA-256",
|
|
3550
|
+
new TextEncoder().encode(bootstrapHash)
|
|
3551
|
+
)
|
|
3552
|
+
);
|
|
3553
|
+
const filename = Array.from(
|
|
3554
|
+
digest,
|
|
3555
|
+
(byte) => byte.toString(16).padStart(2, "0")
|
|
3556
|
+
).join("");
|
|
3557
|
+
return posix5.join(
|
|
3558
|
+
harnessStateDirectoryPath({
|
|
3559
|
+
sandboxHomeDir: await resolveSandboxHomeDir({
|
|
3560
|
+
sandbox: session,
|
|
3561
|
+
abortSignal
|
|
3562
|
+
})
|
|
3563
|
+
}),
|
|
3564
|
+
".on-bootstrap",
|
|
3565
|
+
`${filename}.ok`
|
|
3566
|
+
);
|
|
3567
|
+
}
|
|
3568
|
+
async function hasOnBootstrapMarker(options) {
|
|
3569
|
+
return await options.session.readTextFile({
|
|
3570
|
+
path: await onBootstrapMarkerPath(options),
|
|
3571
|
+
abortSignal: options.abortSignal
|
|
3572
|
+
}) !== null;
|
|
3573
|
+
}
|
|
3574
|
+
async function writeOnBootstrapMarker(options) {
|
|
3575
|
+
const path2 = await onBootstrapMarkerPath(options);
|
|
3576
|
+
const result = await options.session.run({
|
|
3577
|
+
command: 'mkdir -p "$MARKER_DIR"',
|
|
3578
|
+
env: { MARKER_DIR: posix5.dirname(path2) },
|
|
3579
|
+
abortSignal: options.abortSignal
|
|
3580
|
+
});
|
|
3581
|
+
if (result.exitCode !== 0) {
|
|
3582
|
+
throw new Error(
|
|
3583
|
+
`Failed to create onBootstrap marker directory: ${result.stderr || result.stdout}`
|
|
3584
|
+
);
|
|
3585
|
+
}
|
|
3586
|
+
await options.session.writeTextFile({
|
|
3587
|
+
path: path2,
|
|
3588
|
+
content: "",
|
|
3589
|
+
abortSignal: options.abortSignal
|
|
3590
|
+
});
|
|
3591
|
+
}
|
|
3592
|
+
|
|
3569
3593
|
// src/agent/internal/sandbox-bootstrap.ts
|
|
3570
3594
|
var SANDBOX_BOOTSTRAP_IDENTITY_VERSION = 1;
|
|
3571
3595
|
function validateSandboxBootstrapSettings(settings) {
|
|
@@ -3592,10 +3616,10 @@ function normalizeSandboxWorkDir(workDir) {
|
|
|
3592
3616
|
"HarnessAgent: `sandboxConfig.workDir` must use POSIX path separators."
|
|
3593
3617
|
);
|
|
3594
3618
|
}
|
|
3595
|
-
if (
|
|
3619
|
+
if (posix6.isAbsolute(workDir)) {
|
|
3596
3620
|
throw new Error("HarnessAgent: `sandboxConfig.workDir` must be relative.");
|
|
3597
3621
|
}
|
|
3598
|
-
const normalized =
|
|
3622
|
+
const normalized = posix6.normalize(workDir);
|
|
3599
3623
|
if (normalized === "." || normalized === ".." || normalized.startsWith("../")) {
|
|
3600
3624
|
throw new Error(
|
|
3601
3625
|
"HarnessAgent: `sandboxConfig.workDir` must stay inside the sandbox default working directory."
|
|
@@ -3611,7 +3635,7 @@ function resolveSessionWorkDir({
|
|
|
3611
3635
|
}) {
|
|
3612
3636
|
return joinSandboxPath({
|
|
3613
3637
|
base: defaultWorkingDirectory,
|
|
3614
|
-
path: workDir
|
|
3638
|
+
path: workDir ?? `${encodeHarnessPathSegment(harnessId)}-${encodeHarnessPathSegment(sessionId)}`
|
|
3615
3639
|
});
|
|
3616
3640
|
}
|
|
3617
3641
|
async function createSandboxBootstrapPlan({
|
|
@@ -3639,6 +3663,7 @@ async function createSandboxBootstrapPlan({
|
|
|
3639
3663
|
recipeIdentity,
|
|
3640
3664
|
workDir,
|
|
3641
3665
|
onBootstrap: settings.onBootstrap,
|
|
3666
|
+
bootstrapHash: settings.bootstrapHash,
|
|
3642
3667
|
abortSignal: opts.abortSignal
|
|
3643
3668
|
})
|
|
3644
3669
|
} : {}
|
|
@@ -3650,6 +3675,8 @@ async function runSandboxBootstrap({
|
|
|
3650
3675
|
recipeIdentity,
|
|
3651
3676
|
workDir,
|
|
3652
3677
|
onBootstrap,
|
|
3678
|
+
bootstrapHash,
|
|
3679
|
+
skipOnBootstrapIfMarked = false,
|
|
3653
3680
|
defaultWorkingDirectory,
|
|
3654
3681
|
abortSignal
|
|
3655
3682
|
}) {
|
|
@@ -3674,7 +3701,9 @@ async function runSandboxBootstrap({
|
|
|
3674
3701
|
});
|
|
3675
3702
|
}
|
|
3676
3703
|
if (onBootstrap == null) return;
|
|
3677
|
-
|
|
3704
|
+
if (skipOnBootstrapIfMarked && bootstrapHash != null && await hasOnBootstrapMarker({ session, bootstrapHash, abortSignal }))
|
|
3705
|
+
return;
|
|
3706
|
+
const resolvedDefaultWorkingDirectory = defaultWorkingDirectory ?? await resolveSandboxDefaultWorkingDirectory({
|
|
3678
3707
|
sandboxSession: session,
|
|
3679
3708
|
abortSignal
|
|
3680
3709
|
});
|
|
@@ -3688,6 +3717,9 @@ async function runSandboxBootstrap({
|
|
|
3688
3717
|
abortSignal
|
|
3689
3718
|
});
|
|
3690
3719
|
await onBootstrap({ session, workDir: bootstrapWorkDir, abortSignal });
|
|
3720
|
+
if (bootstrapHash != null) {
|
|
3721
|
+
await writeOnBootstrapMarker({ session, bootstrapHash, abortSignal });
|
|
3722
|
+
}
|
|
3691
3723
|
}
|
|
3692
3724
|
async function ensureSandboxDirectory({
|
|
3693
3725
|
session,
|
|
@@ -3717,9 +3749,9 @@ async function hashSandboxBootstrapIdentity({
|
|
|
3717
3749
|
chunks.push(encoder.encode("\0"));
|
|
3718
3750
|
};
|
|
3719
3751
|
pushString(String(SANDBOX_BOOTSTRAP_IDENTITY_VERSION));
|
|
3720
|
-
pushString(recipeIdentity
|
|
3721
|
-
pushString(bootstrapHash
|
|
3722
|
-
pushString(workDir
|
|
3752
|
+
pushString(recipeIdentity ?? "");
|
|
3753
|
+
pushString(bootstrapHash ?? "");
|
|
3754
|
+
pushString(workDir ?? "");
|
|
3723
3755
|
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
3724
3756
|
const buffer = new Uint8Array(totalLength);
|
|
3725
3757
|
let offset = 0;
|
|
@@ -3739,7 +3771,7 @@ function joinSandboxPath({
|
|
|
3739
3771
|
base,
|
|
3740
3772
|
path: path2
|
|
3741
3773
|
}) {
|
|
3742
|
-
return
|
|
3774
|
+
return posix6.join(base, path2);
|
|
3743
3775
|
}
|
|
3744
3776
|
|
|
3745
3777
|
// src/agent/internal/resolve-observability.ts
|
|
@@ -3751,10 +3783,9 @@ function parseList(value) {
|
|
|
3751
3783
|
return items.length > 0 ? items : void 0;
|
|
3752
3784
|
}
|
|
3753
3785
|
function resolveDebugConfig(debug, env = process.env) {
|
|
3754
|
-
|
|
3755
|
-
const
|
|
3756
|
-
const
|
|
3757
|
-
const subsystems = (debug == null ? void 0 : debug.subsystems) ? [...debug.subsystems] : parseList(env.HARNESS_DEBUG_SUBSYSTEMS);
|
|
3786
|
+
const enabled = debug?.enabled ?? ENV_TRUTHY.has((env.HARNESS_DEBUG ?? "").toLowerCase());
|
|
3787
|
+
const level = debug?.level ?? env.HARNESS_DEBUG_LEVEL ?? "debug";
|
|
3788
|
+
const subsystems = debug?.subsystems ? [...debug.subsystems] : parseList(env.HARNESS_DEBUG_SUBSYSTEMS);
|
|
3758
3789
|
return { enabled, level, subsystems };
|
|
3759
3790
|
}
|
|
3760
3791
|
function toHarnessDiagnostic(d) {
|
|
@@ -3772,36 +3803,33 @@ function toHarnessDiagnostic(d) {
|
|
|
3772
3803
|
};
|
|
3773
3804
|
}
|
|
3774
3805
|
function formatForStderr(d) {
|
|
3775
|
-
var _a4;
|
|
3776
3806
|
const parts = [`[harness:${d.level}]`, d.subsystem, d.message].filter(
|
|
3777
3807
|
Boolean
|
|
3778
3808
|
);
|
|
3779
3809
|
let line = parts.join(" ");
|
|
3780
3810
|
if (d.error) {
|
|
3781
|
-
line += ` (${
|
|
3811
|
+
line += ` (${d.error.name ?? "Error"}: ${d.error.message})`;
|
|
3782
3812
|
}
|
|
3783
3813
|
return `${line}
|
|
3784
3814
|
`;
|
|
3785
3815
|
}
|
|
3786
3816
|
function buildObservability(options) {
|
|
3787
|
-
var _a4;
|
|
3788
3817
|
const resolved = resolveDebugConfig(options.settings.debug);
|
|
3789
3818
|
if (!resolved.enabled) return void 0;
|
|
3790
3819
|
const onLog = options.settings.onLog;
|
|
3791
|
-
const integrations =
|
|
3820
|
+
const integrations = options.settings.telemetry?.integrations ? asArray(options.settings.telemetry.integrations) : [];
|
|
3792
3821
|
const diagnosticConsumers = integrations.filter(
|
|
3793
3822
|
(integration) => typeof integration.ingestDiagnostic === "function"
|
|
3794
3823
|
);
|
|
3795
3824
|
const report = (emitted) => {
|
|
3796
|
-
var _a5;
|
|
3797
3825
|
const diagnostic = toHarnessDiagnostic(emitted);
|
|
3798
3826
|
try {
|
|
3799
3827
|
process.stderr.write(formatForStderr(diagnostic));
|
|
3800
|
-
} catch
|
|
3828
|
+
} catch {
|
|
3801
3829
|
}
|
|
3802
|
-
onLog
|
|
3830
|
+
onLog?.(diagnostic);
|
|
3803
3831
|
for (const consumer of diagnosticConsumers) {
|
|
3804
|
-
|
|
3832
|
+
consumer.ingestDiagnostic?.(diagnostic);
|
|
3805
3833
|
}
|
|
3806
3834
|
};
|
|
3807
3835
|
return {
|
|
@@ -3826,7 +3854,7 @@ function resolveHarnessAgentToolFiltering(input) {
|
|
|
3826
3854
|
const activeTools = dedupeToolNames({ toolNames: input.activeTools });
|
|
3827
3855
|
const inactiveTools = dedupeToolNames({ toolNames: input.inactiveTools });
|
|
3828
3856
|
validateToolNames({
|
|
3829
|
-
requestedToolNames: activeTools
|
|
3857
|
+
requestedToolNames: activeTools ?? inactiveTools,
|
|
3830
3858
|
availableToolNames: allToolNames
|
|
3831
3859
|
});
|
|
3832
3860
|
const userToolNames = Object.keys(input.userTools);
|
|
@@ -3874,11 +3902,115 @@ function filterToolSet(input) {
|
|
|
3874
3902
|
);
|
|
3875
3903
|
}
|
|
3876
3904
|
|
|
3905
|
+
// src/agent/internal/prepared-sandbox-identity.ts
|
|
3906
|
+
var PREPARED_SANDBOX_IDENTITY_VERSION = 1;
|
|
3907
|
+
async function resolvePreparedSandboxIdentity({
|
|
3908
|
+
recipeIdentities,
|
|
3909
|
+
bootstrapHash,
|
|
3910
|
+
workDir
|
|
3911
|
+
}) {
|
|
3912
|
+
const entries = Object.entries(recipeIdentities).sort(
|
|
3913
|
+
([a], [b]) => a.localeCompare(b)
|
|
3914
|
+
);
|
|
3915
|
+
if (entries.length === 0 && bootstrapHash == null) return void 0;
|
|
3916
|
+
const encoder = new TextEncoder();
|
|
3917
|
+
const chunks = [];
|
|
3918
|
+
const pushString = (value) => {
|
|
3919
|
+
chunks.push(encoder.encode(value));
|
|
3920
|
+
chunks.push(encoder.encode("\0"));
|
|
3921
|
+
};
|
|
3922
|
+
pushString(String(PREPARED_SANDBOX_IDENTITY_VERSION));
|
|
3923
|
+
pushString(workDir ?? "");
|
|
3924
|
+
pushString(bootstrapHash ?? "");
|
|
3925
|
+
for (const [harnessId, identity] of entries) {
|
|
3926
|
+
pushString(harnessId);
|
|
3927
|
+
pushString(identity);
|
|
3928
|
+
}
|
|
3929
|
+
const buffer = new Uint8Array(
|
|
3930
|
+
chunks.reduce((sum, chunk) => sum + chunk.length, 0)
|
|
3931
|
+
);
|
|
3932
|
+
let offset = 0;
|
|
3933
|
+
for (const chunk of chunks) {
|
|
3934
|
+
buffer.set(chunk, offset);
|
|
3935
|
+
offset += chunk.length;
|
|
3936
|
+
}
|
|
3937
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", buffer));
|
|
3938
|
+
return Array.from(
|
|
3939
|
+
digest.slice(0, 8),
|
|
3940
|
+
(byte) => byte.toString(16).padStart(2, "0")
|
|
3941
|
+
).join("");
|
|
3942
|
+
}
|
|
3943
|
+
|
|
3944
|
+
// src/agent/create-harness-sandbox-template.ts
|
|
3945
|
+
async function createHarnessSandboxTemplate(options) {
|
|
3946
|
+
if (options.harnesses.length === 0) {
|
|
3947
|
+
throw new Error(
|
|
3948
|
+
"createHarnessSandboxTemplate: at least one harness must be provided."
|
|
3949
|
+
);
|
|
3950
|
+
}
|
|
3951
|
+
const settings = options.sandboxConfig ?? {};
|
|
3952
|
+
validateSandboxBootstrapSettings(settings);
|
|
3953
|
+
const workDir = settings.workDir == null ? void 0 : normalizeSandboxWorkDir(settings.workDir);
|
|
3954
|
+
const harnesses = [
|
|
3955
|
+
...new Map(
|
|
3956
|
+
options.harnesses.map((harness) => [harness.harnessId, harness])
|
|
3957
|
+
).values()
|
|
3958
|
+
].sort((a, b) => a.harnessId.localeCompare(b.harnessId));
|
|
3959
|
+
const recipes = await Promise.all(
|
|
3960
|
+
harnesses.map(async (harness) => {
|
|
3961
|
+
const recipe = await harness.getBootstrap?.({});
|
|
3962
|
+
return recipe == null ? void 0 : {
|
|
3963
|
+
recipe,
|
|
3964
|
+
identity: await hashHarnessBootstrap(recipe)
|
|
3965
|
+
};
|
|
3966
|
+
})
|
|
3967
|
+
);
|
|
3968
|
+
const recipeIdentities = {};
|
|
3969
|
+
for (let index = 0; index < harnesses.length; index++) {
|
|
3970
|
+
const entry = recipes[index];
|
|
3971
|
+
if (entry != null)
|
|
3972
|
+
recipeIdentities[harnesses[index].harnessId] = entry.identity;
|
|
3973
|
+
}
|
|
3974
|
+
const identity = await resolvePreparedSandboxIdentity({
|
|
3975
|
+
recipeIdentities,
|
|
3976
|
+
bootstrapHash: settings.bootstrapHash,
|
|
3977
|
+
workDir
|
|
3978
|
+
});
|
|
3979
|
+
if (identity == null) return void 0;
|
|
3980
|
+
return {
|
|
3981
|
+
identity,
|
|
3982
|
+
prepare: async ({ session, abortSignal }) => {
|
|
3983
|
+
for (const entry of recipes) {
|
|
3984
|
+
if (entry != null) {
|
|
3985
|
+
await runSandboxBootstrap({
|
|
3986
|
+
session,
|
|
3987
|
+
recipe: entry.recipe,
|
|
3988
|
+
recipeIdentity: entry.identity,
|
|
3989
|
+
abortSignal
|
|
3990
|
+
});
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
await runSandboxBootstrap({
|
|
3994
|
+
session,
|
|
3995
|
+
workDir,
|
|
3996
|
+
onBootstrap: settings.onBootstrap,
|
|
3997
|
+
bootstrapHash: settings.bootstrapHash,
|
|
3998
|
+
skipOnBootstrapIfMarked: true,
|
|
3999
|
+
abortSignal
|
|
4000
|
+
});
|
|
4001
|
+
}
|
|
4002
|
+
};
|
|
4003
|
+
}
|
|
4004
|
+
|
|
3877
4005
|
// src/agent/harness-agent.ts
|
|
3878
4006
|
var HarnessAgent = class {
|
|
3879
4007
|
constructor(settings) {
|
|
3880
4008
|
this.version = "agent-v1";
|
|
3881
|
-
|
|
4009
|
+
if (settings.sandbox != null) {
|
|
4010
|
+
console.warn(
|
|
4011
|
+
"HarnessAgent: `sandbox` is deprecated. Supply `sandboxSession` to createSession() instead."
|
|
4012
|
+
);
|
|
4013
|
+
}
|
|
3882
4014
|
const sandboxConfig = resolveSandboxConfig(settings);
|
|
3883
4015
|
validateSandboxBootstrapSettings(sandboxConfig);
|
|
3884
4016
|
this.settings = settings;
|
|
@@ -3890,7 +4022,7 @@ var HarnessAgent = class {
|
|
|
3890
4022
|
"user-agent",
|
|
3891
4023
|
"x-client-app"
|
|
3892
4024
|
]);
|
|
3893
|
-
const forbiddenHeader = Object.keys(
|
|
4025
|
+
const forbiddenHeader = Object.keys(settings.headers ?? {}).map((name4) => name4.toLowerCase()).find((name4) => forbiddenHeaders.has(name4));
|
|
3894
4026
|
if (forbiddenHeader != null) {
|
|
3895
4027
|
throw new Error(
|
|
3896
4028
|
`HarnessAgent: \`headers\` must not include the managed header \`${forbiddenHeader}\`.`
|
|
@@ -3899,7 +4031,7 @@ var HarnessAgent = class {
|
|
|
3899
4031
|
const headers = normalizeHeaders(settings.headers);
|
|
3900
4032
|
this.headers = Object.keys(headers).length === 0 ? void 0 : headers;
|
|
3901
4033
|
this.id = settings.id;
|
|
3902
|
-
const userTools =
|
|
4034
|
+
const userTools = settings.tools ?? {};
|
|
3903
4035
|
assertNoReservedQuestionTool({
|
|
3904
4036
|
harness: settings.harness,
|
|
3905
4037
|
userTools
|
|
@@ -3937,6 +4069,12 @@ var HarnessAgent = class {
|
|
|
3937
4069
|
get hasOutput() {
|
|
3938
4070
|
return this.settings.output != null;
|
|
3939
4071
|
}
|
|
4072
|
+
getSandboxTemplate() {
|
|
4073
|
+
return createHarnessSandboxTemplate({
|
|
4074
|
+
harnesses: [this.settings.harness],
|
|
4075
|
+
sandboxConfig: this.sandboxConfig
|
|
4076
|
+
});
|
|
4077
|
+
}
|
|
3940
4078
|
/**
|
|
3941
4079
|
* Start a fresh session, or resume from state previously returned by
|
|
3942
4080
|
* `session.detach()` or `session.stop()`. The returned
|
|
@@ -3945,12 +4083,11 @@ var HarnessAgent = class {
|
|
|
3945
4083
|
* `session.destroy()`.
|
|
3946
4084
|
*/
|
|
3947
4085
|
async createSession(options) {
|
|
3948
|
-
|
|
3949
|
-
const
|
|
3950
|
-
const
|
|
3951
|
-
const
|
|
3952
|
-
const
|
|
3953
|
-
const abortSignal = options == null ? void 0 : options.abortSignal;
|
|
4086
|
+
const sessionId = options?.sessionId ?? generateId3();
|
|
4087
|
+
const resumeFrom = options?.resumeFrom;
|
|
4088
|
+
const continueFrom = options?.continueFrom;
|
|
4089
|
+
const providedSandboxSession = options?.sandboxSession;
|
|
4090
|
+
const abortSignal = options?.abortSignal;
|
|
3954
4091
|
const harness = this.settings.harness;
|
|
3955
4092
|
const sandboxProvider = this.settings.sandbox;
|
|
3956
4093
|
const ownsSandboxLifecycle = providedSandboxSession == null;
|
|
@@ -3975,8 +4112,8 @@ var HarnessAgent = class {
|
|
|
3975
4112
|
expectedType: "continue-turn"
|
|
3976
4113
|
});
|
|
3977
4114
|
}
|
|
3978
|
-
const effectiveContinueFrom = validatedContinueFrom
|
|
3979
|
-
if (
|
|
4115
|
+
const effectiveContinueFrom = validatedContinueFrom ?? validatedResumeFrom?.continueFrom;
|
|
4116
|
+
if (options?.toolsContext != null && effectiveContinueFrom == null) {
|
|
3980
4117
|
throw new Error(
|
|
3981
4118
|
"HarnessAgent.createSession: `toolsContext` can only rebind an unfinished turn from `continueFrom` or `resumeFrom`."
|
|
3982
4119
|
);
|
|
@@ -3997,7 +4134,7 @@ var HarnessAgent = class {
|
|
|
3997
4134
|
sessionId,
|
|
3998
4135
|
workDir: this.sandboxConfig.workDir
|
|
3999
4136
|
});
|
|
4000
|
-
const recipe = await
|
|
4137
|
+
const recipe = await harness.getBootstrap?.({ abortSignal });
|
|
4001
4138
|
if (recipe != null) {
|
|
4002
4139
|
const recipeIdentity = await hashHarnessBootstrap(recipe);
|
|
4003
4140
|
try {
|
|
@@ -4029,7 +4166,7 @@ var HarnessAgent = class {
|
|
|
4029
4166
|
"HarnessAgent.createSession: configure `sandbox` on HarnessAgent or pass `sandboxSession` to createSession()."
|
|
4030
4167
|
);
|
|
4031
4168
|
}
|
|
4032
|
-
const recipe = await
|
|
4169
|
+
const recipe = await harness.getBootstrap?.({ abortSignal });
|
|
4033
4170
|
if (isResumedSession) {
|
|
4034
4171
|
if (sandboxProvider.resumeSession == null) {
|
|
4035
4172
|
throw new HarnessCapabilityUnsupportedError({
|
|
@@ -4118,6 +4255,14 @@ var HarnessAgent = class {
|
|
|
4118
4255
|
}
|
|
4119
4256
|
}
|
|
4120
4257
|
try {
|
|
4258
|
+
await runSandboxBootstrap({
|
|
4259
|
+
session: getRestrictedSandboxSession(sandboxSession),
|
|
4260
|
+
workDir: this.sandboxConfig.workDir,
|
|
4261
|
+
onBootstrap: this.sandboxConfig.onBootstrap,
|
|
4262
|
+
bootstrapHash: this.sandboxConfig.bootstrapHash,
|
|
4263
|
+
skipOnBootstrapIfMarked: true,
|
|
4264
|
+
abortSignal
|
|
4265
|
+
});
|
|
4121
4266
|
await ensureSandboxDirectory({
|
|
4122
4267
|
session: sandboxSession,
|
|
4123
4268
|
workDir: sessionWorkDir,
|
|
@@ -4161,10 +4306,10 @@ var HarnessAgent = class {
|
|
|
4161
4306
|
ownsSandboxLifecycle,
|
|
4162
4307
|
sessionWorkDir,
|
|
4163
4308
|
toolApproval: this.settings.toolApproval,
|
|
4164
|
-
pendingToolApprovals: effectiveContinueFrom
|
|
4165
|
-
pendingToolResults: effectiveContinueFrom
|
|
4166
|
-
turnSettings: effectiveContinueFrom
|
|
4167
|
-
resumedToolsContext: options
|
|
4309
|
+
pendingToolApprovals: effectiveContinueFrom?.pendingToolApprovals,
|
|
4310
|
+
pendingToolResults: effectiveContinueFrom?.pendingToolResults,
|
|
4311
|
+
turnSettings: effectiveContinueFrom?.turnSettings,
|
|
4312
|
+
resumedToolsContext: options?.toolsContext,
|
|
4168
4313
|
turnState: effectiveContinueFrom == null ? "idle" : effectiveContinueFrom.pendingToolApprovals != null && effectiveContinueFrom.pendingToolApprovals.length > 0 ? "awaiting-approval" : effectiveContinueFrom.pendingToolResults != null && effectiveContinueFrom.pendingToolResults.length > 0 ? "awaiting-tool-result" : "suspended"
|
|
4169
4314
|
});
|
|
4170
4315
|
} catch (error) {
|
|
@@ -4205,13 +4350,12 @@ var HarnessAgent = class {
|
|
|
4205
4350
|
* consuming a turn that crossed a process boundary.
|
|
4206
4351
|
*/
|
|
4207
4352
|
async continueGenerate(options) {
|
|
4208
|
-
var _a4, _b4;
|
|
4209
4353
|
const runtimeContext = {};
|
|
4210
4354
|
const { result, done } = await this._startContinueTurn({
|
|
4211
4355
|
session: options.session,
|
|
4212
4356
|
turnInput: {
|
|
4213
|
-
toolApprovalContinuations:
|
|
4214
|
-
toolResultContinuations:
|
|
4357
|
+
toolApprovalContinuations: options.toolApprovalContinuations ?? [],
|
|
4358
|
+
toolResultContinuations: options.toolResultContinuations ?? []
|
|
4215
4359
|
},
|
|
4216
4360
|
runtimeContext,
|
|
4217
4361
|
abortSignal: options.abortSignal
|
|
@@ -4228,13 +4372,12 @@ var HarnessAgent = class {
|
|
|
4228
4372
|
* follows from how the adapter resumed the session.
|
|
4229
4373
|
*/
|
|
4230
4374
|
async continueStream(options) {
|
|
4231
|
-
var _a4, _b4;
|
|
4232
4375
|
const runtimeContext = {};
|
|
4233
4376
|
const { result, ready } = await this._startContinueTurn({
|
|
4234
4377
|
session: options.session,
|
|
4235
4378
|
turnInput: {
|
|
4236
|
-
toolApprovalContinuations:
|
|
4237
|
-
toolResultContinuations:
|
|
4379
|
+
toolApprovalContinuations: options.toolApprovalContinuations ?? [],
|
|
4380
|
+
toolResultContinuations: options.toolResultContinuations ?? []
|
|
4238
4381
|
},
|
|
4239
4382
|
runtimeContext,
|
|
4240
4383
|
abortSignal: options.abortSignal
|
|
@@ -4302,31 +4445,30 @@ var HarnessAgent = class {
|
|
|
4302
4445
|
};
|
|
4303
4446
|
}
|
|
4304
4447
|
_resolveLifecycleCallbacks(call) {
|
|
4305
|
-
var _a4, _b4, _c, _d, _e, _f;
|
|
4306
4448
|
return {
|
|
4307
4449
|
onStart: mergeCallbacks(
|
|
4308
4450
|
this.settings.onStart,
|
|
4309
|
-
|
|
4451
|
+
call?.onStart ?? call?.experimental_onStart
|
|
4310
4452
|
),
|
|
4311
4453
|
onStepStart: mergeCallbacks(
|
|
4312
4454
|
this.settings.onStepStart,
|
|
4313
|
-
|
|
4455
|
+
call?.onStepStart ?? call?.experimental_onStepStart
|
|
4314
4456
|
),
|
|
4315
4457
|
onLanguageModelCallStart: this.settings.onLanguageModelCallStart,
|
|
4316
4458
|
onLanguageModelCallEnd: this.settings.onLanguageModelCallEnd,
|
|
4317
4459
|
onToolExecutionStart: mergeCallbacks(
|
|
4318
4460
|
this.settings.onToolExecutionStart,
|
|
4319
|
-
|
|
4461
|
+
call?.onToolExecutionStart ?? call?.experimental_onToolCallStart
|
|
4320
4462
|
),
|
|
4321
4463
|
onToolExecutionEnd: mergeCallbacks(
|
|
4322
4464
|
this.settings.onToolExecutionEnd,
|
|
4323
|
-
|
|
4465
|
+
call?.onToolExecutionEnd ?? call?.experimental_onToolCallFinish
|
|
4324
4466
|
),
|
|
4325
4467
|
onStepEnd: mergeCallbacks(
|
|
4326
4468
|
this.settings.onStepEnd,
|
|
4327
|
-
|
|
4469
|
+
call?.onStepEnd ?? call?.onStepFinish
|
|
4328
4470
|
),
|
|
4329
|
-
onEnd: mergeCallbacks(this.settings.onEnd,
|
|
4471
|
+
onEnd: mergeCallbacks(this.settings.onEnd, call?.onEnd ?? call?.onFinish)
|
|
4330
4472
|
};
|
|
4331
4473
|
}
|
|
4332
4474
|
_resolveContinueTurnInput(options) {
|
|
@@ -4361,7 +4503,7 @@ var HarnessAgent = class {
|
|
|
4361
4503
|
if (Array.isArray(messages)) {
|
|
4362
4504
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
4363
4505
|
const message = messages[i];
|
|
4364
|
-
if (
|
|
4506
|
+
if (message?.role === "user") return message;
|
|
4365
4507
|
}
|
|
4366
4508
|
throw new Error(
|
|
4367
4509
|
'HarnessAgent: messages must contain at least one `role: "user"` entry.'
|
|
@@ -4370,7 +4512,6 @@ var HarnessAgent = class {
|
|
|
4370
4512
|
throw new Error("HarnessAgent: either `prompt` or `messages` is required.");
|
|
4371
4513
|
}
|
|
4372
4514
|
async _preparePromptTurnInput(options) {
|
|
4373
|
-
var _a4, _b4, _c, _d;
|
|
4374
4515
|
let callOptions = options;
|
|
4375
4516
|
if (this.settings.callOptionsSchema != null && options.options !== void 0) {
|
|
4376
4517
|
const validatedOptions = await validateTypes({
|
|
@@ -4407,13 +4548,12 @@ var HarnessAgent = class {
|
|
|
4407
4548
|
skills: this.settings.skills,
|
|
4408
4549
|
instructions: this.settings.instructions,
|
|
4409
4550
|
tools: this.settings.tools,
|
|
4410
|
-
toolsContext:
|
|
4551
|
+
toolsContext: this.settings.toolsContext ?? {},
|
|
4411
4552
|
...promptOptions
|
|
4412
4553
|
};
|
|
4413
|
-
const preparedCallArgs =
|
|
4414
|
-
_b4,
|
|
4554
|
+
const preparedCallArgs = await this.settings.prepareCall?.(
|
|
4415
4555
|
baseCallArgs
|
|
4416
|
-
)
|
|
4556
|
+
) ?? baseCallArgs;
|
|
4417
4557
|
if (this._resolveContinueTurnInput(preparedCallArgs) != null) {
|
|
4418
4558
|
throw new Error(
|
|
4419
4559
|
"HarnessAgent.prepareCall must return a fresh user prompt, not a tool continuation."
|
|
@@ -4431,7 +4571,6 @@ var HarnessAgent = class {
|
|
|
4431
4571
|
};
|
|
4432
4572
|
}
|
|
4433
4573
|
_prepareContinueTurnInput(options) {
|
|
4434
|
-
var _a4, _b4;
|
|
4435
4574
|
return {
|
|
4436
4575
|
...this._prepareTurnSettings({
|
|
4437
4576
|
model: this.settings.model,
|
|
@@ -4440,13 +4579,12 @@ var HarnessAgent = class {
|
|
|
4440
4579
|
tools: this.settings.tools,
|
|
4441
4580
|
toolsContext: this.settings.toolsContext
|
|
4442
4581
|
}),
|
|
4443
|
-
toolApprovalContinuations:
|
|
4444
|
-
toolResultContinuations:
|
|
4582
|
+
toolApprovalContinuations: options.toolApprovalContinuations ?? [],
|
|
4583
|
+
toolResultContinuations: options.toolResultContinuations ?? []
|
|
4445
4584
|
};
|
|
4446
4585
|
}
|
|
4447
4586
|
_prepareTurnSettings(options) {
|
|
4448
|
-
|
|
4449
|
-
const userTools = (_a4 = options.tools) != null ? _a4 : {};
|
|
4587
|
+
const userTools = options.tools ?? {};
|
|
4450
4588
|
assertNoReservedQuestionTool({
|
|
4451
4589
|
harness: this.settings.harness,
|
|
4452
4590
|
userTools
|
|
@@ -4464,10 +4602,10 @@ var HarnessAgent = class {
|
|
|
4464
4602
|
});
|
|
4465
4603
|
return {
|
|
4466
4604
|
model: options.model,
|
|
4467
|
-
skills:
|
|
4468
|
-
instructions: typeof options.instructions === "string" ? options.instructions :
|
|
4605
|
+
skills: options.skills ?? [],
|
|
4606
|
+
instructions: typeof options.instructions === "string" ? options.instructions : options.instructions?.content,
|
|
4469
4607
|
tools,
|
|
4470
|
-
toolsContext:
|
|
4608
|
+
toolsContext: options.toolsContext ?? {},
|
|
4471
4609
|
activeTools: toolFiltering.activeUserTools,
|
|
4472
4610
|
toolSpecs: this._toToolSpecs(toolFiltering.activeUserTools),
|
|
4473
4611
|
builtinToolFiltering: toolFiltering.builtinToolFiltering
|
|
@@ -4490,7 +4628,7 @@ var HarnessAgent = class {
|
|
|
4490
4628
|
inputSchema = asSchema(
|
|
4491
4629
|
t.inputSchema
|
|
4492
4630
|
).jsonSchema;
|
|
4493
|
-
} catch
|
|
4631
|
+
} catch {
|
|
4494
4632
|
}
|
|
4495
4633
|
}
|
|
4496
4634
|
specs.push({ name: name4, description: t.description, inputSchema });
|
|
@@ -4507,8 +4645,7 @@ var HarnessAgent = class {
|
|
|
4507
4645
|
return new HarnessGenerateTextResult({ steps, usage, responseMessages, output });
|
|
4508
4646
|
}
|
|
4509
4647
|
async _resolveResponseFormat() {
|
|
4510
|
-
|
|
4511
|
-
const responseFormat = await ((_a4 = this.settings.output) == null ? void 0 : _a4.responseFormat);
|
|
4648
|
+
const responseFormat = await this.settings.output?.responseFormat;
|
|
4512
4649
|
if (responseFormat == null || responseFormat.type === "text") {
|
|
4513
4650
|
return responseFormat == null ? void 0 : { type: "text" };
|
|
4514
4651
|
}
|
|
@@ -4577,10 +4714,7 @@ var HarnessGenerateTextResult = class {
|
|
|
4577
4714
|
return this.finalStep.rawFinishReason;
|
|
4578
4715
|
}
|
|
4579
4716
|
get warnings() {
|
|
4580
|
-
return this.steps.flatMap((step) =>
|
|
4581
|
-
var _a4;
|
|
4582
|
-
return (_a4 = step.warnings) != null ? _a4 : [];
|
|
4583
|
-
});
|
|
4717
|
+
return this.steps.flatMap((step) => step.warnings ?? []);
|
|
4584
4718
|
}
|
|
4585
4719
|
get reasoning() {
|
|
4586
4720
|
return this.finalStep.content.filter(
|
|
@@ -4604,7 +4738,6 @@ var HarnessGenerateTextResult = class {
|
|
|
4604
4738
|
}
|
|
4605
4739
|
};
|
|
4606
4740
|
function resolveSandboxConfig(settings) {
|
|
4607
|
-
var _a4;
|
|
4608
4741
|
if (settings.onSandboxSession != null) {
|
|
4609
4742
|
console.warn(
|
|
4610
4743
|
"HarnessAgent: `onSandboxSession` is deprecated. Use `sandboxConfig.onSession` instead."
|
|
@@ -4612,7 +4745,7 @@ function resolveSandboxConfig(settings) {
|
|
|
4612
4745
|
}
|
|
4613
4746
|
return {
|
|
4614
4747
|
...settings.sandboxConfig,
|
|
4615
|
-
...
|
|
4748
|
+
...settings.sandboxConfig?.onSession == null && settings.onSandboxSession != null ? { onSession: settings.onSandboxSession } : {}
|
|
4616
4749
|
};
|
|
4617
4750
|
}
|
|
4618
4751
|
async function cleanupAfterStartFailure(input) {
|
|
@@ -4625,8 +4758,10 @@ async function cleanupAfterStartFailure(input) {
|
|
|
4625
4758
|
|
|
4626
4759
|
// src/agent/prepare-harness-sandbox-template.ts
|
|
4627
4760
|
async function prepareHarnessSandboxTemplate(options) {
|
|
4628
|
-
|
|
4629
|
-
|
|
4761
|
+
console.warn(
|
|
4762
|
+
"prepareHarnessSandboxTemplate (prewarmHarness) is deprecated. Use createHarnessSandboxTemplate and a sandbox session creator instead."
|
|
4763
|
+
);
|
|
4764
|
+
const sandboxConfig = options.sandboxConfig ?? {};
|
|
4630
4765
|
validateSandboxBootstrapSettings(sandboxConfig);
|
|
4631
4766
|
const { harness, sandboxProvider, abortSignal } = options;
|
|
4632
4767
|
let recipe;
|
|
@@ -4671,10 +4806,11 @@ async function prepareHarnessSandboxTemplate(options) {
|
|
|
4671
4806
|
var prewarmHarness = prepareHarnessSandboxTemplate;
|
|
4672
4807
|
|
|
4673
4808
|
// src/agent/prepare-sandbox-for-harness.ts
|
|
4674
|
-
var PREPARED_SANDBOX_IDENTITY_VERSION = 1;
|
|
4675
4809
|
async function prepareSandboxForHarness(options) {
|
|
4676
|
-
|
|
4677
|
-
|
|
4810
|
+
console.warn(
|
|
4811
|
+
"prepareSandboxForHarness is deprecated. Use createHarnessSandboxTemplate and template.prepare instead."
|
|
4812
|
+
);
|
|
4813
|
+
const sandboxConfig = options.sandboxConfig ?? {};
|
|
4678
4814
|
validateSandboxBootstrapSettings(sandboxConfig);
|
|
4679
4815
|
if (options.harnesses.length === 0) {
|
|
4680
4816
|
throw new Error(
|
|
@@ -4691,16 +4827,16 @@ async function prepareSandboxForHarness(options) {
|
|
|
4691
4827
|
const skippedHarnessIds = [];
|
|
4692
4828
|
let stateDirectory;
|
|
4693
4829
|
for (const harness of harnesses) {
|
|
4694
|
-
const recipe = await
|
|
4830
|
+
const recipe = await harness.getBootstrap?.({
|
|
4695
4831
|
abortSignal: options.abortSignal
|
|
4696
|
-
})
|
|
4832
|
+
});
|
|
4697
4833
|
if (recipe == null) {
|
|
4698
4834
|
skippedHarnessIds.push(harness.harnessId);
|
|
4699
4835
|
continue;
|
|
4700
4836
|
}
|
|
4701
4837
|
const recipeIdentity = await hashHarnessBootstrap(recipe);
|
|
4702
4838
|
recipeIdentities[harness.harnessId] = recipeIdentity;
|
|
4703
|
-
stateDirectory
|
|
4839
|
+
stateDirectory ??= harnessStateDirectoryPath({
|
|
4704
4840
|
sandboxHomeDir: await resolveSandboxHomeDir({
|
|
4705
4841
|
sandbox: options.session,
|
|
4706
4842
|
abortSignal: options.abortSignal
|
|
@@ -4722,6 +4858,7 @@ async function prepareSandboxForHarness(options) {
|
|
|
4722
4858
|
session: options.session,
|
|
4723
4859
|
workDir,
|
|
4724
4860
|
onBootstrap: sandboxConfig.onBootstrap,
|
|
4861
|
+
bootstrapHash: sandboxConfig.bootstrapHash,
|
|
4725
4862
|
defaultWorkingDirectory,
|
|
4726
4863
|
abortSignal: options.abortSignal
|
|
4727
4864
|
});
|
|
@@ -4737,45 +4874,6 @@ async function prepareSandboxForHarness(options) {
|
|
|
4737
4874
|
skippedHarnessIds
|
|
4738
4875
|
};
|
|
4739
4876
|
}
|
|
4740
|
-
async function resolvePreparedSandboxIdentity({
|
|
4741
|
-
recipeIdentities,
|
|
4742
|
-
bootstrapHash,
|
|
4743
|
-
workDir
|
|
4744
|
-
}) {
|
|
4745
|
-
const entries = Object.entries(recipeIdentities).sort(
|
|
4746
|
-
([a], [b]) => a.localeCompare(b)
|
|
4747
|
-
);
|
|
4748
|
-
if (entries.length === 0 && bootstrapHash == null) {
|
|
4749
|
-
return void 0;
|
|
4750
|
-
}
|
|
4751
|
-
const encoder = new TextEncoder();
|
|
4752
|
-
const chunks = [];
|
|
4753
|
-
const pushString = (value) => {
|
|
4754
|
-
chunks.push(encoder.encode(value));
|
|
4755
|
-
chunks.push(encoder.encode("\0"));
|
|
4756
|
-
};
|
|
4757
|
-
pushString(String(PREPARED_SANDBOX_IDENTITY_VERSION));
|
|
4758
|
-
pushString(workDir != null ? workDir : "");
|
|
4759
|
-
pushString(bootstrapHash != null ? bootstrapHash : "");
|
|
4760
|
-
for (const [harnessId, identity] of entries) {
|
|
4761
|
-
pushString(harnessId);
|
|
4762
|
-
pushString(identity);
|
|
4763
|
-
}
|
|
4764
|
-
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
4765
|
-
const buffer = new Uint8Array(totalLength);
|
|
4766
|
-
let offset = 0;
|
|
4767
|
-
for (const chunk of chunks) {
|
|
4768
|
-
buffer.set(chunk, offset);
|
|
4769
|
-
offset += chunk.length;
|
|
4770
|
-
}
|
|
4771
|
-
const digest = await crypto.subtle.digest("SHA-256", buffer);
|
|
4772
|
-
const bytes = new Uint8Array(digest);
|
|
4773
|
-
let hex = "";
|
|
4774
|
-
for (let i = 0; i < 8; i++) {
|
|
4775
|
-
hex += bytes[i].toString(16).padStart(2, "0");
|
|
4776
|
-
}
|
|
4777
|
-
return hex;
|
|
4778
|
-
}
|
|
4779
4877
|
|
|
4780
4878
|
// src/errors/harness-sandbox-authentication-error.ts
|
|
4781
4879
|
import { AISDKError as AISDKError3 } from "@ai-sdk/provider";
|
|
@@ -4811,10 +4909,9 @@ function getHarnessErrorMessage(error) {
|
|
|
4811
4909
|
// src/agent/observability/file-reporter.ts
|
|
4812
4910
|
import { appendFileSync, mkdirSync } from "fs";
|
|
4813
4911
|
function createFileReporter(options) {
|
|
4814
|
-
|
|
4815
|
-
const fileName = (_a4 = options.fileName) != null ? _a4 : "events.jsonl";
|
|
4912
|
+
const fileName = options.fileName ?? "events.jsonl";
|
|
4816
4913
|
const path2 = `${options.dir}/${fileName}`;
|
|
4817
|
-
const failOnly =
|
|
4914
|
+
const failOnly = options.failOnly ?? false;
|
|
4818
4915
|
const turns = /* @__PURE__ */ new Map();
|
|
4819
4916
|
let lastOpenCallId;
|
|
4820
4917
|
let dirReady = false;
|
|
@@ -4827,7 +4924,7 @@ function createFileReporter(options) {
|
|
|
4827
4924
|
return bucket;
|
|
4828
4925
|
};
|
|
4829
4926
|
const record = (callId, rec) => {
|
|
4830
|
-
const id = callId
|
|
4927
|
+
const id = callId ?? lastOpenCallId;
|
|
4831
4928
|
if (id == null) {
|
|
4832
4929
|
flushLines([rec]);
|
|
4833
4930
|
return;
|
|
@@ -4842,7 +4939,7 @@ function createFileReporter(options) {
|
|
|
4842
4939
|
dirReady = true;
|
|
4843
4940
|
}
|
|
4844
4941
|
appendFileSync(path2, lines.map((l) => JSON.stringify(l)).join("\n") + "\n");
|
|
4845
|
-
} catch
|
|
4942
|
+
} catch {
|
|
4846
4943
|
}
|
|
4847
4944
|
};
|
|
4848
4945
|
const finishTurn = (callId) => {
|
|
@@ -4913,14 +5010,13 @@ function createFileReporter(options) {
|
|
|
4913
5010
|
});
|
|
4914
5011
|
},
|
|
4915
5012
|
onEnd(event) {
|
|
4916
|
-
var _a5;
|
|
4917
5013
|
const e = event;
|
|
4918
5014
|
record(e.callId, {
|
|
4919
5015
|
ts: Date.now(),
|
|
4920
5016
|
kind: "turn-finish",
|
|
4921
5017
|
callId: e.callId,
|
|
4922
5018
|
finishReason: e.finishReason,
|
|
4923
|
-
usage:
|
|
5019
|
+
usage: e.totalUsage ?? e.usage
|
|
4924
5020
|
});
|
|
4925
5021
|
finishTurn(e.callId);
|
|
4926
5022
|
},
|
|
@@ -4947,8 +5043,7 @@ function createFileReporter(options) {
|
|
|
4947
5043
|
|
|
4948
5044
|
// src/agent/observability/trace-tree-reporter.ts
|
|
4949
5045
|
function createTraceTreeReporter(options = {}) {
|
|
4950
|
-
|
|
4951
|
-
const write = (_a4 = options.write) != null ? _a4 : ((chunk) => void process.stderr.write(chunk));
|
|
5046
|
+
const write = options.write ?? ((chunk) => void process.stderr.write(chunk));
|
|
4952
5047
|
const turns = /* @__PURE__ */ new Map();
|
|
4953
5048
|
const render = (node, depth) => {
|
|
4954
5049
|
const indent = " ".repeat(depth);
|
|
@@ -4960,11 +5055,10 @@ function createTraceTreeReporter(options = {}) {
|
|
|
4960
5055
|
};
|
|
4961
5056
|
return {
|
|
4962
5057
|
onStart(event) {
|
|
4963
|
-
var _a5;
|
|
4964
5058
|
const e = event;
|
|
4965
5059
|
turns.set(e.callId, {
|
|
4966
5060
|
root: {
|
|
4967
|
-
label: `${
|
|
5061
|
+
label: `${e.operationId ?? "turn"}${e.modelId ? ` ${e.modelId}` : ""}`,
|
|
4968
5062
|
startMs: Date.now(),
|
|
4969
5063
|
children: []
|
|
4970
5064
|
},
|
|
@@ -4972,12 +5066,11 @@ function createTraceTreeReporter(options = {}) {
|
|
|
4972
5066
|
});
|
|
4973
5067
|
},
|
|
4974
5068
|
onStepStart(event) {
|
|
4975
|
-
var _a5;
|
|
4976
5069
|
const e = event;
|
|
4977
5070
|
const turn = turns.get(e.callId);
|
|
4978
5071
|
if (!turn) return;
|
|
4979
5072
|
const step = {
|
|
4980
|
-
label: `step ${(
|
|
5073
|
+
label: `step ${(e.stepNumber ?? turn.root.children.length) + 1}`,
|
|
4981
5074
|
startMs: Date.now(),
|
|
4982
5075
|
children: []
|
|
4983
5076
|
};
|
|
@@ -4985,10 +5078,9 @@ function createTraceTreeReporter(options = {}) {
|
|
|
4985
5078
|
turn.root.children.push(step);
|
|
4986
5079
|
},
|
|
4987
5080
|
onToolExecutionStart(event) {
|
|
4988
|
-
var _a5;
|
|
4989
5081
|
const e = event;
|
|
4990
5082
|
const turn = turns.get(e.callId);
|
|
4991
|
-
const parent =
|
|
5083
|
+
const parent = turn?.step ?? turn?.root;
|
|
4992
5084
|
if (!turn || !parent) return;
|
|
4993
5085
|
const node = {
|
|
4994
5086
|
label: `tool ${e.toolCall.toolName}`,
|
|
@@ -4999,9 +5091,8 @@ function createTraceTreeReporter(options = {}) {
|
|
|
4999
5091
|
parent.children.push(node);
|
|
5000
5092
|
},
|
|
5001
5093
|
onToolExecutionEnd(event) {
|
|
5002
|
-
var _a5;
|
|
5003
5094
|
const e = event;
|
|
5004
|
-
const node =
|
|
5095
|
+
const node = turns.get(e.callId)?.tools.get(e.toolCall.toolCallId);
|
|
5005
5096
|
if (!node) return;
|
|
5006
5097
|
node.endMs = Date.now();
|
|
5007
5098
|
if (e.toolOutput.type === "error") node.label += " [error]";
|
|
@@ -5009,7 +5100,7 @@ function createTraceTreeReporter(options = {}) {
|
|
|
5009
5100
|
onStepFinish(event) {
|
|
5010
5101
|
const e = event;
|
|
5011
5102
|
const turn = turns.get(e.callId);
|
|
5012
|
-
if (turn
|
|
5103
|
+
if (turn?.step) {
|
|
5013
5104
|
turn.step.endMs = Date.now();
|
|
5014
5105
|
turn.step = void 0;
|
|
5015
5106
|
}
|
|
@@ -5023,7 +5114,7 @@ function createTraceTreeReporter(options = {}) {
|
|
|
5023
5114
|
try {
|
|
5024
5115
|
write(`
|
|
5025
5116
|
${render(turn.root, 0)}`);
|
|
5026
|
-
} catch
|
|
5117
|
+
} catch {
|
|
5027
5118
|
}
|
|
5028
5119
|
}
|
|
5029
5120
|
};
|
|
@@ -5037,6 +5128,7 @@ export {
|
|
|
5037
5128
|
collectHarnessAgentToolApprovalContinuations,
|
|
5038
5129
|
collectHarnessAgentToolResultContinuations,
|
|
5039
5130
|
createFileReporter,
|
|
5131
|
+
createHarnessSandboxTemplate,
|
|
5040
5132
|
createTraceTreeReporter,
|
|
5041
5133
|
getHarnessErrorMessage,
|
|
5042
5134
|
prepareHarnessSandboxTemplate,
|