@agen-ai/agent-runtime 0.4.1 → 0.4.3
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/README.md +176 -74
- package/dist/adapterValidation.d.ts +4 -2
- package/dist/adapterValidation.js +108 -59
- package/dist/contractErrors.d.ts +1 -1
- package/dist/contractErrors.js +7 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/nativeContinuations/admission.d.ts +17 -0
- package/dist/nativeContinuations/admission.js +250 -0
- package/dist/nativeContinuations/index.d.ts +2 -0
- package/dist/nativeContinuations/index.js +1 -0
- package/dist/nativeContinuations/types.d.ts +52 -0
- package/dist/nativeContinuations/types.js +0 -0
- package/dist/outputValidation.js +1 -0
- package/dist/providerCatalog.d.ts +1 -1
- package/dist/providerDriver.d.ts +4 -1
- package/dist/providerInstanceRegistry.d.ts +4 -4
- package/dist/sessionAdmission.d.ts +14 -0
- package/dist/sessionAdmission.js +67 -0
- package/dist/sessionInteractions/lifetime.d.ts +32 -3
- package/dist/sessionInteractions/lifetime.js +145 -13
- package/dist/sessionInteractions/request.d.ts +3 -2
- package/dist/sessionInteractions/request.js +98 -25
- package/dist/sessionInteractions/types.d.ts +68 -12
- package/dist/sessionInteractions/validation.d.ts +13 -9
- package/dist/sessionInteractions/validation.js +121 -60
- package/dist/sessionValidation.d.ts +80 -2
- package/dist/sessionValidation.js +348 -283
- package/dist/sessions.d.ts +33 -2
- package/dist/testing/conformance.d.ts +3 -1
- package/dist/testing/conformance.js +180 -85
- package/dist/testing/fakeProvider.js +2 -2
- package/dist/turnExecution/execution.d.ts +23 -6
- package/dist/turnExecution/execution.js +136 -32
- package/dist/turnExecution/requests.d.ts +15 -3
- package/dist/turnExecution/requests.js +93 -28
- package/package.json +2 -2
|
@@ -44,8 +44,10 @@ import {
|
|
|
44
44
|
validateAgentProviderOutputForContext
|
|
45
45
|
} from "./outputValidation.js";
|
|
46
46
|
import { validateAgentTurnSteeringResult } from "./steeringValidation.js";
|
|
47
|
-
import { createValidatedAgentTurnExecution } from "./turnExecution/execution.js";
|
|
47
|
+
import { createValidatedAgentTurnExecution, adoptValidatedAgentTurnExecution } from "./turnExecution/execution.js";
|
|
48
48
|
import { validateAgentProviderTurnInterruptionResult } from "./turnExecution/receipts.js";
|
|
49
|
+
import { createAgentTurnRequestAdmission } from "./turnExecution/requests.js";
|
|
50
|
+
import { createAgentSessionAdmission } from "./sessionAdmission.js";
|
|
49
51
|
function validateCloseReason(reason) {
|
|
50
52
|
if (reason !== void 0 && !["idle", "shutdown", "replaced", "contract_rejected", "error", "other"].includes(reason)) {
|
|
51
53
|
throw new TypeError("Provider session close reason is unsupported.");
|
|
@@ -163,7 +165,7 @@ function invalidTurnSequence(providerKey, message) {
|
|
|
163
165
|
);
|
|
164
166
|
}
|
|
165
167
|
function completeTurnSequence(input) {
|
|
166
|
-
if (input.
|
|
168
|
+
if (input.requests.hasUnclaimedRequest()) {
|
|
167
169
|
invalidTurnSequence(
|
|
168
170
|
input.providerKey,
|
|
169
171
|
"Provider completed a turn while an interaction request remained pending."
|
|
@@ -176,6 +178,7 @@ const FINAL_DIFF_TRAILING_EVENT_TYPES = [
|
|
|
176
178
|
"collaboration.updated",
|
|
177
179
|
"operation.updated",
|
|
178
180
|
"provider.diagnostic",
|
|
181
|
+
"request.unavailable",
|
|
179
182
|
"resource.updated",
|
|
180
183
|
"runtime.error",
|
|
181
184
|
"runtime.warning",
|
|
@@ -226,29 +229,19 @@ function observeItemLifecycle(input) {
|
|
|
226
229
|
terminal: event.type === "item.completed" || TERMINAL_ITEM_STATUSES.has(event.payload.status)
|
|
227
230
|
});
|
|
228
231
|
}
|
|
232
|
+
function hasLiveApprovalSubject(request, state) {
|
|
233
|
+
if (request.requestKind !== "approval") return true;
|
|
234
|
+
if (request.subject.kind === "plan") return state.proposedPlans.get(request.subject.artifactId) === request.requestId;
|
|
235
|
+
const item = state.observedItems.get(request.subject.itemId);
|
|
236
|
+
return item !== void 0 && !item.terminal && (item.status === "pending" || item.status === "in_progress" || item.status === "unknown" && item.inProgressObserved);
|
|
237
|
+
}
|
|
229
238
|
function assertApprovalSubjectCorrelation(input) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (request.subject.kind === "plan") {
|
|
233
|
-
if (input.state.proposedPlans.get(request.subject.artifactId) !== request.requestId) {
|
|
234
|
-
invalidTurnSequence(
|
|
235
|
-
input.providerKey,
|
|
236
|
-
"Provider approval request does not identify a proposed plan from this turn."
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
const item = input.state.observedItems.get(request.subject.itemId);
|
|
242
|
-
const itemIsLive = item !== void 0 && !item.terminal && (item.status === "pending" || item.status === "in_progress" || item.status === "unknown" && item.inProgressObserved);
|
|
243
|
-
if (!itemIsLive) {
|
|
244
|
-
invalidTurnSequence(
|
|
245
|
-
input.providerKey,
|
|
246
|
-
"Provider approval request does not identify a live item from this turn."
|
|
247
|
-
);
|
|
239
|
+
if (!hasLiveApprovalSubject(input.request, input.state)) {
|
|
240
|
+
invalidTurnSequence(input.providerKey, input.request.requestKind === "approval" && input.request.subject.kind === "plan" ? "Provider approval request does not identify a proposed plan from this turn." : "Provider approval request does not identify a live item from this turn.");
|
|
248
241
|
}
|
|
249
242
|
}
|
|
250
243
|
function assertPendingApprovalSubjectCorrelations(input) {
|
|
251
|
-
for (const pending of input.
|
|
244
|
+
for (const pending of input.requests.unclaimedRequests()) {
|
|
252
245
|
assertApprovalSubjectCorrelation({
|
|
253
246
|
providerKey: input.providerKey,
|
|
254
247
|
request: pending.request,
|
|
@@ -304,9 +297,7 @@ function observeTurnEvent(input) {
|
|
|
304
297
|
const {
|
|
305
298
|
contextUsageState,
|
|
306
299
|
event,
|
|
307
|
-
|
|
308
|
-
turnRequestIds,
|
|
309
|
-
pendingRequests,
|
|
300
|
+
requests,
|
|
310
301
|
providerKey,
|
|
311
302
|
state
|
|
312
303
|
} = input;
|
|
@@ -332,7 +323,7 @@ function observeTurnEvent(input) {
|
|
|
332
323
|
}
|
|
333
324
|
if (state.fileChangeMode === "final_diff") {
|
|
334
325
|
if (event.type === "turn.diff.updated") {
|
|
335
|
-
if (
|
|
326
|
+
if (requests.hasUnclaimedRequest()) {
|
|
336
327
|
invalidTurnSequence(
|
|
337
328
|
providerKey,
|
|
338
329
|
"Provider emitted a terminal diff while an interaction request remained pending."
|
|
@@ -356,7 +347,7 @@ function observeTurnEvent(input) {
|
|
|
356
347
|
observeItemLifecycle({ providerKey, event, state });
|
|
357
348
|
assertPendingApprovalSubjectCorrelations({
|
|
358
349
|
providerKey,
|
|
359
|
-
|
|
350
|
+
requests,
|
|
360
351
|
state
|
|
361
352
|
});
|
|
362
353
|
if (event.payload.itemKind === "context_compaction" && event.type === "item.completed" && event.payload.status === "completed") {
|
|
@@ -369,7 +360,7 @@ function observeTurnEvent(input) {
|
|
|
369
360
|
state.proposedPlans.set(event.payload.artifactId, event.payload.requestId);
|
|
370
361
|
assertPendingApprovalSubjectCorrelations({
|
|
371
362
|
providerKey,
|
|
372
|
-
|
|
363
|
+
requests,
|
|
373
364
|
state
|
|
374
365
|
});
|
|
375
366
|
}
|
|
@@ -381,34 +372,20 @@ function observeTurnEvent(input) {
|
|
|
381
372
|
});
|
|
382
373
|
}
|
|
383
374
|
if (event.type === "request.opened") {
|
|
384
|
-
if (pendingRequests.size > 0) {
|
|
385
|
-
invalidTurnSequence(
|
|
386
|
-
providerKey,
|
|
387
|
-
"Provider opened more than one pending request for a session."
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
const requestId = event.payload.request.requestId;
|
|
391
|
-
if (openedRequestIds.has(requestId)) {
|
|
392
|
-
invalidTurnSequence(
|
|
393
|
-
providerKey,
|
|
394
|
-
"Provider reused a request ID within a session."
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
375
|
assertApprovalSubjectCorrelation({
|
|
398
376
|
providerKey,
|
|
399
377
|
request: event.payload.request,
|
|
400
378
|
state
|
|
401
379
|
});
|
|
402
|
-
|
|
403
|
-
turnRequestIds.add(requestId);
|
|
404
|
-
pendingRequests.set(requestId, {
|
|
380
|
+
requests.open({
|
|
405
381
|
request: event.payload.request,
|
|
406
382
|
turnId: event.turnId
|
|
407
383
|
});
|
|
408
384
|
}
|
|
385
|
+
if (event.type === "request.unavailable") requests.unavailable(event.payload.requestId);
|
|
409
386
|
if (event.type === "turn.state_changed") {
|
|
410
387
|
const waiting = event.payload.state === "waiting_for_request";
|
|
411
|
-
if (waiting && !
|
|
388
|
+
if (waiting && !requests.hasOpened(event.payload.requestId)) {
|
|
412
389
|
invalidTurnSequence(
|
|
413
390
|
providerKey,
|
|
414
391
|
"Provider entered a waiting state for a request it did not open."
|
|
@@ -416,8 +393,8 @@ function observeTurnEvent(input) {
|
|
|
416
393
|
}
|
|
417
394
|
}
|
|
418
395
|
if (event.type === "turn.completed") {
|
|
419
|
-
if (event.payload.outcome !== "completed")
|
|
420
|
-
completeTurnSequence({ providerKey, state,
|
|
396
|
+
if (event.payload.outcome !== "completed") requests.withdraw();
|
|
397
|
+
completeTurnSequence({ providerKey, state, requests });
|
|
421
398
|
}
|
|
422
399
|
}
|
|
423
400
|
function observeTurnOutput(input) {
|
|
@@ -508,8 +485,7 @@ function observeTurnOutput(input) {
|
|
|
508
485
|
event: input.output.event,
|
|
509
486
|
state: input.state,
|
|
510
487
|
pendingRequests: input.pendingRequests,
|
|
511
|
-
|
|
512
|
-
turnRequestIds: input.turnRequestIds,
|
|
488
|
+
requests: input.requests,
|
|
513
489
|
contextUsageState: input.contextUsageState
|
|
514
490
|
});
|
|
515
491
|
}
|
|
@@ -523,6 +499,7 @@ const SESSION_OPERATION_OBSERVATION_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
523
499
|
"resource.updated",
|
|
524
500
|
"runtime.warning",
|
|
525
501
|
"runtime.error",
|
|
502
|
+
"runtime.retrying",
|
|
526
503
|
"provider.diagnostic"
|
|
527
504
|
]);
|
|
528
505
|
function observeSessionOperationOutput(input) {
|
|
@@ -541,14 +518,20 @@ function observeSessionOperationOutput(input) {
|
|
|
541
518
|
);
|
|
542
519
|
}
|
|
543
520
|
}
|
|
521
|
+
const pendingRequests = /* @__PURE__ */ new Map();
|
|
544
522
|
observeTurnOutput({
|
|
545
523
|
capabilities: input.capabilities,
|
|
546
524
|
providerKey: input.providerKey,
|
|
547
525
|
output: input.output,
|
|
548
526
|
state: input.state,
|
|
549
|
-
pendingRequests
|
|
550
|
-
|
|
551
|
-
|
|
527
|
+
pendingRequests,
|
|
528
|
+
requests: createAgentTurnRequestAdmission({
|
|
529
|
+
providerKey: input.providerKey,
|
|
530
|
+
sessionAdmission: createAgentSessionAdmission(input.providerKey),
|
|
531
|
+
pendingRequests,
|
|
532
|
+
canRestore: () => false,
|
|
533
|
+
canRestoreRequest: () => false
|
|
534
|
+
}),
|
|
552
535
|
contextUsageState: input.contextUsageState,
|
|
553
536
|
interactionState: input.interactionState
|
|
554
537
|
});
|
|
@@ -637,6 +620,146 @@ function assertAgentTurnInputCapability(input) {
|
|
|
637
620
|
});
|
|
638
621
|
if (textIssue) rejectReference(`${textIssue.target} must use ${textIssue.format} text`);
|
|
639
622
|
}
|
|
623
|
+
function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
624
|
+
const providerKey = capabilities.providerKey;
|
|
625
|
+
const sessionLifetime = new AbortController();
|
|
626
|
+
const sessionAdmission = createAgentSessionAdmission(providerKey);
|
|
627
|
+
const contextUsageState = {
|
|
628
|
+
latestByScope: /* @__PURE__ */ new Map(),
|
|
629
|
+
cumulativeByScope: /* @__PURE__ */ new Map(),
|
|
630
|
+
compactionReadyScopes: /* @__PURE__ */ new Set()
|
|
631
|
+
};
|
|
632
|
+
const interactionState = {
|
|
633
|
+
operationResults: /* @__PURE__ */ new Map(),
|
|
634
|
+
operationInvocations: /* @__PURE__ */ new Map(),
|
|
635
|
+
collaborationNodes: /* @__PURE__ */ new Map(),
|
|
636
|
+
collaborationSpawnReservations: /* @__PURE__ */ new Map(),
|
|
637
|
+
generatedResources: /* @__PURE__ */ new Map()
|
|
638
|
+
};
|
|
639
|
+
let closed = false;
|
|
640
|
+
let unusable = false;
|
|
641
|
+
let closing;
|
|
642
|
+
const requireOpen = () => {
|
|
643
|
+
if (closed)
|
|
644
|
+
throwAgentProviderContractError(
|
|
645
|
+
providerKey,
|
|
646
|
+
"session_closed",
|
|
647
|
+
"Provider session is closed."
|
|
648
|
+
);
|
|
649
|
+
};
|
|
650
|
+
const requireUsable = () => {
|
|
651
|
+
requireOpen();
|
|
652
|
+
if (unusable) {
|
|
653
|
+
throwAgentProviderContractError(
|
|
654
|
+
providerKey,
|
|
655
|
+
"session_unusable",
|
|
656
|
+
"Provider session cannot be reused after an incomplete operation."
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
const outputContext = (turnId) => ({
|
|
661
|
+
capabilities,
|
|
662
|
+
providerKey,
|
|
663
|
+
sessionId,
|
|
664
|
+
...turnId === void 0 ? {} : { turnId }
|
|
665
|
+
});
|
|
666
|
+
function installExecution(token, turnId, source) {
|
|
667
|
+
const pendingRequests = /* @__PURE__ */ new Map();
|
|
668
|
+
const state = {
|
|
669
|
+
fileChangeMode: capabilities.output.fileChanges,
|
|
670
|
+
observedItems: /* @__PURE__ */ new Map(),
|
|
671
|
+
proposedPlans: /* @__PURE__ */ new Map(),
|
|
672
|
+
generatedResourceIds: /* @__PURE__ */ new Set(),
|
|
673
|
+
started: false,
|
|
674
|
+
terminal: false,
|
|
675
|
+
finalDiffObserved: false
|
|
676
|
+
};
|
|
677
|
+
const inFlightOperations = /* @__PURE__ */ new Set();
|
|
678
|
+
const common = {
|
|
679
|
+
providerKey,
|
|
680
|
+
pendingRequests,
|
|
681
|
+
sessionAdmission,
|
|
682
|
+
inFlightOperations,
|
|
683
|
+
requireUsable,
|
|
684
|
+
isTerminal: () => state.terminal,
|
|
685
|
+
canRestoreRequest: (pending) => hasLiveApprovalSubject(pending.request, state),
|
|
686
|
+
observe(candidate, requests) {
|
|
687
|
+
const output = validateAgentProviderOutputForContext(candidate, outputContext(turnId));
|
|
688
|
+
observeTurnOutput({
|
|
689
|
+
capabilities,
|
|
690
|
+
providerKey,
|
|
691
|
+
output,
|
|
692
|
+
state,
|
|
693
|
+
pendingRequests,
|
|
694
|
+
requests,
|
|
695
|
+
contextUsageState,
|
|
696
|
+
interactionState
|
|
697
|
+
});
|
|
698
|
+
return output;
|
|
699
|
+
},
|
|
700
|
+
assertCompleted() {
|
|
701
|
+
if (!state.started || !state.terminal || pendingRequests.size > 0) {
|
|
702
|
+
invalidTurnSequence(providerKey, "Provider turn output must remain open until actual terminal completion.");
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
release() {
|
|
706
|
+
if (source.kind === "caller") sessionAdmission.releaseExecution(token);
|
|
707
|
+
},
|
|
708
|
+
retire() {
|
|
709
|
+
unusable = true;
|
|
710
|
+
},
|
|
711
|
+
abandon: () => closing ? closing() : Promise.reject(new Error("Session cleanup is waiting for its opening owner."))
|
|
712
|
+
};
|
|
713
|
+
const owner = source.kind === "caller" ? createValidatedAgentTurnExecution({ ...common, turnInput: source.input, start: source.start }) : adoptValidatedAgentTurnExecution({ ...common, turnId, createCandidate: source.createCandidate });
|
|
714
|
+
try {
|
|
715
|
+
sessionAdmission.installExecution(token, { turnId, pendingRequests, state, inFlightOperations, owner });
|
|
716
|
+
} catch (cause) {
|
|
717
|
+
owner.stop(cause instanceof Error ? cause : new Error("Execution installation failed.", { cause }));
|
|
718
|
+
throw cause;
|
|
719
|
+
}
|
|
720
|
+
return owner;
|
|
721
|
+
}
|
|
722
|
+
return {
|
|
723
|
+
sessionAdmission,
|
|
724
|
+
sessionLifetime,
|
|
725
|
+
contextUsageState,
|
|
726
|
+
interactionState,
|
|
727
|
+
outputContext,
|
|
728
|
+
requireUsable,
|
|
729
|
+
get activeTurn() {
|
|
730
|
+
return sessionAdmission.execution;
|
|
731
|
+
},
|
|
732
|
+
get closed() {
|
|
733
|
+
return closed;
|
|
734
|
+
},
|
|
735
|
+
get unusable() {
|
|
736
|
+
return unusable;
|
|
737
|
+
},
|
|
738
|
+
fence() {
|
|
739
|
+
unusable = true;
|
|
740
|
+
},
|
|
741
|
+
stop() {
|
|
742
|
+
unusable = true;
|
|
743
|
+
sessionAdmission.stop();
|
|
744
|
+
sessionLifetime.abort(new DOMException("The provider session was closed.", "AbortError"));
|
|
745
|
+
},
|
|
746
|
+
completeClose() {
|
|
747
|
+
closed = true;
|
|
748
|
+
},
|
|
749
|
+
installClose(close) {
|
|
750
|
+
closing = close;
|
|
751
|
+
},
|
|
752
|
+
reserveExecution: sessionAdmission.reserveExecution,
|
|
753
|
+
ownsExecution: sessionAdmission.ownsExecution,
|
|
754
|
+
releaseExecution: sessionAdmission.releaseExecution,
|
|
755
|
+
installNativeExecution(token, turnId, createCandidate) {
|
|
756
|
+
return installExecution(token, turnId, { kind: "native", createCandidate });
|
|
757
|
+
},
|
|
758
|
+
installCallerExecution(token, turnInput, start) {
|
|
759
|
+
return installExecution(token, turnInput.turnId, { kind: "caller", input: turnInput, start });
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
}
|
|
640
763
|
function validateAgentProviderSession(input) {
|
|
641
764
|
const { capabilities, sessionId } = input;
|
|
642
765
|
const providerKey = capabilities.providerKey;
|
|
@@ -672,58 +795,22 @@ function validateAgentProviderSession(input) {
|
|
|
672
795
|
);
|
|
673
796
|
}
|
|
674
797
|
validateSessionPorts(capabilities, input.candidate);
|
|
675
|
-
const
|
|
798
|
+
const validationOwner = input.validationOwner ?? createAgentSessionValidationOwner(capabilities, sessionId);
|
|
799
|
+
const { sessionLifetime, contextUsageState, interactionState, outputContext } = validationOwner;
|
|
800
|
+
const collaborationNodes = interactionState.collaborationNodes;
|
|
801
|
+
const collaborationSpawnReservations = interactionState.collaborationSpawnReservations;
|
|
802
|
+
const requireUsable = () => {
|
|
803
|
+
input.sessionInteractionOwner?.requireUsable();
|
|
804
|
+
validationOwner.requireUsable();
|
|
805
|
+
};
|
|
676
806
|
const environment = validateAgentEnvironmentObservationPort({
|
|
677
807
|
providerKey,
|
|
678
808
|
capability: capabilities.environment.session,
|
|
679
809
|
port: input.candidate.environment,
|
|
680
810
|
signal: sessionLifetime.signal
|
|
681
811
|
});
|
|
682
|
-
const openedRequestIds = /* @__PURE__ */ new Set();
|
|
683
|
-
const contextUsageState = {
|
|
684
|
-
latestByScope: /* @__PURE__ */ new Map(),
|
|
685
|
-
cumulativeByScope: /* @__PURE__ */ new Map(),
|
|
686
|
-
compactionReadyScopes: /* @__PURE__ */ new Set()
|
|
687
|
-
};
|
|
688
|
-
const interactionState = {
|
|
689
|
-
operationResults: /* @__PURE__ */ new Map(),
|
|
690
|
-
operationInvocations: /* @__PURE__ */ new Map(),
|
|
691
|
-
collaborationNodes: /* @__PURE__ */ new Map(),
|
|
692
|
-
collaborationSpawnReservations: /* @__PURE__ */ new Map(),
|
|
693
|
-
generatedResources: /* @__PURE__ */ new Map()
|
|
694
|
-
};
|
|
695
|
-
const collaborationNodes = interactionState.collaborationNodes;
|
|
696
|
-
const collaborationSpawnReservations = interactionState.collaborationSpawnReservations;
|
|
697
|
-
let activeTurn = null;
|
|
698
812
|
let closePromise = null;
|
|
699
|
-
let closed = false;
|
|
700
813
|
let providerClosed = false;
|
|
701
|
-
let unusable = false;
|
|
702
|
-
const requireOpen = () => {
|
|
703
|
-
if (closed)
|
|
704
|
-
throwAgentProviderContractError(
|
|
705
|
-
providerKey,
|
|
706
|
-
"session_closed",
|
|
707
|
-
"Provider session is closed."
|
|
708
|
-
);
|
|
709
|
-
};
|
|
710
|
-
const requireUsable = () => {
|
|
711
|
-
input.sessionInteractionOwner?.requireUsable();
|
|
712
|
-
requireOpen();
|
|
713
|
-
if (unusable) {
|
|
714
|
-
throwAgentProviderContractError(
|
|
715
|
-
providerKey,
|
|
716
|
-
"session_unusable",
|
|
717
|
-
"Provider session cannot be reused after an incomplete operation."
|
|
718
|
-
);
|
|
719
|
-
}
|
|
720
|
-
};
|
|
721
|
-
const outputContext = (turnId) => ({
|
|
722
|
-
capabilities,
|
|
723
|
-
providerKey,
|
|
724
|
-
sessionId,
|
|
725
|
-
...turnId === void 0 ? {} : { turnId }
|
|
726
|
-
});
|
|
727
814
|
const delegateProviderMutation = async (input2) => {
|
|
728
815
|
let executionStarted = false;
|
|
729
816
|
const onProviderExecutionStarted = () => {
|
|
@@ -760,7 +847,7 @@ function validateAgentProviderSession(input) {
|
|
|
760
847
|
return input2.validate(candidate);
|
|
761
848
|
} catch (error) {
|
|
762
849
|
if (!executionStarted) throw error;
|
|
763
|
-
|
|
850
|
+
validationOwner.fence();
|
|
764
851
|
throw new AgentProviderDelegatedOperationError(
|
|
765
852
|
providerKey,
|
|
766
853
|
input2.operation,
|
|
@@ -786,63 +873,17 @@ function validateAgentProviderSession(input) {
|
|
|
786
873
|
`Provider ${providerKey} does not support ${parsedInput.interactionMode} turn interaction mode.`
|
|
787
874
|
);
|
|
788
875
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
const pendingRequests = /* @__PURE__ */ new Map();
|
|
793
|
-
const turnRequestIds = /* @__PURE__ */ new Set();
|
|
794
|
-
const state = {
|
|
795
|
-
fileChangeMode: capabilities.output.fileChanges,
|
|
796
|
-
observedItems: /* @__PURE__ */ new Map(),
|
|
797
|
-
proposedPlans: /* @__PURE__ */ new Map(),
|
|
798
|
-
generatedResourceIds: /* @__PURE__ */ new Set(),
|
|
799
|
-
started: false,
|
|
800
|
-
terminal: false,
|
|
801
|
-
finalDiffObserved: false
|
|
802
|
-
};
|
|
803
|
-
const inFlightOperations = /* @__PURE__ */ new Set();
|
|
804
|
-
const owner = createValidatedAgentTurnExecution({
|
|
805
|
-
providerKey,
|
|
806
|
-
turnInput: {
|
|
876
|
+
const token = validationOwner.reserveExecution();
|
|
877
|
+
try {
|
|
878
|
+
return validationOwner.installCallerExecution(token, {
|
|
807
879
|
...parsedInput,
|
|
808
880
|
...turnInput.signal === void 0 ? {} : { signal: turnInput.signal },
|
|
809
881
|
...turnInput.onProviderExecutionStarted === void 0 ? {} : { onProviderExecutionStarted: turnInput.onProviderExecutionStarted }
|
|
810
|
-
},
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
isTerminal: () => state.terminal,
|
|
816
|
-
observe(candidate) {
|
|
817
|
-
const output = validateAgentProviderOutputForContext(candidate, outputContext(parsedInput.turnId));
|
|
818
|
-
observeTurnOutput({
|
|
819
|
-
capabilities,
|
|
820
|
-
providerKey,
|
|
821
|
-
output,
|
|
822
|
-
state,
|
|
823
|
-
pendingRequests,
|
|
824
|
-
openedRequestIds,
|
|
825
|
-
turnRequestIds,
|
|
826
|
-
contextUsageState,
|
|
827
|
-
interactionState
|
|
828
|
-
});
|
|
829
|
-
return output;
|
|
830
|
-
},
|
|
831
|
-
assertCompleted() {
|
|
832
|
-
if (!state.started || !state.terminal || pendingRequests.size > 0) {
|
|
833
|
-
invalidTurnSequence(providerKey, "Provider turn output must remain open until actual terminal completion.");
|
|
834
|
-
}
|
|
835
|
-
},
|
|
836
|
-
release() {
|
|
837
|
-
if (activeTurn?.owner === owner) activeTurn = null;
|
|
838
|
-
},
|
|
839
|
-
retire() {
|
|
840
|
-
unusable = true;
|
|
841
|
-
},
|
|
842
|
-
abandon: () => close({ reason: "other" })
|
|
843
|
-
});
|
|
844
|
-
activeTurn = { turnId: parsedInput.turnId, pendingRequests, state, inFlightOperations, owner };
|
|
845
|
-
return owner.execution;
|
|
882
|
+
}, (inputTurn) => input.candidate.startTurn(inputTurn)).execution;
|
|
883
|
+
} catch (error) {
|
|
884
|
+
validationOwner.releaseExecution(token);
|
|
885
|
+
throw error;
|
|
886
|
+
}
|
|
846
887
|
};
|
|
847
888
|
const declaredInterruption = input.candidate.interruption;
|
|
848
889
|
const interruption = declaredInterruption.kind === "unsupported" ? Object.freeze({ kind: "unsupported" }) : Object.freeze({
|
|
@@ -855,7 +896,7 @@ function validateAgentProviderSession(input) {
|
|
|
855
896
|
reason: interruptionInput.reason,
|
|
856
897
|
...interruptionInput.requestedAt === void 0 ? {} : { requestedAt: interruptionInput.requestedAt }
|
|
857
898
|
});
|
|
858
|
-
const targetedActiveTurn = activeTurn?.turnId === parsed.turnId ? activeTurn : null;
|
|
899
|
+
const targetedActiveTurn = validationOwner.activeTurn?.turnId === parsed.turnId ? validationOwner.activeTurn : null;
|
|
859
900
|
const targetedTurn = targetedActiveTurn;
|
|
860
901
|
if (targetedTurn === null || targetedTurn.state.terminal || !targetedTurn.owner.hasEntered()) {
|
|
861
902
|
throwAgentProviderContractError(
|
|
@@ -880,7 +921,7 @@ function validateAgentProviderSession(input) {
|
|
|
880
921
|
);
|
|
881
922
|
} catch (error) {
|
|
882
923
|
suspendedRequests.withdraw();
|
|
883
|
-
|
|
924
|
+
validationOwner.fence();
|
|
884
925
|
throw error;
|
|
885
926
|
}
|
|
886
927
|
if (result.status === "failed") {
|
|
@@ -899,7 +940,7 @@ function validateAgentProviderSession(input) {
|
|
|
899
940
|
requireUsable();
|
|
900
941
|
throwIfAgentOperationAborted(steeringInput.signal);
|
|
901
942
|
const turnId = parseAgentTurnId(steeringInput.turnId);
|
|
902
|
-
if (activeTurn?.turnId !== turnId || !activeTurn.owner.hasEntered() || activeTurn.state.terminal || activeTurn.pendingRequests.size > 0) {
|
|
943
|
+
if (validationOwner.activeTurn?.turnId !== turnId || !validationOwner.activeTurn.owner.hasEntered() || validationOwner.activeTurn.state.terminal || validationOwner.activeTurn.pendingRequests.size > 0) {
|
|
903
944
|
throwAgentProviderContractError(
|
|
904
945
|
providerKey,
|
|
905
946
|
"active_turn_mismatch",
|
|
@@ -915,7 +956,7 @@ function validateAgentProviderSession(input) {
|
|
|
915
956
|
parts: content.parts,
|
|
916
957
|
providerKey
|
|
917
958
|
});
|
|
918
|
-
const targetedActiveTurn = activeTurn;
|
|
959
|
+
const targetedActiveTurn = validationOwner.activeTurn;
|
|
919
960
|
const settleSteering = trackActiveTurnOperation(targetedActiveTurn);
|
|
920
961
|
try {
|
|
921
962
|
try {
|
|
@@ -927,10 +968,10 @@ function validateAgentProviderSession(input) {
|
|
|
927
968
|
}),
|
|
928
969
|
providerKey
|
|
929
970
|
);
|
|
930
|
-
if (result.status === "delivery_uncertain")
|
|
971
|
+
if (result.status === "delivery_uncertain") validationOwner.fence();
|
|
931
972
|
return result;
|
|
932
973
|
} catch (error) {
|
|
933
|
-
|
|
974
|
+
validationOwner.fence();
|
|
934
975
|
throw new AgentProviderDelegatedOperationError(
|
|
935
976
|
providerKey,
|
|
936
977
|
"steer_turn",
|
|
@@ -1008,142 +1049,154 @@ function validateAgentProviderSession(input) {
|
|
|
1008
1049
|
invokeOperation: async (operationInput) => {
|
|
1009
1050
|
requireUsable();
|
|
1010
1051
|
throwIfAgentOperationAborted(operationInput.signal);
|
|
1011
|
-
|
|
1012
|
-
|
|
1052
|
+
const settle = validationOwner.sessionAdmission.trackOperation();
|
|
1053
|
+
const signal = operationInput.signal === void 0 ? sessionLifetime.signal : AbortSignal.any([operationInput.signal, sessionLifetime.signal]);
|
|
1054
|
+
operationInput = { ...operationInput, signal };
|
|
1013
1055
|
try {
|
|
1014
|
-
|
|
1015
|
-
observationTurnId
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
);
|
|
1034
|
-
if (descriptor === void 0) {
|
|
1035
|
-
return throwAgentProviderContractError(
|
|
1036
|
-
providerKey,
|
|
1037
|
-
"input_operation_mismatch",
|
|
1038
|
-
"Operation invocation does not identify an offered operation."
|
|
1056
|
+
let invocation;
|
|
1057
|
+
let observationTurnId;
|
|
1058
|
+
try {
|
|
1059
|
+
invocation = parseAgentOperationInvocation(operationInput.invocation);
|
|
1060
|
+
observationTurnId = parseAgentTurnId(
|
|
1061
|
+
operationInput.observationTurnId
|
|
1062
|
+
);
|
|
1063
|
+
} catch {
|
|
1064
|
+
return throwAgentProviderContractError(
|
|
1065
|
+
providerKey,
|
|
1066
|
+
"input_operation_mismatch",
|
|
1067
|
+
"Operation invocation is invalid."
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
const catalog = validateAgentOperationCatalogForCapabilities(
|
|
1071
|
+
capabilities,
|
|
1072
|
+
await declaredOperations.listOperations(
|
|
1073
|
+
operationInput.signal === void 0 ? {} : { signal: operationInput.signal }
|
|
1074
|
+
)
|
|
1039
1075
|
);
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
invocation = parseAgentOperationInvocationFor(
|
|
1043
|
-
descriptor,
|
|
1044
|
-
invocation
|
|
1076
|
+
const descriptor = catalog.operations.find(
|
|
1077
|
+
(operation) => operation.operationId === invocation.operationId
|
|
1045
1078
|
);
|
|
1046
|
-
|
|
1047
|
-
return throwAgentProviderContractError(
|
|
1048
|
-
providerKey,
|
|
1049
|
-
"input_operation_mismatch",
|
|
1050
|
-
"Operation invocation is stale or outside the offered descriptor."
|
|
1051
|
-
);
|
|
1052
|
-
}
|
|
1053
|
-
const existing = interactionState.operationInvocations.get(
|
|
1054
|
-
invocation.invocationId
|
|
1055
|
-
);
|
|
1056
|
-
if (existing !== void 0) {
|
|
1057
|
-
if (JSON.stringify(existing.invocation) !== JSON.stringify(invocation)) {
|
|
1079
|
+
if (descriptor === void 0) {
|
|
1058
1080
|
return throwAgentProviderContractError(
|
|
1059
1081
|
providerKey,
|
|
1060
1082
|
"input_operation_mismatch",
|
|
1061
|
-
"Operation invocation
|
|
1083
|
+
"Operation invocation does not identify an offered operation."
|
|
1062
1084
|
);
|
|
1063
1085
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1086
|
+
try {
|
|
1087
|
+
invocation = parseAgentOperationInvocationFor(
|
|
1088
|
+
descriptor,
|
|
1089
|
+
invocation
|
|
1090
|
+
);
|
|
1091
|
+
} catch {
|
|
1092
|
+
return throwAgentProviderContractError(
|
|
1093
|
+
providerKey,
|
|
1094
|
+
"input_operation_mismatch",
|
|
1095
|
+
"Operation invocation is stale or outside the offered descriptor."
|
|
1096
|
+
);
|
|
1066
1097
|
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
"input_operation_mismatch",
|
|
1070
|
-
"Operation invocation ID is already active or is not replayable."
|
|
1098
|
+
const existing = interactionState.operationInvocations.get(
|
|
1099
|
+
invocation.invocationId
|
|
1071
1100
|
);
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
};
|
|
1076
|
-
const observationState = {
|
|
1077
|
-
fileChangeMode: capabilities.output.fileChanges,
|
|
1078
|
-
observedItems: /* @__PURE__ */ new Map(),
|
|
1079
|
-
proposedPlans: /* @__PURE__ */ new Map(),
|
|
1080
|
-
generatedResourceIds: /* @__PURE__ */ new Set(),
|
|
1081
|
-
started: true,
|
|
1082
|
-
terminal: false,
|
|
1083
|
-
finalDiffObserved: false
|
|
1084
|
-
};
|
|
1085
|
-
interactionState.operationInvocations.set(
|
|
1086
|
-
invocation.invocationId,
|
|
1087
|
-
trackedInvocation
|
|
1088
|
-
);
|
|
1089
|
-
try {
|
|
1090
|
-
const result = await delegateProviderMutation({
|
|
1091
|
-
operation: "invoke_operation",
|
|
1092
|
-
observer: operationInput.onProviderExecutionStarted,
|
|
1093
|
-
invoke: (onProviderExecutionStarted, onOutput) => declaredOperations.invokeOperation({
|
|
1094
|
-
invocation,
|
|
1095
|
-
observationTurnId,
|
|
1096
|
-
onProviderExecutionStarted,
|
|
1097
|
-
onOutput,
|
|
1098
|
-
...operationInput.signal === void 0 ? {} : { signal: operationInput.signal }
|
|
1099
|
-
}),
|
|
1100
|
-
observeOutput: async (candidate) => {
|
|
1101
|
-
const output = validateAgentProviderOutputForContext(
|
|
1102
|
-
candidate,
|
|
1103
|
-
{
|
|
1104
|
-
...outputContext(observationTurnId),
|
|
1105
|
-
operationInvocationId: invocation.invocationId
|
|
1106
|
-
}
|
|
1107
|
-
);
|
|
1108
|
-
observeSessionOperationOutput({
|
|
1109
|
-
capabilities,
|
|
1110
|
-
providerKey,
|
|
1111
|
-
output,
|
|
1112
|
-
state: observationState,
|
|
1113
|
-
contextUsageState,
|
|
1114
|
-
interactionState
|
|
1115
|
-
});
|
|
1116
|
-
await operationInput.onOutput?.(output);
|
|
1117
|
-
},
|
|
1118
|
-
validate: (candidate) => {
|
|
1119
|
-
const result2 = validateAgentOperationResultTransition({
|
|
1101
|
+
if (existing !== void 0) {
|
|
1102
|
+
if (JSON.stringify(existing.invocation) !== JSON.stringify(invocation)) {
|
|
1103
|
+
return throwAgentProviderContractError(
|
|
1120
1104
|
providerKey,
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
descriptor,
|
|
1124
|
-
invocation,
|
|
1125
|
-
candidate
|
|
1126
|
-
),
|
|
1127
|
-
previous: interactionState.operationResults.get(
|
|
1128
|
-
invocation.invocationId
|
|
1129
|
-
)
|
|
1130
|
-
});
|
|
1131
|
-
interactionState.operationResults.set(
|
|
1132
|
-
result2.invocationId,
|
|
1133
|
-
result2
|
|
1105
|
+
"input_operation_mismatch",
|
|
1106
|
+
"Operation invocation ID was reused with conflicting input."
|
|
1134
1107
|
);
|
|
1135
|
-
return result2;
|
|
1136
1108
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
invocation.
|
|
1109
|
+
if (descriptor.idempotency === "required" && existing.result !== void 0) {
|
|
1110
|
+
return existing.result;
|
|
1111
|
+
}
|
|
1112
|
+
return throwAgentProviderContractError(
|
|
1113
|
+
providerKey,
|
|
1114
|
+
"input_operation_mismatch",
|
|
1115
|
+
"Operation invocation ID is already active or is not replayable."
|
|
1144
1116
|
);
|
|
1145
1117
|
}
|
|
1146
|
-
|
|
1118
|
+
requireUsable();
|
|
1119
|
+
signal.throwIfAborted();
|
|
1120
|
+
const reservation = descriptor.timing === "idle_session" && descriptor.executionMode === "immediate" ? validationOwner.reserveExecution() : void 0;
|
|
1121
|
+
const trackedInvocation = {
|
|
1122
|
+
invocation
|
|
1123
|
+
};
|
|
1124
|
+
const observationState = {
|
|
1125
|
+
fileChangeMode: capabilities.output.fileChanges,
|
|
1126
|
+
observedItems: /* @__PURE__ */ new Map(),
|
|
1127
|
+
proposedPlans: /* @__PURE__ */ new Map(),
|
|
1128
|
+
generatedResourceIds: /* @__PURE__ */ new Set(),
|
|
1129
|
+
started: true,
|
|
1130
|
+
terminal: false,
|
|
1131
|
+
finalDiffObserved: false
|
|
1132
|
+
};
|
|
1133
|
+
interactionState.operationInvocations.set(
|
|
1134
|
+
invocation.invocationId,
|
|
1135
|
+
trackedInvocation
|
|
1136
|
+
);
|
|
1137
|
+
try {
|
|
1138
|
+
const result = await delegateProviderMutation({
|
|
1139
|
+
operation: "invoke_operation",
|
|
1140
|
+
observer: operationInput.onProviderExecutionStarted,
|
|
1141
|
+
invoke: (onProviderExecutionStarted, onOutput) => declaredOperations.invokeOperation({
|
|
1142
|
+
invocation,
|
|
1143
|
+
observationTurnId,
|
|
1144
|
+
onProviderExecutionStarted,
|
|
1145
|
+
onOutput,
|
|
1146
|
+
...operationInput.signal === void 0 ? {} : { signal: operationInput.signal }
|
|
1147
|
+
}),
|
|
1148
|
+
observeOutput: async (candidate) => {
|
|
1149
|
+
const output = validateAgentProviderOutputForContext(
|
|
1150
|
+
candidate,
|
|
1151
|
+
{
|
|
1152
|
+
...outputContext(observationTurnId),
|
|
1153
|
+
operationInvocationId: invocation.invocationId
|
|
1154
|
+
}
|
|
1155
|
+
);
|
|
1156
|
+
observeSessionOperationOutput({
|
|
1157
|
+
capabilities,
|
|
1158
|
+
providerKey,
|
|
1159
|
+
output,
|
|
1160
|
+
state: observationState,
|
|
1161
|
+
contextUsageState,
|
|
1162
|
+
interactionState
|
|
1163
|
+
});
|
|
1164
|
+
await operationInput.onOutput?.(output);
|
|
1165
|
+
},
|
|
1166
|
+
validate: (candidate) => {
|
|
1167
|
+
const result2 = validateAgentOperationResultTransition({
|
|
1168
|
+
providerKey,
|
|
1169
|
+
candidate: validateAgentOperationResultForInvocation(
|
|
1170
|
+
providerKey,
|
|
1171
|
+
descriptor,
|
|
1172
|
+
invocation,
|
|
1173
|
+
candidate
|
|
1174
|
+
),
|
|
1175
|
+
previous: interactionState.operationResults.get(
|
|
1176
|
+
invocation.invocationId
|
|
1177
|
+
)
|
|
1178
|
+
});
|
|
1179
|
+
interactionState.operationResults.set(
|
|
1180
|
+
result2.invocationId,
|
|
1181
|
+
result2
|
|
1182
|
+
);
|
|
1183
|
+
return result2;
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
trackedInvocation.result = result;
|
|
1187
|
+
return result;
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
if (!(error instanceof AgentProviderDelegatedOperationError)) {
|
|
1190
|
+
interactionState.operationInvocations.delete(
|
|
1191
|
+
invocation.invocationId
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
throw error;
|
|
1195
|
+
} finally {
|
|
1196
|
+
if (reservation !== void 0) validationOwner.releaseExecution(reservation);
|
|
1197
|
+
}
|
|
1198
|
+
} finally {
|
|
1199
|
+
settle();
|
|
1147
1200
|
}
|
|
1148
1201
|
}
|
|
1149
1202
|
});
|
|
@@ -1394,14 +1447,14 @@ function validateAgentProviderSession(input) {
|
|
|
1394
1447
|
}
|
|
1395
1448
|
});
|
|
1396
1449
|
const closeOwned = (closeInput, explicit) => {
|
|
1397
|
-
if (closed && !input.sessionInteractionOwner) return Promise.resolve();
|
|
1450
|
+
if (validationOwner.closed && !input.sessionInteractionOwner) return Promise.resolve();
|
|
1398
1451
|
if (!input.sessionInteractionOwner && closePromise) return closePromise;
|
|
1399
1452
|
throwIfAgentOperationAborted(closeInput.signal);
|
|
1400
1453
|
validateCloseReason(closeInput.reason);
|
|
1401
|
-
|
|
1402
|
-
|
|
1454
|
+
validationOwner.fence();
|
|
1455
|
+
validationOwner.stop();
|
|
1403
1456
|
input.hostBindingLease?.stop();
|
|
1404
|
-
const closingTurn = activeTurn;
|
|
1457
|
+
const closingTurn = validationOwner.activeTurn;
|
|
1405
1458
|
closingTurn?.owner.stop(new DOMException("The provider session was closed.", "AbortError"));
|
|
1406
1459
|
const cleanup = async () => {
|
|
1407
1460
|
if (!providerClosed) {
|
|
@@ -1410,8 +1463,9 @@ function validateAgentProviderSession(input) {
|
|
|
1410
1463
|
}
|
|
1411
1464
|
await input.sessionInteractionOwner?.join();
|
|
1412
1465
|
await closingTurn?.owner.join();
|
|
1466
|
+
await validationOwner.sessionAdmission.joinOperations();
|
|
1413
1467
|
await input.hostBindingLease?.release();
|
|
1414
|
-
|
|
1468
|
+
validationOwner.completeClose();
|
|
1415
1469
|
};
|
|
1416
1470
|
if (input.sessionInteractionOwner) return input.sessionInteractionOwner.close(cleanup, explicit);
|
|
1417
1471
|
closePromise = Promise.resolve().then(cleanup).finally(() => {
|
|
@@ -1420,6 +1474,7 @@ function validateAgentProviderSession(input) {
|
|
|
1420
1474
|
return closePromise;
|
|
1421
1475
|
};
|
|
1422
1476
|
const close = (closeInput) => closeOwned(closeInput, true);
|
|
1477
|
+
validationOwner.installClose(() => closeOwned({ reason: "error" }, false));
|
|
1423
1478
|
input.sessionInteractionOwner?.installClose(() => closeOwned({ reason: "error" }, false));
|
|
1424
1479
|
return Object.freeze({
|
|
1425
1480
|
binding,
|
|
@@ -1504,8 +1559,14 @@ function bindingTracker(input) {
|
|
|
1504
1559
|
"Provider branch reused its source binding."
|
|
1505
1560
|
);
|
|
1506
1561
|
}
|
|
1507
|
-
input.observer(binding);
|
|
1508
1562
|
observed = binding;
|
|
1563
|
+
try {
|
|
1564
|
+
input.interactions?.bind();
|
|
1565
|
+
input.observer(binding);
|
|
1566
|
+
} catch (cause) {
|
|
1567
|
+
input.interactions?.fail(cause);
|
|
1568
|
+
throw cause;
|
|
1569
|
+
}
|
|
1509
1570
|
},
|
|
1510
1571
|
requireMatch(binding) {
|
|
1511
1572
|
if (!observed) {
|
|
@@ -1529,15 +1590,18 @@ async function openIdentityCreatingAgentProviderSession(input) {
|
|
|
1529
1590
|
const tracker = bindingTracker({
|
|
1530
1591
|
providerKey: input.capabilities.providerKey,
|
|
1531
1592
|
observer: input.observer,
|
|
1593
|
+
...input.sessionInteractionOwner === void 0 ? {} : { interactions: input.sessionInteractionOwner },
|
|
1532
1594
|
...input.sourceBinding === void 0 ? {} : { sourceBinding: input.sourceBinding }
|
|
1533
1595
|
});
|
|
1534
1596
|
let candidate = null;
|
|
1535
1597
|
try {
|
|
1536
1598
|
candidate = await input.open(tracker.observe);
|
|
1599
|
+
tracker.requireMatch(parseAgentSessionBinding(candidate.binding));
|
|
1537
1600
|
const session = validateAgentProviderSession({
|
|
1538
1601
|
capabilities: input.capabilities,
|
|
1539
1602
|
sessionId: input.sessionId,
|
|
1540
1603
|
candidate,
|
|
1604
|
+
...input.validationOwner === void 0 ? {} : { validationOwner: input.validationOwner },
|
|
1541
1605
|
...input.sessionInteractionOwner === void 0 ? {} : { sessionInteractionOwner: input.sessionInteractionOwner },
|
|
1542
1606
|
...input.hostBindingLease === void 0 ? {} : { hostBindingLease: input.hostBindingLease },
|
|
1543
1607
|
...input.sourceBinding === void 0 ? {} : { sourceBinding: input.sourceBinding }
|
|
@@ -1560,6 +1624,7 @@ async function openIdentityCreatingAgentProviderSession(input) {
|
|
|
1560
1624
|
}
|
|
1561
1625
|
export {
|
|
1562
1626
|
closeRejectedAgentProviderSession,
|
|
1627
|
+
createAgentSessionValidationOwner,
|
|
1563
1628
|
openIdentityCreatingAgentProviderSession,
|
|
1564
1629
|
validateAgentProviderSession
|
|
1565
1630
|
};
|