@agen-ai/agent-runtime 0.4.2 → 0.4.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/README.md +316 -10
- package/dist/adapterValidation.js +38 -4
- package/dist/contractErrors.d.ts +2 -2
- package/dist/contractErrors.js +8 -1
- package/dist/executionInput/index.d.ts +3 -0
- package/dist/executionInput/index.js +4 -0
- package/dist/executionInput/lifetime.d.ts +47 -0
- package/dist/executionInput/lifetime.js +241 -0
- package/dist/executionInput/types.d.ts +61 -0
- package/dist/executionInput/types.js +0 -0
- package/dist/executionInput/validation.d.ts +25 -0
- package/dist/executionInput/validation.js +178 -0
- package/dist/generation/cleanup.d.ts +15 -0
- package/dist/generation/cleanup.js +108 -0
- package/dist/generation/deadline.d.ts +16 -0
- package/dist/generation/deadline.js +81 -0
- package/dist/generation/decoding.d.ts +4 -0
- package/dist/generation/decoding.js +59 -0
- package/dist/generation/errors.d.ts +29 -0
- package/dist/generation/errors.js +39 -0
- package/dist/generation/generateObject.d.ts +3 -0
- package/dist/generation/generateObject.js +148 -0
- package/dist/generation/index.d.ts +5 -0
- package/dist/generation/index.js +8 -0
- package/dist/generation/preflight.d.ts +25 -0
- package/dist/generation/preflight.js +48 -0
- package/dist/generation/requests.d.ts +17 -0
- package/dist/generation/requests.js +117 -0
- package/dist/generation/types.d.ts +22 -0
- package/dist/generation/types.js +0 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -1
- package/dist/nativeContinuations/admission.js +1 -0
- package/dist/outputValidation.d.ts +2 -0
- package/dist/outputValidation.js +29 -1
- package/dist/sessionAdmission.d.ts +2 -0
- package/dist/sessionAdmission.js +13 -0
- package/dist/sessionInteractions/lifetime.d.ts +1 -0
- package/dist/sessionInteractions/lifetime.js +4 -0
- package/dist/sessionInteractions/request.d.ts +1 -0
- package/dist/sessionInteractions/request.js +3 -0
- package/dist/sessionValidation.d.ts +15 -3
- package/dist/sessionValidation.js +215 -127
- package/dist/sessions.d.ts +7 -1
- package/dist/structuredOutput/admission.d.ts +16 -0
- package/dist/structuredOutput/admission.js +89 -0
- package/dist/structuredOutput/candidate.d.ts +22 -0
- package/dist/structuredOutput/candidate.js +64 -0
- package/dist/structuredOutput/validation.d.ts +8 -0
- package/dist/structuredOutput/validation.js +26 -0
- package/dist/testing/conformance.d.ts +20 -1
- package/dist/testing/conformance.js +103 -3
- package/dist/testing/fakeProvider.js +5 -4
- package/dist/turnExecution/execution.d.ts +9 -1
- package/dist/turnExecution/execution.js +88 -7
- package/dist/turnExecution/terminalBuffer.d.ts +9 -0
- package/dist/turnExecution/terminalBuffer.js +38 -0
- package/package.json +6 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AgentCapabilities, type AgentCollaborationId, type AgentGeneratedResourceId, type AgentOperationInvocationId, type AgentProviderKey, type AgentSessionId, type AgentTurnId } from "@agen-ai/agent-protocol";
|
|
2
2
|
import { type AgentProviderOutput } from "./outputs.js";
|
|
3
3
|
import type { AgentProviderOperationResult } from "./sessions.js";
|
|
4
|
+
import type { AgentStructuredOutputBinding } from "./structuredOutput/admission.js";
|
|
4
5
|
export interface AgentProviderOutputValidationContext {
|
|
5
6
|
readonly capabilities: AgentCapabilities;
|
|
6
7
|
readonly providerKey: AgentProviderKey;
|
|
@@ -10,6 +11,7 @@ export interface AgentProviderOutputValidationContext {
|
|
|
10
11
|
readonly operationInvocationId?: AgentOperationInvocationId;
|
|
11
12
|
readonly collaborationId?: AgentCollaborationId;
|
|
12
13
|
readonly generatedResourceId?: AgentGeneratedResourceId;
|
|
14
|
+
readonly structuredOutputBinding?: AgentStructuredOutputBinding;
|
|
13
15
|
}
|
|
14
16
|
export declare function validateAgentProviderOutputForContext(candidate: AgentProviderOutput, context: AgentProviderOutputValidationContext): AgentProviderOutput;
|
|
15
17
|
export declare function validateAgentProviderOperationResult(candidate: AgentProviderOperationResult, context: AgentProviderOutputValidationContext): AgentProviderOperationResult;
|
package/dist/outputValidation.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
AGENT_PROTOCOL_EVENT_BYTES_LIMIT,
|
|
3
|
+
agentProtocolSerializedJsonBytes,
|
|
4
|
+
parseAgentError,
|
|
5
|
+
parseAgentEvent
|
|
3
6
|
} from "@agen-ai/agent-protocol";
|
|
4
7
|
import { throwAgentProviderContractError } from "./contractErrors.js";
|
|
5
8
|
import {
|
|
6
9
|
validateAgentProviderOutput
|
|
7
10
|
} from "./outputs.js";
|
|
11
|
+
import { validateAgentStructuredOutputResult } from "./structuredOutput/validation.js";
|
|
8
12
|
function unsupportedCapabilitySemantic(value) {
|
|
9
13
|
throw new TypeError(
|
|
10
14
|
`Unsupported Agent Protocol capability semantic: ${String(value)}.`
|
|
@@ -206,6 +210,30 @@ function validateAgentProviderOutputForContext(candidate, context) {
|
|
|
206
210
|
);
|
|
207
211
|
}
|
|
208
212
|
assertOutputCapability(context, output);
|
|
213
|
+
if (output.kind === "event" && output.event.type === "turn.completed") {
|
|
214
|
+
let structuredOutput = validateAgentStructuredOutputResult({
|
|
215
|
+
providerKey: context.providerKey,
|
|
216
|
+
...context.structuredOutputBinding === void 0 ? {} : { binding: context.structuredOutputBinding },
|
|
217
|
+
result: output.event.payload.structuredOutput
|
|
218
|
+
});
|
|
219
|
+
if (output.event.payload.outcome !== "completed") return output;
|
|
220
|
+
let event = {
|
|
221
|
+
...output.event,
|
|
222
|
+
payload: { ...output.event.payload, structuredOutput }
|
|
223
|
+
};
|
|
224
|
+
if (structuredOutput.kind === "unavailable" && structuredOutput.reason === "schema_mismatch" && structuredOutput.issues !== void 0 && agentProtocolSerializedJsonBytes(event) > AGENT_PROTOCOL_EVENT_BYTES_LIMIT) {
|
|
225
|
+
structuredOutput = Object.freeze({ kind: "unavailable", reason: "schema_mismatch" });
|
|
226
|
+
event = { ...event, payload: { ...event.payload, structuredOutput } };
|
|
227
|
+
}
|
|
228
|
+
parseAgentEvent(event);
|
|
229
|
+
return Object.freeze({
|
|
230
|
+
...output,
|
|
231
|
+
event: Object.freeze({
|
|
232
|
+
...event,
|
|
233
|
+
payload: Object.freeze(event.payload)
|
|
234
|
+
})
|
|
235
|
+
});
|
|
236
|
+
}
|
|
209
237
|
return output;
|
|
210
238
|
}
|
|
211
239
|
function validateAgentProviderOperationResult(candidate, context) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AgentProviderKey, AgentRequestId } from "@agen-ai/agent-protocol";
|
|
2
2
|
export declare function createAgentSessionAdmission<Execution = unknown>(providerKey: AgentProviderKey): {
|
|
3
|
+
trackOperation(): () => void;
|
|
4
|
+
joinOperations(): Promise<void>;
|
|
3
5
|
reserveExecution(): object;
|
|
4
6
|
installExecution(token: object, execution: Execution): void;
|
|
5
7
|
releaseExecution(token: object): void;
|
package/dist/sessionAdmission.js
CHANGED
|
@@ -6,7 +6,20 @@ function createAgentSessionAdmission(providerKey) {
|
|
|
6
6
|
let requestIdBytes = 0;
|
|
7
7
|
let slot;
|
|
8
8
|
let stopped = false;
|
|
9
|
+
const operations = /* @__PURE__ */ new Set();
|
|
9
10
|
return {
|
|
11
|
+
trackOperation() {
|
|
12
|
+
if (stopped) throwAgentProviderContractError(providerKey, "session_unusable", "Session admission is stopped.");
|
|
13
|
+
const completion = Promise.withResolvers();
|
|
14
|
+
operations.add(completion.promise);
|
|
15
|
+
return () => {
|
|
16
|
+
operations.delete(completion.promise);
|
|
17
|
+
completion.resolve();
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
async joinOperations() {
|
|
21
|
+
await Promise.all(operations);
|
|
22
|
+
},
|
|
10
23
|
reserveExecution() {
|
|
11
24
|
if (stopped) throwAgentProviderContractError(providerKey, "session_unusable", "Session admission is stopped.");
|
|
12
25
|
if (slot) throwAgentProviderContractError(providerKey, "concurrent_turn", "Provider session already owns an execution.");
|
|
@@ -49,6 +49,7 @@ export declare class SessionInteractionOwner {
|
|
|
49
49
|
constructor(providerKey: AgentProviderKey, sessionId: AgentSessionId, context: AgentSessionInteractionContext, validationOwner: AgentSessionValidationOwner, operation: AgentSessionInteractionOpeningOperation, support: AgentSessionInteractionSupport, nativeSupport: AgentNativeContinuationSupport, continuations?: AgentNativeContinuationContext, signal?: AbortSignal);
|
|
50
50
|
track<Result>(promise: Promise<Result>): Promise<Result>;
|
|
51
51
|
get accepting(): boolean;
|
|
52
|
+
get hasLiveRequests(): boolean;
|
|
52
53
|
requireUsable(): void;
|
|
53
54
|
private offer;
|
|
54
55
|
requireContinuation(kind: "form" | "plan_review"): void;
|
|
@@ -102,6 +102,10 @@ class SessionInteractionOwner {
|
|
|
102
102
|
get accepting() {
|
|
103
103
|
return this.state === "opening" || this.state === "open";
|
|
104
104
|
}
|
|
105
|
+
get hasLiveRequests() {
|
|
106
|
+
for (const request of this.requests.values()) if (request.blocksExecutionInput) return true;
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
105
109
|
requireUsable() {
|
|
106
110
|
if (this.fatal) throw this.fatal.cause;
|
|
107
111
|
this.validationOwner.requireUsable();
|
|
@@ -25,6 +25,7 @@ export declare class SessionInteractionRequest {
|
|
|
25
25
|
constructor(owner: SessionInteractionOwner, candidate: Candidate, retire: () => void);
|
|
26
26
|
observe(): void;
|
|
27
27
|
setCallback(callback: Promise<void>): void;
|
|
28
|
+
get blocksExecutionInput(): boolean;
|
|
28
29
|
private scheduleExpiry;
|
|
29
30
|
private expire;
|
|
30
31
|
private protocolFailure;
|
|
@@ -76,6 +76,9 @@ class SessionInteractionRequest {
|
|
|
76
76
|
}
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
|
+
get blocksExecutionInput() {
|
|
80
|
+
return this.state.kind !== "terminal" || this.responseWork > 0 || !this.rawTerminalSettled;
|
|
81
|
+
}
|
|
79
82
|
scheduleExpiry() {
|
|
80
83
|
if (this.candidate.deadlineAt === void 0 || this.state.kind === "terminal") return;
|
|
81
84
|
const remainingMs = this.candidate.deadlineAt - Date.now();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentCapabilities, type AgentCollaborationNode, type AgentContextCumulativeUsage, type AgentContextMeasurementScope, type AgentContextUsage, type AgentGeneratedResourceDescriptor, type AgentItemKind, type AgentItemStatus, type AgentOperationInvocation, type AgentOperationResult, type AgentProviderKey, type AgentSessionBinding, type AgentSessionId, type AgentTurnId } from "@agen-ai/agent-protocol";
|
|
1
|
+
import { type AgentCapabilities, type AgentCollaborationNode, type AgentContextCumulativeUsage, type AgentContextMeasurementScope, type AgentContextUsage, type AgentGeneratedResourceDescriptor, type AgentItemKind, type AgentItemStatus, type AgentOperationInputCapability, type AgentOperationInvocation, type AgentOperationResult, type AgentProviderKey, type AgentSessionBinding, type AgentSessionId, type AgentTurnId } from "@agen-ai/agent-protocol";
|
|
2
2
|
import { type AgentHostBindingLease } from "./hostBindings/lifetime.js";
|
|
3
3
|
import { type MaybePromise } from "./foundation.js";
|
|
4
4
|
import { type AgentProviderOutputValidationContext } from "./outputValidation.js";
|
|
@@ -6,6 +6,8 @@ import type { AgentProviderStartTurnInput, AgentProviderSession, AgentSessionBin
|
|
|
6
6
|
import { type ValidatedAgentTurnExecution, type AdoptedAgentTurnExecution } from "./turnExecution/execution.js";
|
|
7
7
|
import { type PendingAgentRequest } from "./turnExecution/requests.js";
|
|
8
8
|
import type { SessionInteractionOwner } from "./sessionInteractions/lifetime.js";
|
|
9
|
+
import type { AgentExecutionInputSupport } from "./executionInput/types.js";
|
|
10
|
+
import { type AgentStructuredOutputBinding } from "./structuredOutput/admission.js";
|
|
9
11
|
interface ObservedAgentItem {
|
|
10
12
|
readonly itemKind: AgentItemKind;
|
|
11
13
|
readonly status: AgentItemStatus;
|
|
@@ -47,8 +49,15 @@ interface ActiveAgentTurn {
|
|
|
47
49
|
readonly inFlightOperations: Set<Promise<void>>;
|
|
48
50
|
readonly owner: ValidatedAgentTurnExecution;
|
|
49
51
|
}
|
|
50
|
-
export declare function
|
|
52
|
+
export declare function assertAgentTurnInputCapability(input: {
|
|
53
|
+
readonly capability: AgentOperationInputCapability;
|
|
54
|
+
readonly parts: AgentProviderStartTurnInput["parts"];
|
|
55
|
+
readonly providerKey: AgentProviderKey;
|
|
56
|
+
}): void;
|
|
57
|
+
export declare function createAgentSessionValidationOwner(capabilities: AgentCapabilities, sessionId: AgentSessionId, structuredOutputBinding?: AgentStructuredOutputBinding, executionInputSupport?: AgentExecutionInputSupport): {
|
|
51
58
|
sessionAdmission: {
|
|
59
|
+
trackOperation(): () => void;
|
|
60
|
+
joinOperations(): Promise<void>;
|
|
52
61
|
reserveExecution(): object;
|
|
53
62
|
installExecution(token: object, execution: ActiveAgentTurn): void;
|
|
54
63
|
releaseExecution(token: object): void;
|
|
@@ -69,11 +78,14 @@ export declare function createAgentSessionValidationOwner(capabilities: AgentCap
|
|
|
69
78
|
stop(): void;
|
|
70
79
|
completeClose(): void;
|
|
71
80
|
installClose(close: () => Promise<void>): void;
|
|
81
|
+
installInputContextGuard(guard: () => void): void;
|
|
72
82
|
reserveExecution: () => object;
|
|
73
83
|
ownsExecution: (token: object) => boolean;
|
|
74
84
|
releaseExecution: (token: object) => void;
|
|
85
|
+
admitTurnOutput(output: unknown, hasOutput: boolean): AgentStructuredOutputBinding | undefined;
|
|
86
|
+
requireNativeContinuationSupport: () => void;
|
|
75
87
|
installNativeExecution(token: object, turnId: AgentTurnId, createCandidate: (signal: AbortSignal) => AgentProviderTurnExecution): AdoptedAgentTurnExecution;
|
|
76
|
-
installCallerExecution(token: object, turnInput: AgentProviderStartTurnInput, start: (input: AgentProviderStartTurnInput) => AgentProviderTurnExecution): ValidatedAgentTurnExecution;
|
|
88
|
+
installCallerExecution(token: object, turnInput: AgentProviderStartTurnInput, start: (input: AgentProviderStartTurnInput) => AgentProviderTurnExecution, binding?: AgentStructuredOutputBinding): ValidatedAgentTurnExecution;
|
|
77
89
|
};
|
|
78
90
|
export type AgentSessionValidationOwner = ReturnType<typeof createAgentSessionValidationOwner>;
|
|
79
91
|
export declare function validateAgentProviderSession(input: {
|
|
@@ -48,6 +48,10 @@ import { createValidatedAgentTurnExecution, adoptValidatedAgentTurnExecution } f
|
|
|
48
48
|
import { validateAgentProviderTurnInterruptionResult } from "./turnExecution/receipts.js";
|
|
49
49
|
import { createAgentTurnRequestAdmission } from "./turnExecution/requests.js";
|
|
50
50
|
import { createAgentSessionAdmission } from "./sessionAdmission.js";
|
|
51
|
+
import { createExecutionInputCensus } from "./executionInput/lifetime.js";
|
|
52
|
+
import {
|
|
53
|
+
admitAgentStructuredOutputTurn
|
|
54
|
+
} from "./structuredOutput/admission.js";
|
|
51
55
|
function validateCloseReason(reason) {
|
|
52
56
|
if (reason !== void 0 && !["idle", "shutdown", "replaced", "contract_rejected", "error", "other"].includes(reason)) {
|
|
53
57
|
throw new TypeError("Provider session close reason is unsupported.");
|
|
@@ -499,6 +503,7 @@ const SESSION_OPERATION_OBSERVATION_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
499
503
|
"resource.updated",
|
|
500
504
|
"runtime.warning",
|
|
501
505
|
"runtime.error",
|
|
506
|
+
"runtime.retrying",
|
|
502
507
|
"provider.diagnostic"
|
|
503
508
|
]);
|
|
504
509
|
function observeSessionOperationOutput(input) {
|
|
@@ -619,7 +624,7 @@ function assertAgentTurnInputCapability(input) {
|
|
|
619
624
|
});
|
|
620
625
|
if (textIssue) rejectReference(`${textIssue.target} must use ${textIssue.format} text`);
|
|
621
626
|
}
|
|
622
|
-
function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
627
|
+
function createAgentSessionValidationOwner(capabilities, sessionId, structuredOutputBinding, executionInputSupport) {
|
|
623
628
|
const providerKey = capabilities.providerKey;
|
|
624
629
|
const sessionLifetime = new AbortController();
|
|
625
630
|
const sessionAdmission = createAgentSessionAdmission(providerKey);
|
|
@@ -638,6 +643,15 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
|
638
643
|
let closed = false;
|
|
639
644
|
let unusable = false;
|
|
640
645
|
let closing;
|
|
646
|
+
let requireInputContext = () => {
|
|
647
|
+
};
|
|
648
|
+
const executionInputCensus = createExecutionInputCensus(providerKey, () => {
|
|
649
|
+
unusable = true;
|
|
650
|
+
queueMicrotask(() => {
|
|
651
|
+
void closing?.().catch(() => {
|
|
652
|
+
});
|
|
653
|
+
});
|
|
654
|
+
});
|
|
641
655
|
const requireOpen = () => {
|
|
642
656
|
if (closed)
|
|
643
657
|
throwAgentProviderContractError(
|
|
@@ -676,6 +690,11 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
|
676
690
|
const inFlightOperations = /* @__PURE__ */ new Set();
|
|
677
691
|
const common = {
|
|
678
692
|
providerKey,
|
|
693
|
+
...executionInputSupport === void 0 ? {} : { executionInputSupport },
|
|
694
|
+
executionInputCensus,
|
|
695
|
+
ownsExecution: () => sessionAdmission.ownsExecution(token),
|
|
696
|
+
requireInputContext: () => requireInputContext(),
|
|
697
|
+
structuredOutputBound: source.kind === "caller" && source.binding !== void 0,
|
|
679
698
|
pendingRequests,
|
|
680
699
|
sessionAdmission,
|
|
681
700
|
inFlightOperations,
|
|
@@ -683,7 +702,10 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
|
683
702
|
isTerminal: () => state.terminal,
|
|
684
703
|
canRestoreRequest: (pending) => hasLiveApprovalSubject(pending.request, state),
|
|
685
704
|
observe(candidate, requests) {
|
|
686
|
-
const output = validateAgentProviderOutputForContext(candidate,
|
|
705
|
+
const output = validateAgentProviderOutputForContext(candidate, {
|
|
706
|
+
...outputContext(turnId),
|
|
707
|
+
...source.kind !== "caller" || source.binding === void 0 ? {} : { structuredOutputBinding: source.binding }
|
|
708
|
+
});
|
|
687
709
|
observeTurnOutput({
|
|
688
710
|
capabilities,
|
|
689
711
|
providerKey,
|
|
@@ -718,6 +740,15 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
|
718
740
|
}
|
|
719
741
|
return owner;
|
|
720
742
|
}
|
|
743
|
+
const requireNativeContinuationSupport = () => {
|
|
744
|
+
if (structuredOutputBinding !== void 0) {
|
|
745
|
+
throwAgentProviderContractError(
|
|
746
|
+
providerKey,
|
|
747
|
+
"structured_output_unsupported",
|
|
748
|
+
"Schema-bound sessions cannot dispatch native continuations without structured-output admission."
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
};
|
|
721
752
|
return {
|
|
722
753
|
sessionAdmission,
|
|
723
754
|
sessionLifetime,
|
|
@@ -748,14 +779,38 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
|
|
|
748
779
|
installClose(close) {
|
|
749
780
|
closing = close;
|
|
750
781
|
},
|
|
782
|
+
installInputContextGuard(guard) {
|
|
783
|
+
requireInputContext = guard;
|
|
784
|
+
},
|
|
751
785
|
reserveExecution: sessionAdmission.reserveExecution,
|
|
752
786
|
ownsExecution: sessionAdmission.ownsExecution,
|
|
753
787
|
releaseExecution: sessionAdmission.releaseExecution,
|
|
788
|
+
admitTurnOutput(output, hasOutput) {
|
|
789
|
+
if (structuredOutputBinding !== void 0 && hasOutput) {
|
|
790
|
+
throwAgentProviderContractError(
|
|
791
|
+
providerKey,
|
|
792
|
+
"structured_output_scope_mismatch",
|
|
793
|
+
"A schema-bound session cannot override or remove its opening structured-output request."
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
return admitAgentStructuredOutputTurn({
|
|
797
|
+
capabilities,
|
|
798
|
+
...structuredOutputBinding === void 0 ? {} : { binding: structuredOutputBinding },
|
|
799
|
+
output
|
|
800
|
+
});
|
|
801
|
+
},
|
|
802
|
+
requireNativeContinuationSupport,
|
|
754
803
|
installNativeExecution(token, turnId, createCandidate) {
|
|
804
|
+
requireNativeContinuationSupport();
|
|
755
805
|
return installExecution(token, turnId, { kind: "native", createCandidate });
|
|
756
806
|
},
|
|
757
|
-
installCallerExecution(token, turnInput, start) {
|
|
758
|
-
return installExecution(token, turnInput.turnId, {
|
|
807
|
+
installCallerExecution(token, turnInput, start, binding) {
|
|
808
|
+
return installExecution(token, turnInput.turnId, {
|
|
809
|
+
kind: "caller",
|
|
810
|
+
input: turnInput,
|
|
811
|
+
start,
|
|
812
|
+
...binding === void 0 ? {} : { binding }
|
|
813
|
+
});
|
|
759
814
|
}
|
|
760
815
|
};
|
|
761
816
|
}
|
|
@@ -795,6 +850,14 @@ function validateAgentProviderSession(input) {
|
|
|
795
850
|
}
|
|
796
851
|
validateSessionPorts(capabilities, input.candidate);
|
|
797
852
|
const validationOwner = input.validationOwner ?? createAgentSessionValidationOwner(capabilities, sessionId);
|
|
853
|
+
validationOwner.installInputContextGuard(() => {
|
|
854
|
+
input.sessionInteractionOwner?.requireUsable();
|
|
855
|
+
if (input.sessionInteractionOwner?.hasLiveRequests) throwAgentProviderContractError(
|
|
856
|
+
providerKey,
|
|
857
|
+
"request_pending",
|
|
858
|
+
"Execution input cannot enter while a session interaction remains unsettled."
|
|
859
|
+
);
|
|
860
|
+
});
|
|
798
861
|
const { sessionLifetime, contextUsageState, interactionState, outputContext } = validationOwner;
|
|
799
862
|
const collaborationNodes = interactionState.collaborationNodes;
|
|
800
863
|
const collaborationSpawnReservations = interactionState.collaborationSpawnReservations;
|
|
@@ -861,6 +924,7 @@ function validateAgentProviderSession(input) {
|
|
|
861
924
|
turnId: turnInput.turnId,
|
|
862
925
|
interactionMode: turnInput.interactionMode,
|
|
863
926
|
parts: turnInput.parts,
|
|
927
|
+
...turnInput.output === void 0 ? {} : { output: turnInput.output },
|
|
864
928
|
...turnInput.summary === void 0 ? {} : { summary: turnInput.summary },
|
|
865
929
|
...turnInput.deadlineAt === void 0 ? {} : { deadlineAt: turnInput.deadlineAt }
|
|
866
930
|
});
|
|
@@ -872,13 +936,15 @@ function validateAgentProviderSession(input) {
|
|
|
872
936
|
`Provider ${providerKey} does not support ${parsedInput.interactionMode} turn interaction mode.`
|
|
873
937
|
);
|
|
874
938
|
}
|
|
939
|
+
const binding2 = validationOwner.admitTurnOutput(parsedInput.output, Reflect.has(turnInput, "output"));
|
|
875
940
|
const token = validationOwner.reserveExecution();
|
|
876
941
|
try {
|
|
877
942
|
return validationOwner.installCallerExecution(token, {
|
|
878
943
|
...parsedInput,
|
|
944
|
+
...parsedInput.output === void 0 || binding2 === void 0 ? {} : { output: binding2.request },
|
|
879
945
|
...turnInput.signal === void 0 ? {} : { signal: turnInput.signal },
|
|
880
946
|
...turnInput.onProviderExecutionStarted === void 0 ? {} : { onProviderExecutionStarted: turnInput.onProviderExecutionStarted }
|
|
881
|
-
}, (inputTurn) => input.candidate.startTurn(inputTurn)).execution;
|
|
947
|
+
}, (inputTurn) => input.candidate.startTurn(inputTurn), binding2).execution;
|
|
882
948
|
} catch (error) {
|
|
883
949
|
validationOwner.releaseExecution(token);
|
|
884
950
|
throw error;
|
|
@@ -907,6 +973,7 @@ function validateAgentProviderSession(input) {
|
|
|
907
973
|
const settleActiveInterruption = trackActiveTurnOperation(
|
|
908
974
|
targetedActiveTurn
|
|
909
975
|
);
|
|
976
|
+
targetedTurn.owner.closeInputAdmission();
|
|
910
977
|
try {
|
|
911
978
|
const suspendedRequests = targetedTurn.owner.suspendRequests();
|
|
912
979
|
let result;
|
|
@@ -938,6 +1005,13 @@ function validateAgentProviderSession(input) {
|
|
|
938
1005
|
steerTurn: async (steeringInput) => {
|
|
939
1006
|
requireUsable();
|
|
940
1007
|
throwIfAgentOperationAborted(steeringInput.signal);
|
|
1008
|
+
if (Reflect.has(steeringInput, "output")) {
|
|
1009
|
+
throwAgentProviderContractError(
|
|
1010
|
+
providerKey,
|
|
1011
|
+
"structured_output_scope_mismatch",
|
|
1012
|
+
"Steering cannot change a turn's structured-output request."
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
941
1015
|
const turnId = parseAgentTurnId(steeringInput.turnId);
|
|
942
1016
|
if (validationOwner.activeTurn?.turnId !== turnId || !validationOwner.activeTurn.owner.hasEntered() || validationOwner.activeTurn.state.terminal || validationOwner.activeTurn.pendingRequests.size > 0) {
|
|
943
1017
|
throwAgentProviderContractError(
|
|
@@ -1048,142 +1122,154 @@ function validateAgentProviderSession(input) {
|
|
|
1048
1122
|
invokeOperation: async (operationInput) => {
|
|
1049
1123
|
requireUsable();
|
|
1050
1124
|
throwIfAgentOperationAborted(operationInput.signal);
|
|
1051
|
-
|
|
1052
|
-
|
|
1125
|
+
const settle = validationOwner.sessionAdmission.trackOperation();
|
|
1126
|
+
const signal = operationInput.signal === void 0 ? sessionLifetime.signal : AbortSignal.any([operationInput.signal, sessionLifetime.signal]);
|
|
1127
|
+
operationInput = { ...operationInput, signal };
|
|
1053
1128
|
try {
|
|
1054
|
-
|
|
1055
|
-
observationTurnId
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
);
|
|
1074
|
-
if (descriptor === void 0) {
|
|
1075
|
-
return throwAgentProviderContractError(
|
|
1076
|
-
providerKey,
|
|
1077
|
-
"input_operation_mismatch",
|
|
1078
|
-
"Operation invocation does not identify an offered operation."
|
|
1129
|
+
let invocation;
|
|
1130
|
+
let observationTurnId;
|
|
1131
|
+
try {
|
|
1132
|
+
invocation = parseAgentOperationInvocation(operationInput.invocation);
|
|
1133
|
+
observationTurnId = parseAgentTurnId(
|
|
1134
|
+
operationInput.observationTurnId
|
|
1135
|
+
);
|
|
1136
|
+
} catch {
|
|
1137
|
+
return throwAgentProviderContractError(
|
|
1138
|
+
providerKey,
|
|
1139
|
+
"input_operation_mismatch",
|
|
1140
|
+
"Operation invocation is invalid."
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1143
|
+
const catalog = validateAgentOperationCatalogForCapabilities(
|
|
1144
|
+
capabilities,
|
|
1145
|
+
await declaredOperations.listOperations(
|
|
1146
|
+
operationInput.signal === void 0 ? {} : { signal: operationInput.signal }
|
|
1147
|
+
)
|
|
1079
1148
|
);
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
invocation = parseAgentOperationInvocationFor(
|
|
1083
|
-
descriptor,
|
|
1084
|
-
invocation
|
|
1149
|
+
const descriptor = catalog.operations.find(
|
|
1150
|
+
(operation) => operation.operationId === invocation.operationId
|
|
1085
1151
|
);
|
|
1086
|
-
|
|
1087
|
-
return throwAgentProviderContractError(
|
|
1088
|
-
providerKey,
|
|
1089
|
-
"input_operation_mismatch",
|
|
1090
|
-
"Operation invocation is stale or outside the offered descriptor."
|
|
1091
|
-
);
|
|
1092
|
-
}
|
|
1093
|
-
const existing = interactionState.operationInvocations.get(
|
|
1094
|
-
invocation.invocationId
|
|
1095
|
-
);
|
|
1096
|
-
if (existing !== void 0) {
|
|
1097
|
-
if (JSON.stringify(existing.invocation) !== JSON.stringify(invocation)) {
|
|
1152
|
+
if (descriptor === void 0) {
|
|
1098
1153
|
return throwAgentProviderContractError(
|
|
1099
1154
|
providerKey,
|
|
1100
1155
|
"input_operation_mismatch",
|
|
1101
|
-
"Operation invocation
|
|
1156
|
+
"Operation invocation does not identify an offered operation."
|
|
1102
1157
|
);
|
|
1103
1158
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1159
|
+
try {
|
|
1160
|
+
invocation = parseAgentOperationInvocationFor(
|
|
1161
|
+
descriptor,
|
|
1162
|
+
invocation
|
|
1163
|
+
);
|
|
1164
|
+
} catch {
|
|
1165
|
+
return throwAgentProviderContractError(
|
|
1166
|
+
providerKey,
|
|
1167
|
+
"input_operation_mismatch",
|
|
1168
|
+
"Operation invocation is stale or outside the offered descriptor."
|
|
1169
|
+
);
|
|
1106
1170
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
"input_operation_mismatch",
|
|
1110
|
-
"Operation invocation ID is already active or is not replayable."
|
|
1171
|
+
const existing = interactionState.operationInvocations.get(
|
|
1172
|
+
invocation.invocationId
|
|
1111
1173
|
);
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
};
|
|
1116
|
-
const observationState = {
|
|
1117
|
-
fileChangeMode: capabilities.output.fileChanges,
|
|
1118
|
-
observedItems: /* @__PURE__ */ new Map(),
|
|
1119
|
-
proposedPlans: /* @__PURE__ */ new Map(),
|
|
1120
|
-
generatedResourceIds: /* @__PURE__ */ new Set(),
|
|
1121
|
-
started: true,
|
|
1122
|
-
terminal: false,
|
|
1123
|
-
finalDiffObserved: false
|
|
1124
|
-
};
|
|
1125
|
-
interactionState.operationInvocations.set(
|
|
1126
|
-
invocation.invocationId,
|
|
1127
|
-
trackedInvocation
|
|
1128
|
-
);
|
|
1129
|
-
try {
|
|
1130
|
-
const result = await delegateProviderMutation({
|
|
1131
|
-
operation: "invoke_operation",
|
|
1132
|
-
observer: operationInput.onProviderExecutionStarted,
|
|
1133
|
-
invoke: (onProviderExecutionStarted, onOutput) => declaredOperations.invokeOperation({
|
|
1134
|
-
invocation,
|
|
1135
|
-
observationTurnId,
|
|
1136
|
-
onProviderExecutionStarted,
|
|
1137
|
-
onOutput,
|
|
1138
|
-
...operationInput.signal === void 0 ? {} : { signal: operationInput.signal }
|
|
1139
|
-
}),
|
|
1140
|
-
observeOutput: async (candidate) => {
|
|
1141
|
-
const output = validateAgentProviderOutputForContext(
|
|
1142
|
-
candidate,
|
|
1143
|
-
{
|
|
1144
|
-
...outputContext(observationTurnId),
|
|
1145
|
-
operationInvocationId: invocation.invocationId
|
|
1146
|
-
}
|
|
1147
|
-
);
|
|
1148
|
-
observeSessionOperationOutput({
|
|
1149
|
-
capabilities,
|
|
1150
|
-
providerKey,
|
|
1151
|
-
output,
|
|
1152
|
-
state: observationState,
|
|
1153
|
-
contextUsageState,
|
|
1154
|
-
interactionState
|
|
1155
|
-
});
|
|
1156
|
-
await operationInput.onOutput?.(output);
|
|
1157
|
-
},
|
|
1158
|
-
validate: (candidate) => {
|
|
1159
|
-
const result2 = validateAgentOperationResultTransition({
|
|
1174
|
+
if (existing !== void 0) {
|
|
1175
|
+
if (JSON.stringify(existing.invocation) !== JSON.stringify(invocation)) {
|
|
1176
|
+
return throwAgentProviderContractError(
|
|
1160
1177
|
providerKey,
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
descriptor,
|
|
1164
|
-
invocation,
|
|
1165
|
-
candidate
|
|
1166
|
-
),
|
|
1167
|
-
previous: interactionState.operationResults.get(
|
|
1168
|
-
invocation.invocationId
|
|
1169
|
-
)
|
|
1170
|
-
});
|
|
1171
|
-
interactionState.operationResults.set(
|
|
1172
|
-
result2.invocationId,
|
|
1173
|
-
result2
|
|
1178
|
+
"input_operation_mismatch",
|
|
1179
|
+
"Operation invocation ID was reused with conflicting input."
|
|
1174
1180
|
);
|
|
1175
|
-
return result2;
|
|
1176
1181
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
invocation.
|
|
1182
|
+
if (descriptor.idempotency === "required" && existing.result !== void 0) {
|
|
1183
|
+
return existing.result;
|
|
1184
|
+
}
|
|
1185
|
+
return throwAgentProviderContractError(
|
|
1186
|
+
providerKey,
|
|
1187
|
+
"input_operation_mismatch",
|
|
1188
|
+
"Operation invocation ID is already active or is not replayable."
|
|
1184
1189
|
);
|
|
1185
1190
|
}
|
|
1186
|
-
|
|
1191
|
+
requireUsable();
|
|
1192
|
+
signal.throwIfAborted();
|
|
1193
|
+
const reservation = descriptor.timing === "idle_session" && descriptor.executionMode === "immediate" ? validationOwner.reserveExecution() : void 0;
|
|
1194
|
+
const trackedInvocation = {
|
|
1195
|
+
invocation
|
|
1196
|
+
};
|
|
1197
|
+
const observationState = {
|
|
1198
|
+
fileChangeMode: capabilities.output.fileChanges,
|
|
1199
|
+
observedItems: /* @__PURE__ */ new Map(),
|
|
1200
|
+
proposedPlans: /* @__PURE__ */ new Map(),
|
|
1201
|
+
generatedResourceIds: /* @__PURE__ */ new Set(),
|
|
1202
|
+
started: true,
|
|
1203
|
+
terminal: false,
|
|
1204
|
+
finalDiffObserved: false
|
|
1205
|
+
};
|
|
1206
|
+
interactionState.operationInvocations.set(
|
|
1207
|
+
invocation.invocationId,
|
|
1208
|
+
trackedInvocation
|
|
1209
|
+
);
|
|
1210
|
+
try {
|
|
1211
|
+
const result = await delegateProviderMutation({
|
|
1212
|
+
operation: "invoke_operation",
|
|
1213
|
+
observer: operationInput.onProviderExecutionStarted,
|
|
1214
|
+
invoke: (onProviderExecutionStarted, onOutput) => declaredOperations.invokeOperation({
|
|
1215
|
+
invocation,
|
|
1216
|
+
observationTurnId,
|
|
1217
|
+
onProviderExecutionStarted,
|
|
1218
|
+
onOutput,
|
|
1219
|
+
...operationInput.signal === void 0 ? {} : { signal: operationInput.signal }
|
|
1220
|
+
}),
|
|
1221
|
+
observeOutput: async (candidate) => {
|
|
1222
|
+
const output = validateAgentProviderOutputForContext(
|
|
1223
|
+
candidate,
|
|
1224
|
+
{
|
|
1225
|
+
...outputContext(observationTurnId),
|
|
1226
|
+
operationInvocationId: invocation.invocationId
|
|
1227
|
+
}
|
|
1228
|
+
);
|
|
1229
|
+
observeSessionOperationOutput({
|
|
1230
|
+
capabilities,
|
|
1231
|
+
providerKey,
|
|
1232
|
+
output,
|
|
1233
|
+
state: observationState,
|
|
1234
|
+
contextUsageState,
|
|
1235
|
+
interactionState
|
|
1236
|
+
});
|
|
1237
|
+
await operationInput.onOutput?.(output);
|
|
1238
|
+
},
|
|
1239
|
+
validate: (candidate) => {
|
|
1240
|
+
const result2 = validateAgentOperationResultTransition({
|
|
1241
|
+
providerKey,
|
|
1242
|
+
candidate: validateAgentOperationResultForInvocation(
|
|
1243
|
+
providerKey,
|
|
1244
|
+
descriptor,
|
|
1245
|
+
invocation,
|
|
1246
|
+
candidate
|
|
1247
|
+
),
|
|
1248
|
+
previous: interactionState.operationResults.get(
|
|
1249
|
+
invocation.invocationId
|
|
1250
|
+
)
|
|
1251
|
+
});
|
|
1252
|
+
interactionState.operationResults.set(
|
|
1253
|
+
result2.invocationId,
|
|
1254
|
+
result2
|
|
1255
|
+
);
|
|
1256
|
+
return result2;
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
trackedInvocation.result = result;
|
|
1260
|
+
return result;
|
|
1261
|
+
} catch (error) {
|
|
1262
|
+
if (!(error instanceof AgentProviderDelegatedOperationError)) {
|
|
1263
|
+
interactionState.operationInvocations.delete(
|
|
1264
|
+
invocation.invocationId
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
throw error;
|
|
1268
|
+
} finally {
|
|
1269
|
+
if (reservation !== void 0) validationOwner.releaseExecution(reservation);
|
|
1270
|
+
}
|
|
1271
|
+
} finally {
|
|
1272
|
+
settle();
|
|
1187
1273
|
}
|
|
1188
1274
|
}
|
|
1189
1275
|
});
|
|
@@ -1442,7 +1528,7 @@ function validateAgentProviderSession(input) {
|
|
|
1442
1528
|
validationOwner.stop();
|
|
1443
1529
|
input.hostBindingLease?.stop();
|
|
1444
1530
|
const closingTurn = validationOwner.activeTurn;
|
|
1445
|
-
closingTurn?.owner.stop(new DOMException("The provider session was closed.", "AbortError"));
|
|
1531
|
+
closingTurn?.owner.stop(new DOMException("The provider session was closed.", "AbortError"), "closed");
|
|
1446
1532
|
const cleanup = async () => {
|
|
1447
1533
|
if (!providerClosed) {
|
|
1448
1534
|
await input.candidate.close(closeInput);
|
|
@@ -1450,6 +1536,7 @@ function validateAgentProviderSession(input) {
|
|
|
1450
1536
|
}
|
|
1451
1537
|
await input.sessionInteractionOwner?.join();
|
|
1452
1538
|
await closingTurn?.owner.join();
|
|
1539
|
+
await validationOwner.sessionAdmission.joinOperations();
|
|
1453
1540
|
await input.hostBindingLease?.release();
|
|
1454
1541
|
validationOwner.completeClose();
|
|
1455
1542
|
};
|
|
@@ -1609,6 +1696,7 @@ async function openIdentityCreatingAgentProviderSession(input) {
|
|
|
1609
1696
|
}
|
|
1610
1697
|
}
|
|
1611
1698
|
export {
|
|
1699
|
+
assertAgentTurnInputCapability,
|
|
1612
1700
|
closeRejectedAgentProviderSession,
|
|
1613
1701
|
createAgentSessionValidationOwner,
|
|
1614
1702
|
openIdentityCreatingAgentProviderSession,
|