@ai-sdk/harness 1.0.75 → 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 +7 -0
- package/README.md +6 -6
- package/dist/agent/index.d.ts +93 -105
- package/dist/agent/index.js +126 -166
- 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/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) {
|
|
@@ -2352,22 +2325,21 @@ var HarnessAgentSession = class {
|
|
|
2352
2325
|
this.sessionState = "active";
|
|
2353
2326
|
this.turnSequence = 0;
|
|
2354
2327
|
this.activeTurnSequence = 0;
|
|
2355
|
-
var _a4, _b4, _c;
|
|
2328
|
+
var _a4, _b4, _c, _d;
|
|
2356
2329
|
this.sessionId = options.sessionId;
|
|
2357
2330
|
this.harness = options.harness;
|
|
2358
2331
|
this.underlyingSession = options.underlyingSession;
|
|
2359
2332
|
this.sandboxSession = options.sandboxSession;
|
|
2360
|
-
this.
|
|
2361
|
-
this.leasedBridgePort = options.leasedBridgePort;
|
|
2333
|
+
this.ownsSandboxLifecycle = (_a4 = options.ownsSandboxLifecycle) != null ? _a4 : true;
|
|
2362
2334
|
this.sessionWorkDir = options.sessionWorkDir;
|
|
2363
2335
|
this.toolApproval = options.toolApproval;
|
|
2364
|
-
for (const approval of (
|
|
2336
|
+
for (const approval of (_b4 = options.pendingToolApprovals) != null ? _b4 : []) {
|
|
2365
2337
|
this.pendingToolApprovals.set(approval.approvalId, approval);
|
|
2366
2338
|
}
|
|
2367
|
-
for (const pendingResult of (
|
|
2339
|
+
for (const pendingResult of (_c = options.pendingToolResults) != null ? _c : []) {
|
|
2368
2340
|
this.pendingToolResults.set(pendingResult.toolCallId, pendingResult);
|
|
2369
2341
|
}
|
|
2370
|
-
this.turnState = (
|
|
2342
|
+
this.turnState = (_d = options.turnState) != null ? _d : this.pendingToolApprovals.size > 0 ? "awaiting-approval" : this.pendingToolResults.size > 0 ? "awaiting-tool-result" : "idle";
|
|
2371
2343
|
this.isResume = options.underlyingSession.isResume;
|
|
2372
2344
|
}
|
|
2373
2345
|
/**
|
|
@@ -2547,14 +2519,12 @@ var HarnessAgentSession = class {
|
|
|
2547
2519
|
});
|
|
2548
2520
|
return validated;
|
|
2549
2521
|
} finally {
|
|
2550
|
-
this.endLocalHandle({
|
|
2551
|
-
sessionState: "detached",
|
|
2552
|
-
releasePortLease: false
|
|
2553
|
-
});
|
|
2522
|
+
this.endLocalHandle({ sessionState: "detached" });
|
|
2554
2523
|
}
|
|
2555
2524
|
}
|
|
2556
2525
|
/**
|
|
2557
|
-
* 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.
|
|
2558
2528
|
* Returns the resume state for a future
|
|
2559
2529
|
* `agent.createSession({ sessionId, resumeFrom })` call.
|
|
2560
2530
|
*/
|
|
@@ -2580,28 +2550,28 @@ var HarnessAgentSession = class {
|
|
|
2580
2550
|
});
|
|
2581
2551
|
return validated;
|
|
2582
2552
|
} finally {
|
|
2583
|
-
this.endLocalHandle({
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
});
|
|
2553
|
+
this.endLocalHandle({ sessionState: "stopped" });
|
|
2554
|
+
if (this.ownsSandboxLifecycle) {
|
|
2555
|
+
await Promise.resolve(sandboxSession.stop()).catch(() => {
|
|
2556
|
+
});
|
|
2557
|
+
}
|
|
2589
2558
|
}
|
|
2590
2559
|
}
|
|
2591
2560
|
/**
|
|
2592
|
-
* Stop the runtime and discard resumability.
|
|
2593
|
-
*
|
|
2561
|
+
* Stop the runtime and discard resumability. A harness-owned sandbox is
|
|
2562
|
+
* destroyed when supported; otherwise it is stopped.
|
|
2594
2563
|
*/
|
|
2595
2564
|
async destroy() {
|
|
2596
2565
|
var _a4, _b4;
|
|
2597
2566
|
if (this.sessionState !== "active") return;
|
|
2598
2567
|
const session = this.underlyingSession;
|
|
2599
2568
|
const sandboxSession = this.getSandboxSession();
|
|
2600
|
-
this.endLocalHandle({ sessionState: "destroyed"
|
|
2569
|
+
this.endLocalHandle({ sessionState: "destroyed" });
|
|
2601
2570
|
if (session != null) {
|
|
2602
2571
|
await Promise.resolve(session.doDestroy()).catch(() => {
|
|
2603
2572
|
});
|
|
2604
2573
|
}
|
|
2574
|
+
if (!this.ownsSandboxLifecycle) return;
|
|
2605
2575
|
await Promise.resolve(
|
|
2606
2576
|
(_b4 = (_a4 = sandboxSession.destroy) == null ? void 0 : _a4.call(sandboxSession)) != null ? _b4 : sandboxSession.stop()
|
|
2607
2577
|
).catch(() => {
|
|
@@ -2616,9 +2586,8 @@ var HarnessAgentSession = class {
|
|
|
2616
2586
|
*
|
|
2617
2587
|
* After this call the session is detached. This in-process handle no
|
|
2618
2588
|
* longer drives turns; a future slice creates a fresh session from the
|
|
2619
|
-
* returned state. The sandbox is **not** stopped
|
|
2620
|
-
*
|
|
2621
|
-
* that port.
|
|
2589
|
+
* returned state. The sandbox is **not** stopped because bridge-backed
|
|
2590
|
+
* adapters may still have a live bridge.
|
|
2622
2591
|
*/
|
|
2623
2592
|
async suspendTurn() {
|
|
2624
2593
|
if (this.sessionState !== "active" || this.underlyingSession == null) {
|
|
@@ -2635,10 +2604,7 @@ var HarnessAgentSession = class {
|
|
|
2635
2604
|
try {
|
|
2636
2605
|
return await this.suspendCurrentTurn({ session });
|
|
2637
2606
|
} finally {
|
|
2638
|
-
this.endLocalHandle({
|
|
2639
|
-
sessionState: "detached",
|
|
2640
|
-
releasePortLease: false
|
|
2641
|
-
});
|
|
2607
|
+
this.endLocalHandle({ sessionState: "detached" });
|
|
2642
2608
|
}
|
|
2643
2609
|
}
|
|
2644
2610
|
getPendingToolApprovals() {
|
|
@@ -2748,17 +2714,6 @@ var HarnessAgentSession = class {
|
|
|
2748
2714
|
this.sessionState = options.sessionState;
|
|
2749
2715
|
this.underlyingSession = void 0;
|
|
2750
2716
|
this.sandboxSession = void 0;
|
|
2751
|
-
if (options.releasePortLease) {
|
|
2752
|
-
this.releasePortLease();
|
|
2753
|
-
}
|
|
2754
|
-
}
|
|
2755
|
-
releasePortLease() {
|
|
2756
|
-
if (this.leasedBridgePort == null) return;
|
|
2757
|
-
releaseBridgePort({
|
|
2758
|
-
poolKey: this.sandboxProvider,
|
|
2759
|
-
sessionId: this.sessionId
|
|
2760
|
-
});
|
|
2761
|
-
this.leasedBridgePort = void 0;
|
|
2762
2717
|
}
|
|
2763
2718
|
requireReusableSession() {
|
|
2764
2719
|
if (this.sessionState !== "active" || this.underlyingSession == null) {
|
|
@@ -3356,13 +3311,15 @@ var HarnessAgent = class {
|
|
|
3356
3311
|
* `session.destroy()`.
|
|
3357
3312
|
*/
|
|
3358
3313
|
async createSession(options) {
|
|
3359
|
-
var _a4;
|
|
3314
|
+
var _a4, _b4;
|
|
3360
3315
|
const sessionId = (_a4 = options == null ? void 0 : options.sessionId) != null ? _a4 : generateId5();
|
|
3361
3316
|
const resumeFrom = options == null ? void 0 : options.resumeFrom;
|
|
3362
3317
|
const continueFrom = options == null ? void 0 : options.continueFrom;
|
|
3318
|
+
const providedSandboxSession = options == null ? void 0 : options.sandboxSession;
|
|
3363
3319
|
const abortSignal = options == null ? void 0 : options.abortSignal;
|
|
3364
3320
|
const harness = this.settings.harness;
|
|
3365
3321
|
const sandboxProvider = this.settings.sandbox;
|
|
3322
|
+
const ownsSandboxLifecycle = providedSandboxSession == null;
|
|
3366
3323
|
if (resumeFrom != null && continueFrom != null) {
|
|
3367
3324
|
throw new Error(
|
|
3368
3325
|
"HarnessAgent.createSession: pass either `resumeFrom` or `continueFrom`, not both."
|
|
@@ -3386,44 +3343,99 @@ var HarnessAgent = class {
|
|
|
3386
3343
|
}
|
|
3387
3344
|
const effectiveContinueFrom = validatedContinueFrom != null ? validatedContinueFrom : validatedResumeFrom == null ? void 0 : validatedResumeFrom.continueFrom;
|
|
3388
3345
|
const isResumedSession = validatedResumeFrom != null || effectiveContinueFrom != null;
|
|
3389
|
-
let
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
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,
|
|
3424
3390
|
abortSignal
|
|
3425
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
|
+
}
|
|
3426
3436
|
}
|
|
3437
|
+
}
|
|
3438
|
+
try {
|
|
3427
3439
|
await ensureSandboxDirectory({
|
|
3428
3440
|
session: sandboxSession,
|
|
3429
3441
|
workDir: sessionWorkDir,
|
|
@@ -3438,10 +3450,8 @@ var HarnessAgent = class {
|
|
|
3438
3450
|
}
|
|
3439
3451
|
} catch (err) {
|
|
3440
3452
|
await cleanupAfterStartFailure({
|
|
3441
|
-
sandboxProvider,
|
|
3442
3453
|
sandboxSession,
|
|
3443
|
-
|
|
3444
|
-
leasedBridgePort
|
|
3454
|
+
ownsSandboxLifecycle
|
|
3445
3455
|
});
|
|
3446
3456
|
throw err;
|
|
3447
3457
|
}
|
|
@@ -3466,8 +3476,7 @@ var HarnessAgent = class {
|
|
|
3466
3476
|
harness,
|
|
3467
3477
|
underlyingSession,
|
|
3468
3478
|
sandboxSession,
|
|
3469
|
-
|
|
3470
|
-
leasedBridgePort,
|
|
3479
|
+
ownsSandboxLifecycle,
|
|
3471
3480
|
sessionWorkDir,
|
|
3472
3481
|
toolApproval: this.settings.toolApproval,
|
|
3473
3482
|
pendingToolApprovals: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.pendingToolApprovals,
|
|
@@ -3476,10 +3485,8 @@ var HarnessAgent = class {
|
|
|
3476
3485
|
});
|
|
3477
3486
|
} catch (error) {
|
|
3478
3487
|
await cleanupAfterStartFailure({
|
|
3479
|
-
sandboxProvider,
|
|
3480
3488
|
sandboxSession,
|
|
3481
|
-
|
|
3482
|
-
leasedBridgePort
|
|
3489
|
+
ownsSandboxLifecycle
|
|
3483
3490
|
});
|
|
3484
3491
|
throw error;
|
|
3485
3492
|
}
|
|
@@ -3593,27 +3600,6 @@ var HarnessAgent = class {
|
|
|
3593
3600
|
stopConditions: this.stopConditions
|
|
3594
3601
|
});
|
|
3595
3602
|
}
|
|
3596
|
-
async _acquireSandbox(input) {
|
|
3597
|
-
const { sandboxProvider } = input;
|
|
3598
|
-
if (input.isResume) {
|
|
3599
|
-
if (sandboxProvider.resumeSession == null) {
|
|
3600
|
-
throw new HarnessCapabilityUnsupportedError({
|
|
3601
|
-
message: `Sandbox provider '${sandboxProvider.providerId}' does not support resume.`,
|
|
3602
|
-
harnessId: this.settings.harness.harnessId
|
|
3603
|
-
});
|
|
3604
|
-
}
|
|
3605
|
-
return sandboxProvider.resumeSession({
|
|
3606
|
-
sessionId: input.sessionId,
|
|
3607
|
-
abortSignal: input.abortSignal
|
|
3608
|
-
});
|
|
3609
|
-
}
|
|
3610
|
-
return sandboxProvider.createSession({
|
|
3611
|
-
sessionId: input.sessionId,
|
|
3612
|
-
abortSignal: input.abortSignal,
|
|
3613
|
-
identity: input.bootstrapPlan.identity,
|
|
3614
|
-
onFirstCreate: input.bootstrapPlan.onFirstCreate
|
|
3615
|
-
});
|
|
3616
|
-
}
|
|
3617
3603
|
/*
|
|
3618
3604
|
* Reduce AI SDK input to the single user message the harness should run
|
|
3619
3605
|
* for this turn. The harness session owns prior-turn state (system
|
|
@@ -3780,48 +3766,22 @@ function resolveSandboxConfig(settings) {
|
|
|
3780
3766
|
...((_a4 = settings.sandboxConfig) == null ? void 0 : _a4.onSession) == null && settings.onSandboxSession != null ? { onSession: settings.onSandboxSession } : {}
|
|
3781
3767
|
};
|
|
3782
3768
|
}
|
|
3783
|
-
function applyPortLease(input) {
|
|
3784
|
-
const pool = input.provider.bridgePorts;
|
|
3785
|
-
if (pool == null || pool.length === 0) {
|
|
3786
|
-
return { sandboxSession: input.sandboxSession, port: void 0 };
|
|
3787
|
-
}
|
|
3788
|
-
const port = acquireBridgePort({
|
|
3789
|
-
poolKey: input.provider,
|
|
3790
|
-
pool,
|
|
3791
|
-
sessionId: input.sessionId
|
|
3792
|
-
});
|
|
3793
|
-
return {
|
|
3794
|
-
sandboxSession: narrowNetworkSessionPorts(input.sandboxSession, port),
|
|
3795
|
-
port
|
|
3796
|
-
};
|
|
3797
|
-
}
|
|
3798
|
-
function narrowNetworkSessionPorts(sandboxSession, leasedPort) {
|
|
3799
|
-
return Object.create(sandboxSession, {
|
|
3800
|
-
ports: {
|
|
3801
|
-
value: [leasedPort],
|
|
3802
|
-
enumerable: true
|
|
3803
|
-
}
|
|
3804
|
-
});
|
|
3805
|
-
}
|
|
3806
3769
|
async function cleanupAfterStartFailure(input) {
|
|
3770
|
+
if (!input.ownsSandboxLifecycle) return;
|
|
3807
3771
|
await Promise.resolve(input.sandboxSession.stop()).catch(() => {
|
|
3808
3772
|
});
|
|
3809
|
-
if (input.leasedBridgePort != null) {
|
|
3810
|
-
releaseBridgePort({
|
|
3811
|
-
poolKey: input.sandboxProvider,
|
|
3812
|
-
sessionId: input.sessionId
|
|
3813
|
-
});
|
|
3814
|
-
}
|
|
3815
3773
|
}
|
|
3816
3774
|
|
|
3817
3775
|
// src/agent/prepare-harness-sandbox-template.ts
|
|
3818
3776
|
async function prepareHarnessSandboxTemplate(options) {
|
|
3819
|
-
var _a4
|
|
3777
|
+
var _a4;
|
|
3820
3778
|
const sandboxConfig = (_a4 = options.sandboxConfig) != null ? _a4 : {};
|
|
3821
3779
|
validateSandboxBootstrapSettings(sandboxConfig);
|
|
3822
|
-
const
|
|
3823
|
-
|
|
3824
|
-
|
|
3780
|
+
const { harness, sandboxProvider, abortSignal } = options;
|
|
3781
|
+
let recipe;
|
|
3782
|
+
if (harness.getBootstrap != null) {
|
|
3783
|
+
recipe = await harness.getBootstrap({ abortSignal });
|
|
3784
|
+
}
|
|
3825
3785
|
const bootstrapPlan = await createSandboxBootstrapPlan({
|
|
3826
3786
|
recipe,
|
|
3827
3787
|
settings: sandboxConfig
|
|
@@ -3829,8 +3789,8 @@ async function prepareHarnessSandboxTemplate(options) {
|
|
|
3829
3789
|
if (bootstrapPlan.identity == null || bootstrapPlan.onFirstCreate == null) {
|
|
3830
3790
|
return;
|
|
3831
3791
|
}
|
|
3832
|
-
const sandboxSession = await
|
|
3833
|
-
abortSignal
|
|
3792
|
+
const sandboxSession = await sandboxProvider.createSession({
|
|
3793
|
+
abortSignal,
|
|
3834
3794
|
identity: bootstrapPlan.identity,
|
|
3835
3795
|
onFirstCreate: bootstrapPlan.onFirstCreate
|
|
3836
3796
|
});
|
|
@@ -3841,7 +3801,7 @@ async function prepareHarnessSandboxTemplate(options) {
|
|
|
3841
3801
|
recipe: bootstrapPlan.recipe,
|
|
3842
3802
|
identity: bootstrapPlan.recipeIdentity,
|
|
3843
3803
|
defaultWorkingDirectory: sandboxSession.defaultWorkingDirectory,
|
|
3844
|
-
abortSignal
|
|
3804
|
+
abortSignal
|
|
3845
3805
|
});
|
|
3846
3806
|
}
|
|
3847
3807
|
} finally {
|