@ai-sdk/harness 1.0.74 → 1.0.76
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 +14 -0
- package/README.md +6 -6
- package/dist/agent/index.d.ts +93 -105
- package/dist/agent/index.js +153 -180
- package/dist/agent/index.js.map +1 -1
- package/dist/index.d.ts +0 -11
- package/package.json +3 -3
- package/src/agent/harness-agent-session.ts +18 -44
- package/src/agent/harness-agent-settings.ts +4 -5
- package/src/agent/harness-agent.ts +127 -149
- package/src/agent/internal/harness-stream-text-result.ts +1 -12
- package/src/agent/internal/run-prompt.ts +17 -1
- package/src/agent/internal/translate-stream-part.ts +39 -0
- package/src/agent/prepare-harness-sandbox-template.ts +15 -7
- package/src/v1/harness-v1-sandbox-provider.ts +0 -12
- package/src/agent/internal/bridge-port-registry.ts +0 -52
package/dist/agent/index.js
CHANGED
|
@@ -45,33 +45,6 @@ import {
|
|
|
45
45
|
generateId as generateId5
|
|
46
46
|
} from "@ai-sdk/provider-utils";
|
|
47
47
|
|
|
48
|
-
// src/agent/internal/bridge-port-registry.ts
|
|
49
|
-
var registries = /* @__PURE__ */ new WeakMap();
|
|
50
|
-
function acquireBridgePort(options) {
|
|
51
|
-
let entry = registries.get(options.poolKey);
|
|
52
|
-
if (entry == null) {
|
|
53
|
-
entry = { pool: options.pool, leases: /* @__PURE__ */ new Map() };
|
|
54
|
-
registries.set(options.poolKey, entry);
|
|
55
|
-
}
|
|
56
|
-
const existing = entry.leases.get(options.sessionId);
|
|
57
|
-
if (existing != null) return existing;
|
|
58
|
-
const leased = new Set(entry.leases.values());
|
|
59
|
-
for (const port of entry.pool) {
|
|
60
|
-
if (!leased.has(port)) {
|
|
61
|
-
entry.leases.set(options.sessionId, port);
|
|
62
|
-
return port;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
throw new Error(
|
|
66
|
-
`No available bridge port \u2014 pool of ${entry.pool.length} ports is fully leased.`
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
function releaseBridgePort(options) {
|
|
70
|
-
const entry = registries.get(options.poolKey);
|
|
71
|
-
if (entry == null) return;
|
|
72
|
-
entry.leases.delete(options.sessionId);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
48
|
// src/agent/internal/lifecycle-state-validation.ts
|
|
76
49
|
import { safeValidateTypes } from "@ai-sdk/provider-utils";
|
|
77
50
|
async function validateLifecycleStateData(input) {
|
|
@@ -759,21 +732,10 @@ var HarnessStreamTextResult = class {
|
|
|
759
732
|
return;
|
|
760
733
|
}
|
|
761
734
|
case "tool-call":
|
|
762
|
-
this.currentStepContent.push({
|
|
763
|
-
...part
|
|
764
|
-
});
|
|
765
|
-
return;
|
|
766
735
|
case "tool-approval-request":
|
|
767
|
-
this.currentStepContent.push({
|
|
768
|
-
...part
|
|
769
|
-
});
|
|
770
|
-
return;
|
|
771
736
|
case "tool-approval-response":
|
|
772
|
-
this.currentStepContent.push({
|
|
773
|
-
...part
|
|
774
|
-
});
|
|
775
|
-
return;
|
|
776
737
|
case "tool-result":
|
|
738
|
+
case "tool-error":
|
|
777
739
|
this.currentStepContent.push({
|
|
778
740
|
...part
|
|
779
741
|
});
|
|
@@ -870,7 +832,8 @@ function notSupportedYet(feature) {
|
|
|
870
832
|
|
|
871
833
|
// src/agent/internal/translate-stream-part.ts
|
|
872
834
|
import { generateId as generateId2 } from "@ai-sdk/provider-utils";
|
|
873
|
-
function translateStreamPart(event) {
|
|
835
|
+
function translateStreamPart(event, options = {}) {
|
|
836
|
+
var _a4, _b4;
|
|
874
837
|
switch (event.type) {
|
|
875
838
|
case "stream-start":
|
|
876
839
|
return [];
|
|
@@ -929,6 +892,20 @@ function translateStreamPart(event) {
|
|
|
929
892
|
case "tool-approval-request":
|
|
930
893
|
return [];
|
|
931
894
|
case "tool-result":
|
|
895
|
+
if (event.isError === true && ((_b4 = (_a4 = options.isProviderExecuted) == null ? void 0 : _a4.call(options, event.toolCallId)) != null ? _b4 : true)) {
|
|
896
|
+
return [
|
|
897
|
+
{
|
|
898
|
+
type: "tool-error",
|
|
899
|
+
toolCallId: event.toolCallId,
|
|
900
|
+
toolName: event.toolName,
|
|
901
|
+
input: void 0,
|
|
902
|
+
error: event.result,
|
|
903
|
+
providerExecuted: true,
|
|
904
|
+
...event.dynamic !== void 0 ? { dynamic: event.dynamic } : {},
|
|
905
|
+
...event.providerMetadata !== void 0 ? { providerMetadata: event.providerMetadata } : {}
|
|
906
|
+
}
|
|
907
|
+
];
|
|
908
|
+
}
|
|
932
909
|
return [
|
|
933
910
|
{
|
|
934
911
|
type: "tool-result",
|
|
@@ -1575,6 +1552,12 @@ function runPrompt(input) {
|
|
|
1575
1552
|
const reader = stream.getReader();
|
|
1576
1553
|
const toolCallsByToolCallId = /* @__PURE__ */ new Map();
|
|
1577
1554
|
const rawToolCallsByToolCallId = /* @__PURE__ */ new Map();
|
|
1555
|
+
const translateOptions = {
|
|
1556
|
+
isProviderExecuted: (toolCallId) => {
|
|
1557
|
+
const rawToolCall = rawToolCallsByToolCallId.get(toolCallId);
|
|
1558
|
+
return rawToolCall == null || rawToolCall.providerExecuted === true;
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1578
1561
|
const pendingApprovalsByApprovalId = new Map(
|
|
1579
1562
|
pendingToolApprovals.map((approval) => [approval.approvalId, approval])
|
|
1580
1563
|
);
|
|
@@ -1956,7 +1939,10 @@ function runPrompt(input) {
|
|
|
1956
1939
|
settleFailure(displayValue.error);
|
|
1957
1940
|
return;
|
|
1958
1941
|
}
|
|
1959
|
-
for (const part of translateStreamPart(
|
|
1942
|
+
for (const part of translateStreamPart(
|
|
1943
|
+
displayValue,
|
|
1944
|
+
translateOptions
|
|
1945
|
+
)) {
|
|
1960
1946
|
result.enqueue(part);
|
|
1961
1947
|
}
|
|
1962
1948
|
if (displayValue.type === "tool-call") {
|
|
@@ -2339,22 +2325,21 @@ var HarnessAgentSession = class {
|
|
|
2339
2325
|
this.sessionState = "active";
|
|
2340
2326
|
this.turnSequence = 0;
|
|
2341
2327
|
this.activeTurnSequence = 0;
|
|
2342
|
-
var _a4, _b4, _c;
|
|
2328
|
+
var _a4, _b4, _c, _d;
|
|
2343
2329
|
this.sessionId = options.sessionId;
|
|
2344
2330
|
this.harness = options.harness;
|
|
2345
2331
|
this.underlyingSession = options.underlyingSession;
|
|
2346
2332
|
this.sandboxSession = options.sandboxSession;
|
|
2347
|
-
this.
|
|
2348
|
-
this.leasedBridgePort = options.leasedBridgePort;
|
|
2333
|
+
this.ownsSandboxLifecycle = (_a4 = options.ownsSandboxLifecycle) != null ? _a4 : true;
|
|
2349
2334
|
this.sessionWorkDir = options.sessionWorkDir;
|
|
2350
2335
|
this.toolApproval = options.toolApproval;
|
|
2351
|
-
for (const approval of (
|
|
2336
|
+
for (const approval of (_b4 = options.pendingToolApprovals) != null ? _b4 : []) {
|
|
2352
2337
|
this.pendingToolApprovals.set(approval.approvalId, approval);
|
|
2353
2338
|
}
|
|
2354
|
-
for (const pendingResult of (
|
|
2339
|
+
for (const pendingResult of (_c = options.pendingToolResults) != null ? _c : []) {
|
|
2355
2340
|
this.pendingToolResults.set(pendingResult.toolCallId, pendingResult);
|
|
2356
2341
|
}
|
|
2357
|
-
this.turnState = (
|
|
2342
|
+
this.turnState = (_d = options.turnState) != null ? _d : this.pendingToolApprovals.size > 0 ? "awaiting-approval" : this.pendingToolResults.size > 0 ? "awaiting-tool-result" : "idle";
|
|
2358
2343
|
this.isResume = options.underlyingSession.isResume;
|
|
2359
2344
|
}
|
|
2360
2345
|
/**
|
|
@@ -2534,14 +2519,12 @@ var HarnessAgentSession = class {
|
|
|
2534
2519
|
});
|
|
2535
2520
|
return validated;
|
|
2536
2521
|
} finally {
|
|
2537
|
-
this.endLocalHandle({
|
|
2538
|
-
sessionState: "detached",
|
|
2539
|
-
releasePortLease: false
|
|
2540
|
-
});
|
|
2522
|
+
this.endLocalHandle({ sessionState: "detached" });
|
|
2541
2523
|
}
|
|
2542
2524
|
}
|
|
2543
2525
|
/**
|
|
2544
|
-
* Persist enough state to resume later, then stop the runtime and
|
|
2526
|
+
* Persist enough state to resume later, then stop the runtime and any
|
|
2527
|
+
* harness-owned sandbox.
|
|
2545
2528
|
* Returns the resume state for a future
|
|
2546
2529
|
* `agent.createSession({ sessionId, resumeFrom })` call.
|
|
2547
2530
|
*/
|
|
@@ -2567,28 +2550,28 @@ var HarnessAgentSession = class {
|
|
|
2567
2550
|
});
|
|
2568
2551
|
return validated;
|
|
2569
2552
|
} finally {
|
|
2570
|
-
this.endLocalHandle({
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
});
|
|
2553
|
+
this.endLocalHandle({ sessionState: "stopped" });
|
|
2554
|
+
if (this.ownsSandboxLifecycle) {
|
|
2555
|
+
await Promise.resolve(sandboxSession.stop()).catch(() => {
|
|
2556
|
+
});
|
|
2557
|
+
}
|
|
2576
2558
|
}
|
|
2577
2559
|
}
|
|
2578
2560
|
/**
|
|
2579
|
-
* Stop the runtime and discard resumability.
|
|
2580
|
-
*
|
|
2561
|
+
* Stop the runtime and discard resumability. A harness-owned sandbox is
|
|
2562
|
+
* destroyed when supported; otherwise it is stopped.
|
|
2581
2563
|
*/
|
|
2582
2564
|
async destroy() {
|
|
2583
2565
|
var _a4, _b4;
|
|
2584
2566
|
if (this.sessionState !== "active") return;
|
|
2585
2567
|
const session = this.underlyingSession;
|
|
2586
2568
|
const sandboxSession = this.getSandboxSession();
|
|
2587
|
-
this.endLocalHandle({ sessionState: "destroyed"
|
|
2569
|
+
this.endLocalHandle({ sessionState: "destroyed" });
|
|
2588
2570
|
if (session != null) {
|
|
2589
2571
|
await Promise.resolve(session.doDestroy()).catch(() => {
|
|
2590
2572
|
});
|
|
2591
2573
|
}
|
|
2574
|
+
if (!this.ownsSandboxLifecycle) return;
|
|
2592
2575
|
await Promise.resolve(
|
|
2593
2576
|
(_b4 = (_a4 = sandboxSession.destroy) == null ? void 0 : _a4.call(sandboxSession)) != null ? _b4 : sandboxSession.stop()
|
|
2594
2577
|
).catch(() => {
|
|
@@ -2603,9 +2586,8 @@ var HarnessAgentSession = class {
|
|
|
2603
2586
|
*
|
|
2604
2587
|
* After this call the session is detached. This in-process handle no
|
|
2605
2588
|
* longer drives turns; a future slice creates a fresh session from the
|
|
2606
|
-
* returned state. The sandbox is **not** stopped
|
|
2607
|
-
*
|
|
2608
|
-
* that port.
|
|
2589
|
+
* returned state. The sandbox is **not** stopped because bridge-backed
|
|
2590
|
+
* adapters may still have a live bridge.
|
|
2609
2591
|
*/
|
|
2610
2592
|
async suspendTurn() {
|
|
2611
2593
|
if (this.sessionState !== "active" || this.underlyingSession == null) {
|
|
@@ -2622,10 +2604,7 @@ var HarnessAgentSession = class {
|
|
|
2622
2604
|
try {
|
|
2623
2605
|
return await this.suspendCurrentTurn({ session });
|
|
2624
2606
|
} finally {
|
|
2625
|
-
this.endLocalHandle({
|
|
2626
|
-
sessionState: "detached",
|
|
2627
|
-
releasePortLease: false
|
|
2628
|
-
});
|
|
2607
|
+
this.endLocalHandle({ sessionState: "detached" });
|
|
2629
2608
|
}
|
|
2630
2609
|
}
|
|
2631
2610
|
getPendingToolApprovals() {
|
|
@@ -2735,17 +2714,6 @@ var HarnessAgentSession = class {
|
|
|
2735
2714
|
this.sessionState = options.sessionState;
|
|
2736
2715
|
this.underlyingSession = void 0;
|
|
2737
2716
|
this.sandboxSession = void 0;
|
|
2738
|
-
if (options.releasePortLease) {
|
|
2739
|
-
this.releasePortLease();
|
|
2740
|
-
}
|
|
2741
|
-
}
|
|
2742
|
-
releasePortLease() {
|
|
2743
|
-
if (this.leasedBridgePort == null) return;
|
|
2744
|
-
releaseBridgePort({
|
|
2745
|
-
poolKey: this.sandboxProvider,
|
|
2746
|
-
sessionId: this.sessionId
|
|
2747
|
-
});
|
|
2748
|
-
this.leasedBridgePort = void 0;
|
|
2749
2717
|
}
|
|
2750
2718
|
requireReusableSession() {
|
|
2751
2719
|
if (this.sessionState !== "active" || this.underlyingSession == null) {
|
|
@@ -3343,13 +3311,15 @@ var HarnessAgent = class {
|
|
|
3343
3311
|
* `session.destroy()`.
|
|
3344
3312
|
*/
|
|
3345
3313
|
async createSession(options) {
|
|
3346
|
-
var _a4;
|
|
3314
|
+
var _a4, _b4;
|
|
3347
3315
|
const sessionId = (_a4 = options == null ? void 0 : options.sessionId) != null ? _a4 : generateId5();
|
|
3348
3316
|
const resumeFrom = options == null ? void 0 : options.resumeFrom;
|
|
3349
3317
|
const continueFrom = options == null ? void 0 : options.continueFrom;
|
|
3318
|
+
const providedSandboxSession = options == null ? void 0 : options.sandboxSession;
|
|
3350
3319
|
const abortSignal = options == null ? void 0 : options.abortSignal;
|
|
3351
3320
|
const harness = this.settings.harness;
|
|
3352
3321
|
const sandboxProvider = this.settings.sandbox;
|
|
3322
|
+
const ownsSandboxLifecycle = providedSandboxSession == null;
|
|
3353
3323
|
if (resumeFrom != null && continueFrom != null) {
|
|
3354
3324
|
throw new Error(
|
|
3355
3325
|
"HarnessAgent.createSession: pass either `resumeFrom` or `continueFrom`, not both."
|
|
@@ -3373,44 +3343,99 @@ var HarnessAgent = class {
|
|
|
3373
3343
|
}
|
|
3374
3344
|
const effectiveContinueFrom = validatedContinueFrom != null ? validatedContinueFrom : validatedResumeFrom == null ? void 0 : validatedResumeFrom.continueFrom;
|
|
3375
3345
|
const isResumedSession = validatedResumeFrom != null || effectiveContinueFrom != null;
|
|
3376
|
-
let
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3346
|
+
let sandboxSession;
|
|
3347
|
+
let sessionWorkDir;
|
|
3348
|
+
if (providedSandboxSession != null) {
|
|
3349
|
+
sandboxSession = providedSandboxSession;
|
|
3350
|
+
sessionWorkDir = resolveSessionWorkDir({
|
|
3351
|
+
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3352
|
+
harnessId: harness.harnessId,
|
|
3353
|
+
sessionId,
|
|
3354
|
+
workDir: this.sandboxConfig.workDir
|
|
3355
|
+
});
|
|
3356
|
+
const recipe = await ((_b4 = harness.getBootstrap) == null ? void 0 : _b4.call(harness, { abortSignal }));
|
|
3357
|
+
if (recipe != null) {
|
|
3358
|
+
const recipeIdentity = await hashHarnessBootstrap(recipe);
|
|
3359
|
+
try {
|
|
3360
|
+
await applyBootstrapRecipe({
|
|
3361
|
+
session: sandboxSession.restricted(),
|
|
3362
|
+
recipe,
|
|
3363
|
+
identity: recipeIdentity,
|
|
3364
|
+
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3365
|
+
abortSignal
|
|
3366
|
+
});
|
|
3367
|
+
} catch (err) {
|
|
3368
|
+
await cleanupAfterStartFailure({
|
|
3369
|
+
sandboxSession,
|
|
3370
|
+
ownsSandboxLifecycle
|
|
3371
|
+
});
|
|
3372
|
+
throw err;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
} else {
|
|
3376
|
+
if (sandboxProvider == null) {
|
|
3377
|
+
throw new Error(
|
|
3378
|
+
"HarnessAgent.createSession: configure `sandbox` on HarnessAgent or pass `sandboxSession` to createSession()."
|
|
3379
|
+
);
|
|
3380
|
+
}
|
|
3381
|
+
if (isResumedSession) {
|
|
3382
|
+
if (sandboxProvider.resumeSession == null) {
|
|
3383
|
+
throw new HarnessCapabilityUnsupportedError({
|
|
3384
|
+
message: `Sandbox provider '${sandboxProvider.providerId}' does not support resume.`,
|
|
3385
|
+
harnessId: harness.harnessId
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
sandboxSession = await sandboxProvider.resumeSession({
|
|
3389
|
+
sessionId,
|
|
3411
3390
|
abortSignal
|
|
3412
3391
|
});
|
|
3392
|
+
sessionWorkDir = resolveSessionWorkDir({
|
|
3393
|
+
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3394
|
+
harnessId: harness.harnessId,
|
|
3395
|
+
sessionId,
|
|
3396
|
+
workDir: this.sandboxConfig.workDir
|
|
3397
|
+
});
|
|
3398
|
+
} else {
|
|
3399
|
+
let recipe;
|
|
3400
|
+
if (harness.getBootstrap != null) {
|
|
3401
|
+
recipe = await harness.getBootstrap({ abortSignal });
|
|
3402
|
+
}
|
|
3403
|
+
const sandboxBootstrapPlan = await createSandboxBootstrapPlan({
|
|
3404
|
+
recipe,
|
|
3405
|
+
settings: this.sandboxConfig
|
|
3406
|
+
});
|
|
3407
|
+
sandboxSession = await sandboxProvider.createSession({
|
|
3408
|
+
sessionId,
|
|
3409
|
+
abortSignal,
|
|
3410
|
+
identity: sandboxBootstrapPlan.identity,
|
|
3411
|
+
onFirstCreate: sandboxBootstrapPlan.onFirstCreate
|
|
3412
|
+
});
|
|
3413
|
+
sessionWorkDir = resolveSessionWorkDir({
|
|
3414
|
+
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3415
|
+
harnessId: harness.harnessId,
|
|
3416
|
+
sessionId,
|
|
3417
|
+
workDir: sandboxBootstrapPlan.workDir
|
|
3418
|
+
});
|
|
3419
|
+
if (sandboxBootstrapPlan.recipe != null && sandboxBootstrapPlan.recipeIdentity != null) {
|
|
3420
|
+
try {
|
|
3421
|
+
await applyBootstrapRecipe({
|
|
3422
|
+
session: sandboxSession.restricted(),
|
|
3423
|
+
recipe: sandboxBootstrapPlan.recipe,
|
|
3424
|
+
identity: sandboxBootstrapPlan.recipeIdentity,
|
|
3425
|
+
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3426
|
+
abortSignal
|
|
3427
|
+
});
|
|
3428
|
+
} catch (err) {
|
|
3429
|
+
await cleanupAfterStartFailure({
|
|
3430
|
+
sandboxSession,
|
|
3431
|
+
ownsSandboxLifecycle
|
|
3432
|
+
});
|
|
3433
|
+
throw err;
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3413
3436
|
}
|
|
3437
|
+
}
|
|
3438
|
+
try {
|
|
3414
3439
|
await ensureSandboxDirectory({
|
|
3415
3440
|
session: sandboxSession,
|
|
3416
3441
|
workDir: sessionWorkDir,
|
|
@@ -3425,10 +3450,8 @@ var HarnessAgent = class {
|
|
|
3425
3450
|
}
|
|
3426
3451
|
} catch (err) {
|
|
3427
3452
|
await cleanupAfterStartFailure({
|
|
3428
|
-
sandboxProvider,
|
|
3429
3453
|
sandboxSession,
|
|
3430
|
-
|
|
3431
|
-
leasedBridgePort
|
|
3454
|
+
ownsSandboxLifecycle
|
|
3432
3455
|
});
|
|
3433
3456
|
throw err;
|
|
3434
3457
|
}
|
|
@@ -3453,8 +3476,7 @@ var HarnessAgent = class {
|
|
|
3453
3476
|
harness,
|
|
3454
3477
|
underlyingSession,
|
|
3455
3478
|
sandboxSession,
|
|
3456
|
-
|
|
3457
|
-
leasedBridgePort,
|
|
3479
|
+
ownsSandboxLifecycle,
|
|
3458
3480
|
sessionWorkDir,
|
|
3459
3481
|
toolApproval: this.settings.toolApproval,
|
|
3460
3482
|
pendingToolApprovals: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.pendingToolApprovals,
|
|
@@ -3463,10 +3485,8 @@ var HarnessAgent = class {
|
|
|
3463
3485
|
});
|
|
3464
3486
|
} catch (error) {
|
|
3465
3487
|
await cleanupAfterStartFailure({
|
|
3466
|
-
sandboxProvider,
|
|
3467
3488
|
sandboxSession,
|
|
3468
|
-
|
|
3469
|
-
leasedBridgePort
|
|
3489
|
+
ownsSandboxLifecycle
|
|
3470
3490
|
});
|
|
3471
3491
|
throw error;
|
|
3472
3492
|
}
|
|
@@ -3580,27 +3600,6 @@ var HarnessAgent = class {
|
|
|
3580
3600
|
stopConditions: this.stopConditions
|
|
3581
3601
|
});
|
|
3582
3602
|
}
|
|
3583
|
-
async _acquireSandbox(input) {
|
|
3584
|
-
const { sandboxProvider } = input;
|
|
3585
|
-
if (input.isResume) {
|
|
3586
|
-
if (sandboxProvider.resumeSession == null) {
|
|
3587
|
-
throw new HarnessCapabilityUnsupportedError({
|
|
3588
|
-
message: `Sandbox provider '${sandboxProvider.providerId}' does not support resume.`,
|
|
3589
|
-
harnessId: this.settings.harness.harnessId
|
|
3590
|
-
});
|
|
3591
|
-
}
|
|
3592
|
-
return sandboxProvider.resumeSession({
|
|
3593
|
-
sessionId: input.sessionId,
|
|
3594
|
-
abortSignal: input.abortSignal
|
|
3595
|
-
});
|
|
3596
|
-
}
|
|
3597
|
-
return sandboxProvider.createSession({
|
|
3598
|
-
sessionId: input.sessionId,
|
|
3599
|
-
abortSignal: input.abortSignal,
|
|
3600
|
-
identity: input.bootstrapPlan.identity,
|
|
3601
|
-
onFirstCreate: input.bootstrapPlan.onFirstCreate
|
|
3602
|
-
});
|
|
3603
|
-
}
|
|
3604
3603
|
/*
|
|
3605
3604
|
* Reduce AI SDK input to the single user message the harness should run
|
|
3606
3605
|
* for this turn. The harness session owns prior-turn state (system
|
|
@@ -3767,48 +3766,22 @@ function resolveSandboxConfig(settings) {
|
|
|
3767
3766
|
...((_a4 = settings.sandboxConfig) == null ? void 0 : _a4.onSession) == null && settings.onSandboxSession != null ? { onSession: settings.onSandboxSession } : {}
|
|
3768
3767
|
};
|
|
3769
3768
|
}
|
|
3770
|
-
function applyPortLease(input) {
|
|
3771
|
-
const pool = input.provider.bridgePorts;
|
|
3772
|
-
if (pool == null || pool.length === 0) {
|
|
3773
|
-
return { sandboxSession: input.sandboxSession, port: void 0 };
|
|
3774
|
-
}
|
|
3775
|
-
const port = acquireBridgePort({
|
|
3776
|
-
poolKey: input.provider,
|
|
3777
|
-
pool,
|
|
3778
|
-
sessionId: input.sessionId
|
|
3779
|
-
});
|
|
3780
|
-
return {
|
|
3781
|
-
sandboxSession: narrowNetworkSessionPorts(input.sandboxSession, port),
|
|
3782
|
-
port
|
|
3783
|
-
};
|
|
3784
|
-
}
|
|
3785
|
-
function narrowNetworkSessionPorts(sandboxSession, leasedPort) {
|
|
3786
|
-
return Object.create(sandboxSession, {
|
|
3787
|
-
ports: {
|
|
3788
|
-
value: [leasedPort],
|
|
3789
|
-
enumerable: true
|
|
3790
|
-
}
|
|
3791
|
-
});
|
|
3792
|
-
}
|
|
3793
3769
|
async function cleanupAfterStartFailure(input) {
|
|
3770
|
+
if (!input.ownsSandboxLifecycle) return;
|
|
3794
3771
|
await Promise.resolve(input.sandboxSession.stop()).catch(() => {
|
|
3795
3772
|
});
|
|
3796
|
-
if (input.leasedBridgePort != null) {
|
|
3797
|
-
releaseBridgePort({
|
|
3798
|
-
poolKey: input.sandboxProvider,
|
|
3799
|
-
sessionId: input.sessionId
|
|
3800
|
-
});
|
|
3801
|
-
}
|
|
3802
3773
|
}
|
|
3803
3774
|
|
|
3804
3775
|
// src/agent/prepare-harness-sandbox-template.ts
|
|
3805
3776
|
async function prepareHarnessSandboxTemplate(options) {
|
|
3806
|
-
var _a4
|
|
3777
|
+
var _a4;
|
|
3807
3778
|
const sandboxConfig = (_a4 = options.sandboxConfig) != null ? _a4 : {};
|
|
3808
3779
|
validateSandboxBootstrapSettings(sandboxConfig);
|
|
3809
|
-
const
|
|
3810
|
-
|
|
3811
|
-
|
|
3780
|
+
const { harness, sandboxProvider, abortSignal } = options;
|
|
3781
|
+
let recipe;
|
|
3782
|
+
if (harness.getBootstrap != null) {
|
|
3783
|
+
recipe = await harness.getBootstrap({ abortSignal });
|
|
3784
|
+
}
|
|
3812
3785
|
const bootstrapPlan = await createSandboxBootstrapPlan({
|
|
3813
3786
|
recipe,
|
|
3814
3787
|
settings: sandboxConfig
|
|
@@ -3816,8 +3789,8 @@ async function prepareHarnessSandboxTemplate(options) {
|
|
|
3816
3789
|
if (bootstrapPlan.identity == null || bootstrapPlan.onFirstCreate == null) {
|
|
3817
3790
|
return;
|
|
3818
3791
|
}
|
|
3819
|
-
const sandboxSession = await
|
|
3820
|
-
abortSignal
|
|
3792
|
+
const sandboxSession = await sandboxProvider.createSession({
|
|
3793
|
+
abortSignal,
|
|
3821
3794
|
identity: bootstrapPlan.identity,
|
|
3822
3795
|
onFirstCreate: bootstrapPlan.onFirstCreate
|
|
3823
3796
|
});
|
|
@@ -3828,7 +3801,7 @@ async function prepareHarnessSandboxTemplate(options) {
|
|
|
3828
3801
|
recipe: bootstrapPlan.recipe,
|
|
3829
3802
|
identity: bootstrapPlan.recipeIdentity,
|
|
3830
3803
|
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3831
|
-
abortSignal
|
|
3804
|
+
abortSignal
|
|
3832
3805
|
});
|
|
3833
3806
|
}
|
|
3834
3807
|
} finally {
|