@ai-sdk/harness 1.0.0-canary.3 → 1.0.0-canary.4
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 +6 -0
- package/dist/agent/index.d.ts +70 -50
- package/dist/agent/index.js +46 -20
- package/dist/agent/index.js.map +1 -1
- package/dist/index.d.ts +53 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/agent/harness-agent-session.ts +26 -20
- package/src/agent/harness-agent.ts +40 -12
- package/src/agent/internal/lifecycle-state-validation.ts +61 -0
- package/src/v1/harness-v1-bridge-protocol.ts +1 -1
- package/src/v1/{harness-v1-resume-state.ts → harness-v1-lifecycle-state.ts} +25 -12
- package/src/v1/harness-v1-network-sandbox-session.ts +1 -1
- package/src/v1/harness-v1-session.ts +27 -17
- package/src/v1/harness-v1.ts +8 -8
- package/src/v1/index.ts +4 -2
- package/src/agent/internal/resume-state-validation.ts +0 -51
package/CHANGELOG.md
CHANGED
package/dist/agent/index.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ interface HarnessV1NetworkSandboxSession extends Experimental_SandboxSession {
|
|
|
62
62
|
/**
|
|
63
63
|
* Stable identifier for the underlying sandbox resource. Used by the
|
|
64
64
|
* harness session manager as the durable lookup key for cross-process
|
|
65
|
-
* resume — the framework persists this on
|
|
65
|
+
* resume — the framework persists this on lifecycle state so a future
|
|
66
66
|
* process can call `HarnessV1SandboxProvider.resume?({ sessionId })` and
|
|
67
67
|
* reach the same resource. Providers populate it from their native
|
|
68
68
|
* identifier (Vercel: the sandbox name; just-bash: a UUID minted at
|
|
@@ -298,19 +298,10 @@ type HarnessV1PendingToolApproval = {
|
|
|
298
298
|
readonly providerExecuted?: boolean;
|
|
299
299
|
readonly nativeName?: string;
|
|
300
300
|
};
|
|
301
|
-
|
|
302
|
-
* Opaque payload returned by resumable session lifecycle methods and accepted
|
|
303
|
-
* by a future `HarnessV1.doStart({ resumeFrom })` to resume the same
|
|
304
|
-
* underlying session.
|
|
305
|
-
*
|
|
306
|
-
* The contents are entirely adapter-defined. Consumers (including
|
|
307
|
-
* `HarnessAgent`) treat the value as opaque; adapters describe and validate
|
|
308
|
-
* their own schemas via `HarnessV1.resumeStateSchema`.
|
|
309
|
-
*/
|
|
310
|
-
type HarnessV1ResumeState = {
|
|
301
|
+
type HarnessV1LifecycleStateBase = {
|
|
311
302
|
/**
|
|
312
303
|
* Identifier of the harness that produced this state. Used by adapters to
|
|
313
|
-
* refuse mismatched
|
|
304
|
+
* refuse mismatched payloads.
|
|
314
305
|
*/
|
|
315
306
|
readonly harnessId: string;
|
|
316
307
|
/**
|
|
@@ -324,11 +315,27 @@ type HarnessV1ResumeState = {
|
|
|
324
315
|
readonly data: JSONValue;
|
|
325
316
|
/**
|
|
326
317
|
* Framework-owned pending approval records. These are intentionally outside
|
|
327
|
-
* adapter-defined `data` so callers can persist the entire
|
|
318
|
+
* adapter-defined `data` so callers can persist the entire lifecycle payload
|
|
328
319
|
* without the harness framework owning storage.
|
|
329
320
|
*/
|
|
330
321
|
readonly pendingToolApprovals?: readonly HarnessV1PendingToolApproval[];
|
|
331
322
|
};
|
|
323
|
+
/**
|
|
324
|
+
* Opaque payload returned by between-turn session lifecycle methods and
|
|
325
|
+
* accepted by a future `HarnessV1.doStart({ resumeFrom })` to resume the same
|
|
326
|
+
* underlying session before starting a new turn.
|
|
327
|
+
*/
|
|
328
|
+
type HarnessV1ResumeSessionState = HarnessV1LifecycleStateBase & {
|
|
329
|
+
readonly type: 'resume-session';
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Opaque payload returned by `doSuspendTurn` and accepted by a future
|
|
333
|
+
* `HarnessV1.doStart({ continueFrom })` to reconnect to the same session before
|
|
334
|
+
* continuing the interrupted turn.
|
|
335
|
+
*/
|
|
336
|
+
type HarnessV1ContinueTurnState = HarnessV1LifecycleStateBase & {
|
|
337
|
+
readonly type: 'continue-turn';
|
|
338
|
+
};
|
|
332
339
|
|
|
333
340
|
/**
|
|
334
341
|
* A self-contained instruction bundle the underlying runtime can load into
|
|
@@ -515,11 +522,17 @@ type HarnessV1StartOptions = {
|
|
|
515
522
|
*/
|
|
516
523
|
readonly skills?: ReadonlyArray<HarnessV1Skill>;
|
|
517
524
|
/**
|
|
518
|
-
* Optional resume payload returned by a prior session lifecycle
|
|
519
|
-
* provided, the adapter should resume the existing session
|
|
520
|
-
* a
|
|
525
|
+
* Optional resume payload returned by a prior between-turn session lifecycle
|
|
526
|
+
* method. When provided, the adapter should resume the existing session before
|
|
527
|
+
* accepting a new prompt.
|
|
528
|
+
*/
|
|
529
|
+
readonly resumeFrom?: HarnessV1ResumeSessionState;
|
|
530
|
+
/**
|
|
531
|
+
* Optional continuation payload returned by `doSuspendTurn`. When provided,
|
|
532
|
+
* the adapter should resume the existing session in a shape ready for
|
|
533
|
+
* `doContinueTurn` rather than for a fresh prompt.
|
|
521
534
|
*/
|
|
522
|
-
readonly
|
|
535
|
+
readonly continueFrom?: HarnessV1ContinueTurnState;
|
|
523
536
|
/**
|
|
524
537
|
* Approval policy for built-in adapter-native tool use. Custom host-executed
|
|
525
538
|
* tools are approved by the framework before results are submitted back to
|
|
@@ -631,8 +644,8 @@ type HarnessV1Session = {
|
|
|
631
644
|
*/
|
|
632
645
|
readonly sessionId: string;
|
|
633
646
|
/**
|
|
634
|
-
* Whether this session was created from
|
|
635
|
-
* report `false`; resumed sessions report `true`.
|
|
647
|
+
* Whether this session was created from `resumeFrom` or `continueFrom`. Fresh
|
|
648
|
+
* sessions report `false`; resumed sessions report `true`.
|
|
636
649
|
*/
|
|
637
650
|
readonly isResume: boolean;
|
|
638
651
|
/**
|
|
@@ -664,7 +677,7 @@ type HarnessV1Session = {
|
|
|
664
677
|
* Continue the in-flight turn **without a new user prompt**, returning the
|
|
665
678
|
* same control surface as `doPromptTurn`. Used to keep consuming a turn that
|
|
666
679
|
* was interrupted at a process boundary (the workflow slice loop), after the
|
|
667
|
-
* session itself has been resumed via `doStart({
|
|
680
|
+
* session itself has been resumed via `doStart({ continueFrom })`:
|
|
668
681
|
*
|
|
669
682
|
* - When the runtime's turn is still live and reachable (bridge `attach` /
|
|
670
683
|
* `replay`), the adapter subscribes to its events and resolves `done` on
|
|
@@ -680,7 +693,7 @@ type HarnessV1Session = {
|
|
|
680
693
|
doContinueTurn(options: HarnessV1ContinueTurnOptions): PromiseLike<HarnessV1PromptControl>;
|
|
681
694
|
/**
|
|
682
695
|
* Gracefully freeze the active turn **at a precise cursor while keeping the
|
|
683
|
-
* runtime alive**, returning the
|
|
696
|
+
* runtime alive**, returning the continuation payload.
|
|
684
697
|
*
|
|
685
698
|
* This is the slice-boundary primitive. The adapter stops host-side
|
|
686
699
|
* consumption of the in-flight turn without telling the runtime to stop:
|
|
@@ -697,24 +710,24 @@ type HarnessV1Session = {
|
|
|
697
710
|
* this is for an active turn at a slice boundary rather than a between-turn
|
|
698
711
|
* session handoff. Required on every adapter.
|
|
699
712
|
*/
|
|
700
|
-
doSuspendTurn(): PromiseLike<
|
|
713
|
+
doSuspendTurn(): PromiseLike<HarnessV1ContinueTurnState>;
|
|
701
714
|
/**
|
|
702
715
|
* Detach from the underlying runtime without tearing it down, returning a
|
|
703
|
-
* payload the host can later pass to
|
|
704
|
-
*
|
|
705
|
-
* instance may be called.
|
|
716
|
+
* payload the host can later pass to
|
|
717
|
+
* `HarnessV1.doStart({ resumeFrom })` to reconnect before a new turn. After
|
|
718
|
+
* `doDetach`, no further methods on this session instance may be called.
|
|
706
719
|
*
|
|
707
720
|
* Required. Adapters that cannot keep a live runtime parked still return the
|
|
708
|
-
* best resume state they can while leaving the sandbox running.
|
|
721
|
+
* best resume session state they can while leaving the sandbox running.
|
|
709
722
|
*/
|
|
710
|
-
doDetach(): PromiseLike<
|
|
723
|
+
doDetach(): PromiseLike<HarnessV1ResumeSessionState>;
|
|
711
724
|
/**
|
|
712
725
|
* Persist enough state to resume later, then stop the underlying runtime.
|
|
713
726
|
* After `doStop`, no further methods on this session instance may be called.
|
|
714
727
|
*/
|
|
715
|
-
doStop(): PromiseLike<
|
|
728
|
+
doStop(): PromiseLike<HarnessV1ResumeSessionState>;
|
|
716
729
|
/**
|
|
717
|
-
* Stop the underlying runtime without returning
|
|
730
|
+
* Stop the underlying runtime without returning lifecycle state. After
|
|
718
731
|
* `doDestroy`, no further methods on this session instance may be called.
|
|
719
732
|
*/
|
|
720
733
|
doDestroy(): PromiseLike<void>;
|
|
@@ -763,12 +776,12 @@ type HarnessV1<TBuiltinTools extends ToolSet = ToolSet> = {
|
|
|
763
776
|
*/
|
|
764
777
|
readonly supportsBuiltinToolApprovals?: boolean;
|
|
765
778
|
/**
|
|
766
|
-
* Optional schema for
|
|
767
|
-
* When present, the adapter promises that exported state
|
|
768
|
-
* schema can be re-imported in a future
|
|
769
|
-
*
|
|
779
|
+
* Optional schema for the adapter-defined `data` payload returned by session
|
|
780
|
+
* lifecycle methods. When present, the adapter promises that exported state
|
|
781
|
+
* validated by this schema can be re-imported in a future
|
|
782
|
+
* `doStart({ resumeFrom })` or `doStart({ continueFrom })` call.
|
|
770
783
|
*/
|
|
771
|
-
readonly
|
|
784
|
+
readonly lifecycleStateSchema?: FlexibleSchema<unknown>;
|
|
772
785
|
/**
|
|
773
786
|
* Optional bootstrap recipe. When defined, the harness session manager
|
|
774
787
|
* computes a stable identity from the recipe, passes it (along with a
|
|
@@ -784,9 +797,9 @@ type HarnessV1<TBuiltinTools extends ToolSet = ToolSet> = {
|
|
|
784
797
|
abortSignal?: AbortSignal;
|
|
785
798
|
}) => PromiseLike<HarnessV1Bootstrap>;
|
|
786
799
|
/**
|
|
787
|
-
* Start a fresh session
|
|
788
|
-
*
|
|
789
|
-
* `doDestroy`.
|
|
800
|
+
* Start a fresh session, resume a parked session via `resumeFrom`, or resume
|
|
801
|
+
* an interrupted turn via `continueFrom`. The host then issues prompts against
|
|
802
|
+
* the returned session, ending with `doDetach`, `doStop`, or `doDestroy`.
|
|
790
803
|
*/
|
|
791
804
|
doStart(options: HarnessV1StartOptions): PromiseLike<HarnessV1Session>;
|
|
792
805
|
};
|
|
@@ -1261,8 +1274,8 @@ declare class HarnessAgentSession {
|
|
|
1261
1274
|
private readonly pendingToolApprovals;
|
|
1262
1275
|
private stopped;
|
|
1263
1276
|
/**
|
|
1264
|
-
* Whether this session was created from
|
|
1265
|
-
* construction so it survives lifecycle cleanup.
|
|
1277
|
+
* Whether this session was created from `resumeFrom` or `continueFrom`.
|
|
1278
|
+
* Captured at construction so it survives lifecycle cleanup.
|
|
1266
1279
|
*/
|
|
1267
1280
|
readonly isResume: boolean;
|
|
1268
1281
|
constructor(options: {
|
|
@@ -1311,13 +1324,13 @@ declare class HarnessAgentSession {
|
|
|
1311
1324
|
* The runtime and sandbox keep running; this local session handle becomes
|
|
1312
1325
|
* unusable.
|
|
1313
1326
|
*/
|
|
1314
|
-
detach(): Promise<
|
|
1327
|
+
detach(): Promise<HarnessV1ResumeSessionState>;
|
|
1315
1328
|
/**
|
|
1316
1329
|
* Persist enough state to resume later, then stop the runtime and sandbox.
|
|
1317
1330
|
* Returns the resume state for a future
|
|
1318
1331
|
* `agent.createSession({ sessionId, resumeFrom })` call.
|
|
1319
1332
|
*/
|
|
1320
|
-
stop(): Promise<
|
|
1333
|
+
stop(): Promise<HarnessV1ResumeSessionState>;
|
|
1321
1334
|
/**
|
|
1322
1335
|
* Stop the runtime and discard resumability. The sandbox is destroyed when
|
|
1323
1336
|
* the provider supports destruction; otherwise it is stopped.
|
|
@@ -1325,8 +1338,8 @@ declare class HarnessAgentSession {
|
|
|
1325
1338
|
destroy(): Promise<void>;
|
|
1326
1339
|
/**
|
|
1327
1340
|
* Gracefully freeze the active turn at the slice boundary and return the
|
|
1328
|
-
*
|
|
1329
|
-
* can
|
|
1341
|
+
* continuation payload, **leaving the sandbox/runtime running** so the next
|
|
1342
|
+
* process can continue. Resolves once the in-flight `stream()`/`continueTurn()`
|
|
1330
1343
|
* has cleanly wound down at a precise cursor (see
|
|
1331
1344
|
* {@link HarnessV1Session.doSuspendTurn}).
|
|
1332
1345
|
*
|
|
@@ -1336,7 +1349,7 @@ declare class HarnessAgentSession {
|
|
|
1336
1349
|
* released, because bridge-backed adapters may still have a live bridge on
|
|
1337
1350
|
* that port.
|
|
1338
1351
|
*/
|
|
1339
|
-
suspendTurn(): Promise<
|
|
1352
|
+
suspendTurn(): Promise<HarnessV1ContinueTurnState>;
|
|
1340
1353
|
private getPendingToolApprovals;
|
|
1341
1354
|
private withPendingToolApprovals;
|
|
1342
1355
|
private endLocalHandle;
|
|
@@ -1381,7 +1394,9 @@ interface HarnessAgentCallExtensions {
|
|
|
1381
1394
|
* - **Cross-process resume.** `createSession({ sessionId, resumeFrom })`
|
|
1382
1395
|
* resumes from state previously returned by `session.detach()` or
|
|
1383
1396
|
* `session.stop()`. The framework validates `resumeFrom` against the
|
|
1384
|
-
* harness's `
|
|
1397
|
+
* harness's `lifecycleStateSchema` before handing it to the adapter.
|
|
1398
|
+
* `createSession({ sessionId, continueFrom })` resumes from state returned
|
|
1399
|
+
* by `session.suspendTurn()` before `continueTurn()`.
|
|
1385
1400
|
* - **Host tool execution.** User tools passed in `settings.tools` are
|
|
1386
1401
|
* executed on the host whenever the underlying runtime calls them;
|
|
1387
1402
|
* the result is fed back to the harness via `submitToolResult`.
|
|
@@ -1427,12 +1442,17 @@ declare class HarnessAgent<THarness extends HarnessV1<any> = HarnessV1, TUserToo
|
|
|
1427
1442
|
sessionId?: string;
|
|
1428
1443
|
/**
|
|
1429
1444
|
* Resume payload returned by a prior `session.detach()` or
|
|
1430
|
-
* `session.stop()`. Must be
|
|
1431
|
-
*
|
|
1432
|
-
*
|
|
1433
|
-
|
|
1445
|
+
* `session.stop()`. Must be accompanied by the original `sessionId`; the
|
|
1446
|
+
* framework validates it against `harness.lifecycleStateSchema` before
|
|
1447
|
+
* handing it to the adapter.
|
|
1448
|
+
*/
|
|
1449
|
+
resumeFrom?: HarnessV1ResumeSessionState;
|
|
1450
|
+
/**
|
|
1451
|
+
* Continuation payload returned by a prior `session.suspendTurn()`. Must be
|
|
1452
|
+
* accompanied by the original `sessionId`; the framework validates it before
|
|
1453
|
+
* handing it to the adapter.
|
|
1434
1454
|
*/
|
|
1435
|
-
|
|
1455
|
+
continueFrom?: HarnessV1ContinueTurnState;
|
|
1436
1456
|
abortSignal?: AbortSignal;
|
|
1437
1457
|
}): Promise<HarnessAgentSession>;
|
|
1438
1458
|
generate(options: AgentCallParameters<never, HarnessAllTools<THarness, TUserTools>, RUNTIME_CONTEXT> & HarnessAgentCallExtensions): Promise<GenerateTextResult<HarnessAllTools<THarness, TUserTools>, RUNTIME_CONTEXT, never>>;
|
package/dist/agent/index.js
CHANGED
|
@@ -71,34 +71,40 @@ function releaseBridgePort(options) {
|
|
|
71
71
|
entry.leases.delete(options.sessionId);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// src/agent/internal/
|
|
74
|
+
// src/agent/internal/lifecycle-state-validation.ts
|
|
75
75
|
import { safeValidateTypes } from "@ai-sdk/provider-utils";
|
|
76
|
-
async function
|
|
76
|
+
async function validateLifecycleStateData(input) {
|
|
77
77
|
const { harness, state } = input;
|
|
78
|
+
if (state.type !== input.expectedType) {
|
|
79
|
+
throw new HarnessError({
|
|
80
|
+
message: `Lifecycle state has unexpected type '${state.type}'; expected '${input.expectedType}'.`
|
|
81
|
+
});
|
|
82
|
+
}
|
|
78
83
|
if (state.specificationVersion !== "harness-v1") {
|
|
79
84
|
throw new HarnessError({
|
|
80
|
-
message: `
|
|
85
|
+
message: `Lifecycle state has unexpected specificationVersion '${state.specificationVersion}'; expected 'harness-v1'.`
|
|
81
86
|
});
|
|
82
87
|
}
|
|
83
88
|
if (state.harnessId !== harness.harnessId) {
|
|
84
89
|
throw new HarnessError({
|
|
85
|
-
message: `
|
|
90
|
+
message: `Lifecycle state was produced by harness '${state.harnessId}' but this agent uses '${harness.harnessId}'.`
|
|
86
91
|
});
|
|
87
92
|
}
|
|
88
|
-
if (harness.
|
|
93
|
+
if (harness.lifecycleStateSchema == null) {
|
|
89
94
|
return state;
|
|
90
95
|
}
|
|
91
96
|
const result = await safeValidateTypes({
|
|
92
97
|
value: state.data,
|
|
93
|
-
schema: harness.
|
|
98
|
+
schema: harness.lifecycleStateSchema
|
|
94
99
|
});
|
|
95
100
|
if (!result.success) {
|
|
96
101
|
throw new HarnessError({
|
|
97
|
-
message: `
|
|
102
|
+
message: `Lifecycle state failed schema validation for harness '${harness.harnessId}': ${result.error.message}`,
|
|
98
103
|
cause: result.error
|
|
99
104
|
});
|
|
100
105
|
}
|
|
101
106
|
return {
|
|
107
|
+
type: state.type,
|
|
102
108
|
harnessId: state.harnessId,
|
|
103
109
|
specificationVersion: state.specificationVersion,
|
|
104
110
|
data: result.value,
|
|
@@ -1796,9 +1802,10 @@ var HarnessAgentSession = class {
|
|
|
1796
1802
|
const session = this.underlyingSession;
|
|
1797
1803
|
try {
|
|
1798
1804
|
const raw = await session.doDetach();
|
|
1799
|
-
const validated = await
|
|
1805
|
+
const validated = await validateLifecycleStateData({
|
|
1800
1806
|
harness: this.harness,
|
|
1801
|
-
state: raw
|
|
1807
|
+
state: raw,
|
|
1808
|
+
expectedType: "resume-session"
|
|
1802
1809
|
});
|
|
1803
1810
|
return this.withPendingToolApprovals(validated);
|
|
1804
1811
|
} finally {
|
|
@@ -1820,9 +1827,10 @@ var HarnessAgentSession = class {
|
|
|
1820
1827
|
const sandboxSession = this.getSandboxSession();
|
|
1821
1828
|
try {
|
|
1822
1829
|
const raw = await session.doStop();
|
|
1823
|
-
const validated = await
|
|
1830
|
+
const validated = await validateLifecycleStateData({
|
|
1824
1831
|
harness: this.harness,
|
|
1825
|
-
state: raw
|
|
1832
|
+
state: raw,
|
|
1833
|
+
expectedType: "resume-session"
|
|
1826
1834
|
});
|
|
1827
1835
|
return this.withPendingToolApprovals(validated);
|
|
1828
1836
|
} finally {
|
|
@@ -1852,8 +1860,8 @@ var HarnessAgentSession = class {
|
|
|
1852
1860
|
}
|
|
1853
1861
|
/**
|
|
1854
1862
|
* Gracefully freeze the active turn at the slice boundary and return the
|
|
1855
|
-
*
|
|
1856
|
-
* can
|
|
1863
|
+
* continuation payload, **leaving the sandbox/runtime running** so the next
|
|
1864
|
+
* process can continue. Resolves once the in-flight `stream()`/`continueTurn()`
|
|
1857
1865
|
* has cleanly wound down at a precise cursor (see
|
|
1858
1866
|
* {@link HarnessV1Session.doSuspendTurn}).
|
|
1859
1867
|
*
|
|
@@ -1871,9 +1879,10 @@ var HarnessAgentSession = class {
|
|
|
1871
1879
|
}
|
|
1872
1880
|
const session = this.underlyingSession;
|
|
1873
1881
|
const raw = await session.doSuspendTurn();
|
|
1874
|
-
const validated = await
|
|
1882
|
+
const validated = await validateLifecycleStateData({
|
|
1875
1883
|
harness: this.harness,
|
|
1876
|
-
state: raw
|
|
1884
|
+
state: raw,
|
|
1885
|
+
expectedType: "continue-turn"
|
|
1877
1886
|
});
|
|
1878
1887
|
this.stopped = true;
|
|
1879
1888
|
this.underlyingSession = void 0;
|
|
@@ -1887,6 +1896,7 @@ var HarnessAgentSession = class {
|
|
|
1887
1896
|
const pendingToolApprovals = this.getPendingToolApprovals();
|
|
1888
1897
|
if (pendingToolApprovals.length === 0) {
|
|
1889
1898
|
return {
|
|
1899
|
+
type: state.type,
|
|
1890
1900
|
harnessId: state.harnessId,
|
|
1891
1901
|
specificationVersion: state.specificationVersion,
|
|
1892
1902
|
data: state.data
|
|
@@ -2159,17 +2169,32 @@ var HarnessAgent = class {
|
|
|
2159
2169
|
* `session.destroy()`.
|
|
2160
2170
|
*/
|
|
2161
2171
|
async createSession(options) {
|
|
2162
|
-
var _a3;
|
|
2172
|
+
var _a3, _b3;
|
|
2163
2173
|
const sessionId = (_a3 = options == null ? void 0 : options.sessionId) != null ? _a3 : generateId5();
|
|
2164
2174
|
const resumeFrom = options == null ? void 0 : options.resumeFrom;
|
|
2175
|
+
const continueFrom = options == null ? void 0 : options.continueFrom;
|
|
2165
2176
|
const abortSignal = options == null ? void 0 : options.abortSignal;
|
|
2166
2177
|
const harness = this.settings.harness;
|
|
2167
2178
|
const sandboxProvider = this.settings.sandbox;
|
|
2179
|
+
if (resumeFrom != null && continueFrom != null) {
|
|
2180
|
+
throw new Error(
|
|
2181
|
+
"HarnessAgent.createSession: pass either `resumeFrom` or `continueFrom`, not both."
|
|
2182
|
+
);
|
|
2183
|
+
}
|
|
2168
2184
|
let validatedResumeFrom;
|
|
2169
2185
|
if (resumeFrom != null) {
|
|
2170
|
-
validatedResumeFrom = await
|
|
2186
|
+
validatedResumeFrom = await validateLifecycleStateData({
|
|
2187
|
+
harness,
|
|
2188
|
+
state: resumeFrom,
|
|
2189
|
+
expectedType: "resume-session"
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
let validatedContinueFrom;
|
|
2193
|
+
if (continueFrom != null) {
|
|
2194
|
+
validatedContinueFrom = await validateLifecycleStateData({
|
|
2171
2195
|
harness,
|
|
2172
|
-
state:
|
|
2196
|
+
state: continueFrom,
|
|
2197
|
+
expectedType: "continue-turn"
|
|
2173
2198
|
});
|
|
2174
2199
|
}
|
|
2175
2200
|
let recipe;
|
|
@@ -2181,7 +2206,7 @@ var HarnessAgent = class {
|
|
|
2181
2206
|
const acquiredSandboxSession = await this._acquireSandbox({
|
|
2182
2207
|
sandboxProvider,
|
|
2183
2208
|
sessionId,
|
|
2184
|
-
isResume: validatedResumeFrom != null,
|
|
2209
|
+
isResume: validatedResumeFrom != null || validatedContinueFrom != null,
|
|
2185
2210
|
recipe,
|
|
2186
2211
|
identity,
|
|
2187
2212
|
abortSignal
|
|
@@ -2228,6 +2253,7 @@ var HarnessAgent = class {
|
|
|
2228
2253
|
sessionId,
|
|
2229
2254
|
skills: this.settings.skills,
|
|
2230
2255
|
resumeFrom: validatedResumeFrom,
|
|
2256
|
+
continueFrom: validatedContinueFrom,
|
|
2231
2257
|
permissionMode: this.permissionMode,
|
|
2232
2258
|
abortSignal,
|
|
2233
2259
|
observability: buildObservability({ settings: this.settings })
|
|
@@ -2246,7 +2272,7 @@ var HarnessAgent = class {
|
|
|
2246
2272
|
leasedBridgePort,
|
|
2247
2273
|
sessionWorkDir,
|
|
2248
2274
|
toolApproval: this.settings.toolApproval,
|
|
2249
|
-
pendingToolApprovals: validatedResumeFrom == null ? void 0 : validatedResumeFrom.pendingToolApprovals
|
|
2275
|
+
pendingToolApprovals: (_b3 = validatedResumeFrom == null ? void 0 : validatedResumeFrom.pendingToolApprovals) != null ? _b3 : validatedContinueFrom == null ? void 0 : validatedContinueFrom.pendingToolApprovals
|
|
2250
2276
|
});
|
|
2251
2277
|
} catch (error) {
|
|
2252
2278
|
await cleanupAfterStartFailure({
|