@agen-ai/agent-runtime 0.4.3 → 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.
Files changed (56) hide show
  1. package/README.md +297 -10
  2. package/dist/adapterValidation.js +38 -4
  3. package/dist/contractErrors.d.ts +2 -2
  4. package/dist/contractErrors.js +8 -1
  5. package/dist/executionInput/index.d.ts +3 -0
  6. package/dist/executionInput/index.js +4 -0
  7. package/dist/executionInput/lifetime.d.ts +47 -0
  8. package/dist/executionInput/lifetime.js +241 -0
  9. package/dist/executionInput/types.d.ts +61 -0
  10. package/dist/executionInput/types.js +0 -0
  11. package/dist/executionInput/validation.d.ts +25 -0
  12. package/dist/executionInput/validation.js +178 -0
  13. package/dist/generation/cleanup.d.ts +15 -0
  14. package/dist/generation/cleanup.js +108 -0
  15. package/dist/generation/deadline.d.ts +16 -0
  16. package/dist/generation/deadline.js +81 -0
  17. package/dist/generation/decoding.d.ts +4 -0
  18. package/dist/generation/decoding.js +59 -0
  19. package/dist/generation/errors.d.ts +29 -0
  20. package/dist/generation/errors.js +39 -0
  21. package/dist/generation/generateObject.d.ts +3 -0
  22. package/dist/generation/generateObject.js +148 -0
  23. package/dist/generation/index.d.ts +5 -0
  24. package/dist/generation/index.js +8 -0
  25. package/dist/generation/preflight.d.ts +25 -0
  26. package/dist/generation/preflight.js +48 -0
  27. package/dist/generation/requests.d.ts +17 -0
  28. package/dist/generation/requests.js +117 -0
  29. package/dist/generation/types.d.ts +22 -0
  30. package/dist/generation/types.js +0 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.js +7 -1
  33. package/dist/nativeContinuations/admission.js +1 -0
  34. package/dist/outputValidation.d.ts +2 -0
  35. package/dist/outputValidation.js +29 -1
  36. package/dist/sessionInteractions/lifetime.d.ts +1 -0
  37. package/dist/sessionInteractions/lifetime.js +4 -0
  38. package/dist/sessionInteractions/request.d.ts +1 -0
  39. package/dist/sessionInteractions/request.js +3 -0
  40. package/dist/sessionValidation.d.ts +13 -3
  41. package/dist/sessionValidation.js +80 -6
  42. package/dist/sessions.d.ts +7 -1
  43. package/dist/structuredOutput/admission.d.ts +16 -0
  44. package/dist/structuredOutput/admission.js +89 -0
  45. package/dist/structuredOutput/candidate.d.ts +22 -0
  46. package/dist/structuredOutput/candidate.js +64 -0
  47. package/dist/structuredOutput/validation.d.ts +8 -0
  48. package/dist/structuredOutput/validation.js +26 -0
  49. package/dist/testing/conformance.d.ts +20 -1
  50. package/dist/testing/conformance.js +103 -3
  51. package/dist/testing/fakeProvider.js +5 -4
  52. package/dist/turnExecution/execution.d.ts +9 -1
  53. package/dist/turnExecution/execution.js +88 -7
  54. package/dist/turnExecution/terminalBuffer.d.ts +9 -0
  55. package/dist/turnExecution/terminalBuffer.js +38 -0
  56. 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;
@@ -1,10 +1,14 @@
1
1
  import {
2
- parseAgentError
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) {
@@ -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,7 +49,12 @@ interface ActiveAgentTurn {
47
49
  readonly inFlightOperations: Set<Promise<void>>;
48
50
  readonly owner: ValidatedAgentTurnExecution;
49
51
  }
50
- export declare function createAgentSessionValidationOwner(capabilities: AgentCapabilities, sessionId: AgentSessionId): {
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: {
52
59
  trackOperation(): () => void;
53
60
  joinOperations(): Promise<void>;
@@ -71,11 +78,14 @@ export declare function createAgentSessionValidationOwner(capabilities: AgentCap
71
78
  stop(): void;
72
79
  completeClose(): void;
73
80
  installClose(close: () => Promise<void>): void;
81
+ installInputContextGuard(guard: () => void): void;
74
82
  reserveExecution: () => object;
75
83
  ownsExecution: (token: object) => boolean;
76
84
  releaseExecution: (token: object) => void;
85
+ admitTurnOutput(output: unknown, hasOutput: boolean): AgentStructuredOutputBinding | undefined;
86
+ requireNativeContinuationSupport: () => void;
77
87
  installNativeExecution(token: object, turnId: AgentTurnId, createCandidate: (signal: AbortSignal) => AgentProviderTurnExecution): AdoptedAgentTurnExecution;
78
- installCallerExecution(token: object, turnInput: AgentProviderStartTurnInput, start: (input: AgentProviderStartTurnInput) => AgentProviderTurnExecution): ValidatedAgentTurnExecution;
88
+ installCallerExecution(token: object, turnInput: AgentProviderStartTurnInput, start: (input: AgentProviderStartTurnInput) => AgentProviderTurnExecution, binding?: AgentStructuredOutputBinding): ValidatedAgentTurnExecution;
79
89
  };
80
90
  export type AgentSessionValidationOwner = ReturnType<typeof createAgentSessionValidationOwner>;
81
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.");
@@ -620,7 +624,7 @@ function assertAgentTurnInputCapability(input) {
620
624
  });
621
625
  if (textIssue) rejectReference(`${textIssue.target} must use ${textIssue.format} text`);
622
626
  }
623
- function createAgentSessionValidationOwner(capabilities, sessionId) {
627
+ function createAgentSessionValidationOwner(capabilities, sessionId, structuredOutputBinding, executionInputSupport) {
624
628
  const providerKey = capabilities.providerKey;
625
629
  const sessionLifetime = new AbortController();
626
630
  const sessionAdmission = createAgentSessionAdmission(providerKey);
@@ -639,6 +643,15 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
639
643
  let closed = false;
640
644
  let unusable = false;
641
645
  let closing;
646
+ let requireInputContext = () => {
647
+ };
648
+ const executionInputCensus = createExecutionInputCensus(providerKey, () => {
649
+ unusable = true;
650
+ queueMicrotask(() => {
651
+ void closing?.().catch(() => {
652
+ });
653
+ });
654
+ });
642
655
  const requireOpen = () => {
643
656
  if (closed)
644
657
  throwAgentProviderContractError(
@@ -677,6 +690,11 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
677
690
  const inFlightOperations = /* @__PURE__ */ new Set();
678
691
  const common = {
679
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,
680
698
  pendingRequests,
681
699
  sessionAdmission,
682
700
  inFlightOperations,
@@ -684,7 +702,10 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
684
702
  isTerminal: () => state.terminal,
685
703
  canRestoreRequest: (pending) => hasLiveApprovalSubject(pending.request, state),
686
704
  observe(candidate, requests) {
687
- const output = validateAgentProviderOutputForContext(candidate, outputContext(turnId));
705
+ const output = validateAgentProviderOutputForContext(candidate, {
706
+ ...outputContext(turnId),
707
+ ...source.kind !== "caller" || source.binding === void 0 ? {} : { structuredOutputBinding: source.binding }
708
+ });
688
709
  observeTurnOutput({
689
710
  capabilities,
690
711
  providerKey,
@@ -719,6 +740,15 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
719
740
  }
720
741
  return owner;
721
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
+ };
722
752
  return {
723
753
  sessionAdmission,
724
754
  sessionLifetime,
@@ -749,14 +779,38 @@ function createAgentSessionValidationOwner(capabilities, sessionId) {
749
779
  installClose(close) {
750
780
  closing = close;
751
781
  },
782
+ installInputContextGuard(guard) {
783
+ requireInputContext = guard;
784
+ },
752
785
  reserveExecution: sessionAdmission.reserveExecution,
753
786
  ownsExecution: sessionAdmission.ownsExecution,
754
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,
755
803
  installNativeExecution(token, turnId, createCandidate) {
804
+ requireNativeContinuationSupport();
756
805
  return installExecution(token, turnId, { kind: "native", createCandidate });
757
806
  },
758
- installCallerExecution(token, turnInput, start) {
759
- return installExecution(token, turnInput.turnId, { kind: "caller", input: turnInput, start });
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
+ });
760
814
  }
761
815
  };
762
816
  }
@@ -796,6 +850,14 @@ function validateAgentProviderSession(input) {
796
850
  }
797
851
  validateSessionPorts(capabilities, input.candidate);
798
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
+ });
799
861
  const { sessionLifetime, contextUsageState, interactionState, outputContext } = validationOwner;
800
862
  const collaborationNodes = interactionState.collaborationNodes;
801
863
  const collaborationSpawnReservations = interactionState.collaborationSpawnReservations;
@@ -862,6 +924,7 @@ function validateAgentProviderSession(input) {
862
924
  turnId: turnInput.turnId,
863
925
  interactionMode: turnInput.interactionMode,
864
926
  parts: turnInput.parts,
927
+ ...turnInput.output === void 0 ? {} : { output: turnInput.output },
865
928
  ...turnInput.summary === void 0 ? {} : { summary: turnInput.summary },
866
929
  ...turnInput.deadlineAt === void 0 ? {} : { deadlineAt: turnInput.deadlineAt }
867
930
  });
@@ -873,13 +936,15 @@ function validateAgentProviderSession(input) {
873
936
  `Provider ${providerKey} does not support ${parsedInput.interactionMode} turn interaction mode.`
874
937
  );
875
938
  }
939
+ const binding2 = validationOwner.admitTurnOutput(parsedInput.output, Reflect.has(turnInput, "output"));
876
940
  const token = validationOwner.reserveExecution();
877
941
  try {
878
942
  return validationOwner.installCallerExecution(token, {
879
943
  ...parsedInput,
944
+ ...parsedInput.output === void 0 || binding2 === void 0 ? {} : { output: binding2.request },
880
945
  ...turnInput.signal === void 0 ? {} : { signal: turnInput.signal },
881
946
  ...turnInput.onProviderExecutionStarted === void 0 ? {} : { onProviderExecutionStarted: turnInput.onProviderExecutionStarted }
882
- }, (inputTurn) => input.candidate.startTurn(inputTurn)).execution;
947
+ }, (inputTurn) => input.candidate.startTurn(inputTurn), binding2).execution;
883
948
  } catch (error) {
884
949
  validationOwner.releaseExecution(token);
885
950
  throw error;
@@ -908,6 +973,7 @@ function validateAgentProviderSession(input) {
908
973
  const settleActiveInterruption = trackActiveTurnOperation(
909
974
  targetedActiveTurn
910
975
  );
976
+ targetedTurn.owner.closeInputAdmission();
911
977
  try {
912
978
  const suspendedRequests = targetedTurn.owner.suspendRequests();
913
979
  let result;
@@ -939,6 +1005,13 @@ function validateAgentProviderSession(input) {
939
1005
  steerTurn: async (steeringInput) => {
940
1006
  requireUsable();
941
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
+ }
942
1015
  const turnId = parseAgentTurnId(steeringInput.turnId);
943
1016
  if (validationOwner.activeTurn?.turnId !== turnId || !validationOwner.activeTurn.owner.hasEntered() || validationOwner.activeTurn.state.terminal || validationOwner.activeTurn.pendingRequests.size > 0) {
944
1017
  throwAgentProviderContractError(
@@ -1455,7 +1528,7 @@ function validateAgentProviderSession(input) {
1455
1528
  validationOwner.stop();
1456
1529
  input.hostBindingLease?.stop();
1457
1530
  const closingTurn = validationOwner.activeTurn;
1458
- closingTurn?.owner.stop(new DOMException("The provider session was closed.", "AbortError"));
1531
+ closingTurn?.owner.stop(new DOMException("The provider session was closed.", "AbortError"), "closed");
1459
1532
  const cleanup = async () => {
1460
1533
  if (!providerClosed) {
1461
1534
  await input.candidate.close(closeInput);
@@ -1623,6 +1696,7 @@ async function openIdentityCreatingAgentProviderSession(input) {
1623
1696
  }
1624
1697
  }
1625
1698
  export {
1699
+ assertAgentTurnInputCapability,
1626
1700
  closeRejectedAgentProviderSession,
1627
1701
  createAgentSessionValidationOwner,
1628
1702
  openIdentityCreatingAgentProviderSession,
@@ -1,4 +1,4 @@
1
- import type { AgentAuthenticationFlow, AgentCollaborationControlInput, AgentCollaborationNode, AgentCollaborationSpawnInput, AgentConfigurationCatalog, AgentConfigurationSelectionInput, AgentError, AgentGeneratedResourceDescriptor, AgentGeneratedResourceId, AgentManagedContentCatalog, AgentOperationCatalog, AgentOperationInvocation, AgentOperationResult, AgentRequestResolution, AgentSessionBinding, AgentSessionBranchSource, AgentSessionConfiguration, AgentSessionId, AgentTurnId, AgentTurnInputContent, AgentTurnInteractionMode, AgentTurnInputPart, AgentTurnInterruptionReason } from "@agen-ai/agent-protocol";
1
+ import type { AgentAuthenticationFlow, AgentCollaborationControlInput, AgentCollaborationNode, AgentCollaborationSpawnInput, AgentConfigurationCatalog, AgentConfigurationSelectionInput, AgentError, AgentGeneratedResourceDescriptor, AgentGeneratedResourceId, AgentManagedContentCatalog, AgentOperationCatalog, AgentOperationInvocation, AgentOperationResult, AgentRequestResolution, AgentSessionBinding, AgentSessionBranchSource, AgentSessionConfiguration, AgentSessionId, AgentStructuredOutputRequest, AgentTurnId, AgentTurnInputContent, AgentTurnInteractionMode, AgentTurnInputPart, AgentTurnInterruptionReason } from "@agen-ai/agent-protocol";
2
2
  import type { AgentNativeContinuationContext, AgentNativeContinuationSupport } from "./nativeContinuations/types.js";
3
3
  import type { MaybePromise } from "./foundation.js";
4
4
  import type { AgentSessionHostBinding, AgentSessionHostBindingSupport } from "./hostBindings/types.js";
@@ -6,6 +6,7 @@ import type { AgentProviderOutput } from "./outputs.js";
6
6
  import type { AgentArtifactCandidate } from "./artifacts.js";
7
7
  import type { AgentProviderSessionInteractionContext, AgentSessionInteractionContext, AgentSessionInteractionSupport } from "./sessionInteractions/types.js";
8
8
  import type { AgentEnvironmentObservationPort } from "./environment/types.js";
9
+ import type { AgentExecutionInput, AgentExecutionInputSupport } from "./executionInput/types.js";
9
10
  export interface AgentProviderSessionContext {
10
11
  readonly sessionId: AgentSessionId;
11
12
  readonly workingDirectory: string;
@@ -17,6 +18,7 @@ export interface AgentProviderSessionContext {
17
18
  export type AgentSessionBindingCreatedObserver = (binding: AgentSessionBinding) => void;
18
19
  export interface AgentProviderCreateSessionInput extends AgentProviderSessionContext {
19
20
  readonly onBindingCreated: AgentSessionBindingCreatedObserver;
21
+ readonly output?: AgentStructuredOutputRequest;
20
22
  }
21
23
  export interface AgentProviderResumeSessionInput extends AgentProviderSessionContext {
22
24
  readonly binding: AgentSessionBinding;
@@ -33,6 +35,7 @@ export interface AgentProviderStartTurnInput {
33
35
  readonly parts: readonly AgentTurnInputPart[];
34
36
  readonly summary?: string;
35
37
  readonly deadlineAt?: string;
38
+ readonly output?: AgentStructuredOutputRequest;
36
39
  readonly signal?: AbortSignal;
37
40
  readonly onProviderExecutionStarted?: AgentProviderExecutionStartedObserver;
38
41
  }
@@ -55,6 +58,7 @@ export type AgentRequestResolutionResult = Readonly<{
55
58
  export interface AgentProviderTurnExecution {
56
59
  readonly turnId: AgentTurnId;
57
60
  readonly outputs: AsyncIterable<AgentProviderOutput>;
61
+ readonly input?: AgentExecutionInput;
58
62
  readonly resolveRequest: (input: AgentProviderResolveRequestInput) => Promise<AgentRequestResolutionResult>;
59
63
  }
60
64
  export interface AgentProviderInterruptTurnInput {
@@ -215,6 +219,7 @@ export type AgentProviderAuthentication = Readonly<{
215
219
  cancel: (input: AgentProviderAuthenticationCancelInput) => MaybePromise<AgentProviderOperationResult>;
216
220
  }>;
217
221
  export interface AgentProviderAdapter {
222
+ readonly executionInput?: AgentExecutionInputSupport;
218
223
  readonly sessionInteractions?: AgentSessionInteractionSupport;
219
224
  readonly hostBinding?: AgentSessionHostBindingSupport;
220
225
  readonly nativeContinuations?: AgentNativeContinuationSupport;
@@ -229,6 +234,7 @@ export type AgentSessionOpenContext = Omit<AgentProviderSessionContext, "interac
229
234
  }>;
230
235
  export type AgentCreateSessionInput = AgentSessionOpenContext & Readonly<{
231
236
  onBindingCreated: AgentSessionBindingCreatedObserver;
237
+ output?: AgentStructuredOutputRequest;
232
238
  }>;
233
239
  export type AgentResumeSessionInput = AgentSessionOpenContext & Readonly<{
234
240
  binding: AgentSessionBinding;
@@ -0,0 +1,16 @@
1
+ import { type AgentCapabilities, type AgentStructuredOutputRequest } from "@agen-ai/agent-protocol";
2
+ export interface AgentStructuredOutputBinding {
3
+ readonly request: AgentStructuredOutputRequest;
4
+ readonly maxOutputBytes: number;
5
+ }
6
+ export declare function admitAgentStructuredOutputOpening(input: Readonly<{
7
+ capabilities: AgentCapabilities;
8
+ operation: "create" | "resume" | "branch";
9
+ output: unknown;
10
+ }>): AgentStructuredOutputBinding | undefined;
11
+ export declare function admitAgentStructuredOutputTurn(input: Readonly<{
12
+ capabilities: AgentCapabilities;
13
+ binding?: AgentStructuredOutputBinding;
14
+ output: unknown;
15
+ }>): AgentStructuredOutputBinding | undefined;
16
+ //# sourceMappingURL=admission.d.ts.map
@@ -0,0 +1,89 @@
1
+ import {
2
+ AgentProtocolValidationError,
3
+ agentProtocolSerializedJsonBytes,
4
+ parseAgentOutputSchema
5
+ } from "@agen-ai/agent-protocol";
6
+ import { throwAgentProviderContractError } from "../contractErrors.js";
7
+ import { hasExactOwnKeys } from "../internal/objectShape.js";
8
+ function parseOutputRequest(input, maxOutputBytes) {
9
+ const invalid = () => {
10
+ throw new AgentProtocolValidationError([{
11
+ code: "invalid_structured_output_request",
12
+ message: "Structured output must be a plain json_schema request with only kind and schema data properties.",
13
+ path: ["output"]
14
+ }]);
15
+ };
16
+ if (input === null || typeof input !== "object") return invalid();
17
+ let kind;
18
+ let schema;
19
+ try {
20
+ const prototype = Object.getPrototypeOf(input);
21
+ if (prototype !== Object.prototype && prototype !== null || !hasExactOwnKeys(input, ["kind", "schema"])) return invalid();
22
+ const kindDescriptor = Object.getOwnPropertyDescriptor(input, "kind");
23
+ const schemaDescriptor = Object.getOwnPropertyDescriptor(input, "schema");
24
+ if (!kindDescriptor || !("value" in kindDescriptor) || !kindDescriptor.enumerable || !schemaDescriptor || !("value" in schemaDescriptor) || !schemaDescriptor.enumerable) return invalid();
25
+ kind = kindDescriptor.value;
26
+ schema = schemaDescriptor.value;
27
+ } catch (error) {
28
+ if (error instanceof AgentProtocolValidationError) throw error;
29
+ return invalid();
30
+ }
31
+ if (kind !== "json_schema") return invalid();
32
+ return Object.freeze({ kind, schema: parseAgentOutputSchema(schema, { maxOutputBytes }) });
33
+ }
34
+ function admitRequest(capabilities, output) {
35
+ const capability = capabilities.turns.structuredOutput;
36
+ if (capability.kind === "unsupported") {
37
+ throwAgentProviderContractError(
38
+ capabilities.providerKey,
39
+ "structured_output_unsupported",
40
+ "Provider does not support structured output."
41
+ );
42
+ }
43
+ const request = parseOutputRequest(output, capability.maxOutputBytes);
44
+ if (agentProtocolSerializedJsonBytes(request.schema) > capability.maxSchemaBytes) {
45
+ throwAgentProviderContractError(
46
+ capabilities.providerKey,
47
+ "invalid_structured_output",
48
+ "Structured output schema exceeds the provider's advertised byte limit."
49
+ );
50
+ }
51
+ return Object.freeze({ request, maxOutputBytes: capability.maxOutputBytes });
52
+ }
53
+ function admitAgentStructuredOutputOpening(input) {
54
+ if (input.output === void 0) return void 0;
55
+ const { capabilities } = input;
56
+ if (input.operation !== "create") {
57
+ throwAgentProviderContractError(
58
+ capabilities.providerKey,
59
+ "structured_output_unsupported",
60
+ "Structured output cannot be restored through resume or branch."
61
+ );
62
+ }
63
+ const capability = capabilities.turns.structuredOutput;
64
+ if (capability.kind === "supported" && capability.scope !== "session") {
65
+ throwAgentProviderContractError(
66
+ capabilities.providerKey,
67
+ "structured_output_scope_mismatch",
68
+ "Provider accepts structured output only when starting a turn."
69
+ );
70
+ }
71
+ return admitRequest(capabilities, input.output);
72
+ }
73
+ function admitAgentStructuredOutputTurn(input) {
74
+ if (input.output === void 0) return input.binding;
75
+ const { capabilities } = input;
76
+ const capability = capabilities.turns.structuredOutput;
77
+ if (input.binding || capability.kind === "supported" && capability.scope !== "turn") {
78
+ throwAgentProviderContractError(
79
+ capabilities.providerKey,
80
+ "structured_output_scope_mismatch",
81
+ "Session-scoped structured output cannot be overridden or supplied on a turn."
82
+ );
83
+ }
84
+ return admitRequest(capabilities, input.output);
85
+ }
86
+ export {
87
+ admitAgentStructuredOutputOpening,
88
+ admitAgentStructuredOutputTurn
89
+ };
@@ -0,0 +1,22 @@
1
+ import { type AgentOutputSchema, type AgentStructuredOutputResult, type AgentStructuredOutputUnavailableReason } from "@agen-ai/agent-protocol";
2
+ export type AgentStructuredOutputCandidate = Readonly<{
3
+ kind: "json_text";
4
+ text: string;
5
+ }> | Readonly<{
6
+ kind: "json_value";
7
+ value: unknown;
8
+ }> | Readonly<{
9
+ kind: "unavailable";
10
+ reason: AgentStructuredOutputUnavailableReason;
11
+ }>;
12
+ export interface CreateAgentStructuredOutputCandidateInput {
13
+ readonly schema: AgentOutputSchema;
14
+ readonly maxOutputBytes?: number;
15
+ readonly candidate: AgentStructuredOutputCandidate;
16
+ }
17
+ export type AgentStructuredOutputCandidateResult = Exclude<AgentStructuredOutputResult, Readonly<{
18
+ kind: "not_requested";
19
+ }>>;
20
+ export declare function validateAgentStructuredOutputCandidate(schema: AgentOutputSchema, value: unknown, maxOutputBytes: number): AgentStructuredOutputCandidateResult;
21
+ export declare function createAgentStructuredOutputCandidate(input: CreateAgentStructuredOutputCandidateInput): AgentStructuredOutputCandidateResult;
22
+ //# sourceMappingURL=candidate.d.ts.map
@@ -0,0 +1,64 @@
1
+ import {
2
+ AGENT_OUTPUT_RAW_JSON_BYTES_LIMIT,
3
+ AGENT_OUTPUT_VALUE_BYTES_LIMIT,
4
+ AGENT_STRUCTURED_OUTPUT_UNAVAILABLE_REASONS,
5
+ parseAgentOutputSchema,
6
+ validateAgentOutputValue
7
+ } from "@agen-ai/agent-protocol";
8
+ function freezeJson(value) {
9
+ if (value === null || typeof value !== "object") return;
10
+ for (const child of Object.values(value)) freezeJson(child);
11
+ Object.freeze(value);
12
+ }
13
+ function validateAgentStructuredOutputCandidate(schema, value, maxOutputBytes) {
14
+ const parsed = validateAgentOutputValue(schema, value, { maxOutputBytes });
15
+ if (!parsed.success) {
16
+ if (parsed.issues.some((issue) => issue.code === "output_limit_exceeded")) {
17
+ return Object.freeze({ kind: "unavailable", reason: "output_limit_exceeded" });
18
+ }
19
+ if (parsed.issues.some((issue) => issue.code === "invalid_json_data")) {
20
+ return Object.freeze({ kind: "unavailable", reason: "invalid_json" });
21
+ }
22
+ return Object.freeze({ kind: "unavailable", reason: "schema_mismatch", issues: Object.freeze(parsed.issues.map((issue) => Object.freeze({
23
+ ...issue,
24
+ path: Object.freeze([...issue.path])
25
+ }))) });
26
+ }
27
+ freezeJson(parsed.data);
28
+ return Object.freeze({ kind: "json", value: parsed.data });
29
+ }
30
+ function createAgentStructuredOutputCandidate(input) {
31
+ const schema = parseAgentOutputSchema(input.schema);
32
+ const maxOutputBytes = input.maxOutputBytes ?? AGENT_OUTPUT_VALUE_BYTES_LIMIT;
33
+ if (!Number.isSafeInteger(maxOutputBytes) || maxOutputBytes <= 0 || maxOutputBytes > AGENT_OUTPUT_VALUE_BYTES_LIMIT) {
34
+ throw new RangeError("Structured output byte limit must be a positive integer within the portable profile ceiling.");
35
+ }
36
+ const { candidate } = input;
37
+ switch (candidate.kind) {
38
+ case "unavailable":
39
+ if (!AGENT_STRUCTURED_OUTPUT_UNAVAILABLE_REASONS.includes(candidate.reason)) {
40
+ throw new TypeError("Structured output candidate has an unsupported unavailable reason.");
41
+ }
42
+ return Object.freeze({ kind: "unavailable", reason: candidate.reason });
43
+ case "json_text": {
44
+ if (typeof candidate.text !== "string") throw new TypeError("Structured JSON text candidate must contain a string.");
45
+ if (candidate.text.length > AGENT_OUTPUT_RAW_JSON_BYTES_LIMIT || Buffer.byteLength(candidate.text, "utf8") > AGENT_OUTPUT_RAW_JSON_BYTES_LIMIT) {
46
+ return Object.freeze({ kind: "unavailable", reason: "output_limit_exceeded" });
47
+ }
48
+ let value;
49
+ try {
50
+ value = JSON.parse(candidate.text);
51
+ } catch {
52
+ return Object.freeze({ kind: "unavailable", reason: "invalid_json" });
53
+ }
54
+ return validateAgentStructuredOutputCandidate(schema, value, maxOutputBytes);
55
+ }
56
+ case "json_value":
57
+ return validateAgentStructuredOutputCandidate(schema, candidate.value, maxOutputBytes);
58
+ }
59
+ throw new TypeError("Structured output candidate kind is unsupported.");
60
+ }
61
+ export {
62
+ createAgentStructuredOutputCandidate,
63
+ validateAgentStructuredOutputCandidate
64
+ };
@@ -0,0 +1,8 @@
1
+ import type { AgentProviderKey, AgentStructuredOutputResult } from "@agen-ai/agent-protocol";
2
+ import type { AgentStructuredOutputBinding } from "./admission.js";
3
+ export declare function validateAgentStructuredOutputResult(input: Readonly<{
4
+ providerKey: AgentProviderKey;
5
+ binding?: AgentStructuredOutputBinding;
6
+ result: AgentStructuredOutputResult;
7
+ }>): AgentStructuredOutputResult;
8
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1,26 @@
1
+ import { throwAgentProviderContractError } from "../contractErrors.js";
2
+ import { validateAgentStructuredOutputCandidate } from "./candidate.js";
3
+ function validateAgentStructuredOutputResult(input) {
4
+ const { binding, result } = input;
5
+ if (!binding) {
6
+ if (result.kind !== "not_requested") {
7
+ throwAgentProviderContractError(
8
+ input.providerKey,
9
+ "invalid_structured_output",
10
+ "Provider reported structured output for a turn without an admitted schema."
11
+ );
12
+ }
13
+ return result;
14
+ }
15
+ if (result.kind === "not_requested") {
16
+ throwAgentProviderContractError(
17
+ input.providerKey,
18
+ "invalid_structured_output",
19
+ "Provider omitted the admitted structured-output contract."
20
+ );
21
+ }
22
+ return result.kind === "json" ? validateAgentStructuredOutputCandidate(binding.request.schema, result.value, binding.maxOutputBytes) : result;
23
+ }
24
+ export {
25
+ validateAgentStructuredOutputResult
26
+ };