@agen-ai/agent-runtime 0.1.0

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/dist/adapterValidation.d.ts +4 -0
  4. package/dist/adapterValidation.js +242 -0
  5. package/dist/artifacts.d.ts +28 -0
  6. package/dist/artifacts.js +87 -0
  7. package/dist/configurationValidation.d.ts +3 -0
  8. package/dist/configurationValidation.js +35 -0
  9. package/dist/contractErrors.d.ts +17 -0
  10. package/dist/contractErrors.js +59 -0
  11. package/dist/evidence.d.ts +50 -0
  12. package/dist/evidence.js +368 -0
  13. package/dist/foundation.d.ts +8 -0
  14. package/dist/foundation.js +37 -0
  15. package/dist/index.d.ts +13 -0
  16. package/dist/index.js +12 -0
  17. package/dist/internal/controlCharacters.d.ts +2 -0
  18. package/dist/internal/controlCharacters.js +7 -0
  19. package/dist/internal/serializedJsonBytes.d.ts +3 -0
  20. package/dist/internal/serializedJsonBytes.js +57 -0
  21. package/dist/outputValidation.d.ts +13 -0
  22. package/dist/outputValidation.js +174 -0
  23. package/dist/outputs.d.ts +81 -0
  24. package/dist/outputs.js +217 -0
  25. package/dist/providerCatalog.d.ts +13 -0
  26. package/dist/providerCatalog.js +33 -0
  27. package/dist/providerDriver.d.ts +41 -0
  28. package/dist/providerDriver.js +52 -0
  29. package/dist/providerInstanceRegistry.d.ts +40 -0
  30. package/dist/providerInstanceRegistry.js +322 -0
  31. package/dist/readiness.d.ts +22 -0
  32. package/dist/readiness.js +58 -0
  33. package/dist/sessionValidation.d.ts +19 -0
  34. package/dist/sessionValidation.js +767 -0
  35. package/dist/sessions.d.ts +133 -0
  36. package/dist/sessions.js +0 -0
  37. package/dist/steeringValidation.d.ts +4 -0
  38. package/dist/steeringValidation.js +36 -0
  39. package/dist/testing/conformance.d.ts +30 -0
  40. package/dist/testing/conformance.js +379 -0
  41. package/dist/testing/fakeProvider.d.ts +35 -0
  42. package/dist/testing/fakeProvider.js +367 -0
  43. package/dist/testing/index.d.ts +3 -0
  44. package/dist/testing/index.js +2 -0
  45. package/dist/text.d.ts +2 -0
  46. package/dist/text.js +16 -0
  47. package/package.json +62 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Trevor Nichols
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # `@agen-ai/agent-runtime`
2
+
3
+ `@agen-ai/agent-runtime` is the process-local service-provider interface for coding-agent
4
+ implementations. It preserves a small ownership chain: a driver parses host configuration and
5
+ materializes an instance; the instance owns one opaque ID, technical capabilities, an adapter,
6
+ readiness, and disposal; the adapter opens provider-native sessions; each returned session owns
7
+ its binding and conversation-local operations.
8
+
9
+ The runtime depends only on `@agen-ai/agent-protocol`. It has no concept of tenants, SaaS
10
+ workspaces, assigned users, database rows, persistence sequence, visibility, billing, host boots,
11
+ leases, or storage policy. A host must authorize and select an instance before calling this SPI.
12
+
13
+ ## Entrypoints
14
+
15
+ - `@agen-ai/agent-runtime` exports the public driver, instance, adapter, session, output,
16
+ readiness, bounded-evidence, artifact-candidate, and registry APIs.
17
+ - `@agen-ai/agent-runtime/testing` exports the deterministic fake provider and reusable
18
+ conformance runner.
19
+
20
+ ## Lifecycle and ownership
21
+
22
+ 1. Define an `AgentProviderDriver` with `defineAgentProviderDriver`.
23
+ 2. Give caller-owned instance definitions to `createAgentProviderRegistry`.
24
+ 3. Select a materialized instance by opaque `instanceId`.
25
+ 4. Create, resume, or branch a provider session through its adapter.
26
+ 5. Consume each `runTurn` or `resolveRequest` output stream incrementally. Neutral `AgentEvent`
27
+ output carries bounded provider source evidence atomically. A `request.opened` output may also
28
+ carry separately bounded, non-truncated provider request context for continuation; lifecycle,
29
+ authentication, artifact, and standalone diagnostic evidence remain separate output variants.
30
+ Evidence reports an exact truncation reason. `originalDataBytes` is `null` when a structural
31
+ collection, depth, object-key, cycle, accessor, unsupported-value, or inspectability constraint
32
+ prevents honest measurement of the original provider payload.
33
+ 6. Close sessions idempotently, then dispose the instance or registry.
34
+
35
+ Instance IDs never repeat in session calls. `workingDirectory` is resolved by the host and is not
36
+ an authorization credential. Create and branch implementations must invoke `onBindingCreated`
37
+ exactly once before returning the matching session. Capability-dependent operations use explicit
38
+ `supported`/`unsupported` discriminants, and the runtime rejects handlers that disagree with the
39
+ instance capability declaration.
40
+
41
+ The host should serialize mutating operations for a given session. Separate session objects may
42
+ run concurrently, so provider implementations must isolate their conversation-local state.
43
+ `runTurn` and `resolveRequest` both preserve consumer backpressure: the provider does not resume
44
+ until the consumer requests the next output. Each stream must end at a completed turn or exactly
45
+ one newly pending request. If a consumer abandons a stream, a provider throws, or either stream
46
+ ends before that stable boundary, the validated session becomes unusable and must be closed rather
47
+ than retried. The validated `runTurn` input may observe `onProviderExecutionStarted`; validation
48
+ invokes it exactly at candidate-port delegation, after runtime prechecks pass, and never forwards it
49
+ to the candidate adapter. A delegated mutating operation that throws or returns an invalid result
50
+ has the same effect. Pre-aborted operations fail with `AbortError`; close and disposal must be safe
51
+ to call repeatedly. An accepted interruption of an already-waiting turn does not prove that the
52
+ turn terminalized; unless the result also carries a terminal event, the validated session becomes
53
+ unusable and must be closed and rematerialized. A close failure makes the session unusable while
54
+ leaving close itself retryable.
55
+
56
+ When `capabilities.turns.steer` is true, the session exposes `steering.steerTurn`. Steering accepts
57
+ the existing turn ID plus the same canonical `parts` and optional `summary` used to start a turn.
58
+ It does not create or own an output stream: model output continues on the original `runTurn`
59
+ iterator. The receipt is exactly `delivered`, `rejected` with a bounded neutral error, or
60
+ `delivery_uncertain` with a bounded neutral error. A provider must use uncertainty when delivery
61
+ may have started but its authoritative acknowledgement was lost; callers cannot safely replay that
62
+ result. The validated runtime preserves pre-delegation validation and abort errors unchanged, while
63
+ provider-delegated steering failures throw `AgentProviderDelegatedOperationError` with the original
64
+ cause and explicit started-execution evidence so a host can retire the unusable session. Platform
65
+ scheduling and provider-native queue modes are intentionally outside this SPI.
66
+
67
+ ## Minimal driver
68
+
69
+ ```ts
70
+ import {
71
+ defineAgentProviderDriver,
72
+ type MaterializedAgentProviderInstance,
73
+ } from "@agen-ai/agent-runtime";
74
+ import {
75
+ parseAgentInstanceId,
76
+ parseAgentProviderKey,
77
+ } from "@agen-ai/agent-protocol";
78
+
79
+ const providerKey = parseAgentProviderKey("third-party-provider");
80
+
81
+ export const driver = defineAgentProviderDriver({
82
+ providerKey,
83
+ supportsMultipleInstances: true,
84
+ parseConfiguration(input) {
85
+ if (input === null || typeof input !== "object")
86
+ throw new TypeError("Invalid config.");
87
+ return input;
88
+ },
89
+ createInstance({ instanceId }): MaterializedAgentProviderInstance {
90
+ // Construct capabilities, adapter, readiness, and disposal here.
91
+ throw new Error(`Implement ${parseAgentInstanceId(instanceId)}.`);
92
+ },
93
+ });
94
+ ```
95
+
96
+ Use the `/testing` conformance runner for lifecycle, binding, turn-ordering, live steering and
97
+ interruption, interaction results, capability ports, cancellation, close, and disposal checks.
98
+ Registry publication and provider package discovery are intentionally outside this package.
99
+
100
+ ## Errors and cancellation
101
+
102
+ The runtime distinguishes programmer/contract failures from provider failures:
103
+
104
+ - `AgentProviderContractError` reports a stable `code` when an adapter contradicts its declared
105
+ capabilities, emits invalid output, violates turn/request ordering, or returns a mismatched
106
+ binding.
107
+ - `AgentProviderRegistryError` reports stable registry/materialization/disposal codes and retains
108
+ provider/instance correlation when available.
109
+ - `AgentProviderConfigurationError` wraps driver configuration rejection without exposing product
110
+ configuration policy.
111
+ - malformed primitive input may raise `TypeError` or `RangeError`; an aborted operation preserves
112
+ an `AbortError`-named reason.
113
+
114
+ Provider-native exceptions should be normalized or safely wrapped at the provider boundary. Do
115
+ not attach credentials, raw prompts, product identities, or unbounded output to public errors.
116
+
117
+ ## Conformance and release
118
+
119
+ Every external driver should run `runAgentProviderConformance` from
120
+ `@agen-ai/agent-runtime/testing`. The deterministic suite exercises duplicate-instance rejection,
121
+ instance identity, capabilities, readiness, create/resume/branch, binding callbacks, abort,
122
+ turn/request ordering, request resolution, steering, interruption, configuration, idempotent
123
+ close, and idempotent disposal. Unsupported operations must remain explicit discriminants and
124
+ must not expose handlers.
125
+
126
+ The package is at `0.1.0` while the public SPI is being proven with external adapters. Minor
127
+ releases may include breaking changes during this beta period, and those changes will be called out
128
+ in the release notes.
129
+
130
+ The current version tuple is Agent Protocol V6, private host V14/catalog V8, and Workspaces event V8.
131
+ The runtime package version remains independent of Agent Protocol V6.
132
+
133
+ Run the clean packed-consumer proof before any release:
134
+
135
+ From the public repository root, run `pnpm check`.
136
+
137
+ It installs tarballs into a temporary project outside the workspace, typechecks every documented
138
+ entrypoint, runs the fake provider and parser flow, and removes the temporary directory. It never
139
+ publishes or accesses release credentials.
@@ -0,0 +1,4 @@
1
+ import { type AgentCapabilities } from "@agen-ai/agent-protocol";
2
+ import type { AgentProviderAdapter } from "./sessions.js";
3
+ export declare function validateAgentProviderAdapter(capabilityInput: AgentCapabilities, adapter: AgentProviderAdapter): AgentProviderAdapter;
4
+ //# sourceMappingURL=adapterValidation.d.ts.map
@@ -0,0 +1,242 @@
1
+ import path from "node:path";
2
+ import {
3
+ parseAgentCapabilities,
4
+ parseAgentIsoDateTime,
5
+ parseAgentSessionOpenInput
6
+ } from "@agen-ai/agent-protocol";
7
+ import {
8
+ assertAgentSessionConfigurationSupported
9
+ } from "./configurationValidation.js";
10
+ import { throwAgentProviderContractError } from "./contractErrors.js";
11
+ import {
12
+ parseAgentProviderTechnicalId,
13
+ throwIfAgentOperationAborted
14
+ } from "./foundation.js";
15
+ import { containsAgentControlCharacter } from "./internal/controlCharacters.js";
16
+ import {
17
+ validateAgentProviderOperationResult,
18
+ validateAgentProviderOutputForContext
19
+ } from "./outputValidation.js";
20
+ import {
21
+ closeRejectedAgentProviderSession,
22
+ openIdentityCreatingAgentProviderSession,
23
+ validateAgentProviderSession
24
+ } from "./sessionValidation.js";
25
+ function parseWorkingDirectory(value) {
26
+ if (value.length < 1 || value.length > 4096 || !path.isAbsolute(value) || path.normalize(value) !== value || containsAgentControlCharacter(value)) {
27
+ throw new TypeError(
28
+ "Provider workingDirectory must be a canonical absolute path."
29
+ );
30
+ }
31
+ return value;
32
+ }
33
+ function assertAuthenticationOutputKind(providerKey, output) {
34
+ if (["authentication", "lifecycle", "evidence"].includes(output.kind)) {
35
+ return;
36
+ }
37
+ throwAgentProviderContractError(
38
+ providerKey,
39
+ "output_capability_mismatch",
40
+ "Authentication may emit only authentication, lifecycle, or evidence output."
41
+ );
42
+ }
43
+ function validateAgentProviderAdapter(capabilityInput, adapter) {
44
+ const capabilities = parseAgentCapabilities(capabilityInput);
45
+ if (adapter === null || typeof adapter !== "object" || typeof adapter.createSession !== "function" || adapter.resumption === null || typeof adapter.resumption !== "object" || !["supported", "unsupported"].includes(adapter.resumption.kind) || adapter.resumption.kind === "supported" && typeof adapter.resumption.resumeSession !== "function" || adapter.branching === null || typeof adapter.branching !== "object" || !["through_turn", "unsupported"].includes(adapter.branching.kind) || adapter.branching.kind === "through_turn" && typeof adapter.branching.branchSession !== "function" || adapter.authentication === null || typeof adapter.authentication !== "object" || !["supported", "unsupported"].includes(adapter.authentication.kind) || adapter.authentication.kind === "supported" && (typeof adapter.authentication.start !== "function" || typeof adapter.authentication.cancel !== "function")) {
46
+ throwAgentProviderContractError(
47
+ capabilities.providerKey,
48
+ "invalid_adapter",
49
+ `Provider ${capabilities.providerKey} returned an incomplete adapter.`
50
+ );
51
+ }
52
+ if (adapter.resumption.kind === "supported" !== capabilities.sessions.resume || adapter.branching.kind !== capabilities.sessions.branch.kind || adapter.authentication.kind !== capabilities.authentication.kind) {
53
+ throwAgentProviderContractError(
54
+ capabilities.providerKey,
55
+ "capability_port_mismatch",
56
+ `Provider ${capabilities.providerKey} adapter ports do not match its capabilities.`
57
+ );
58
+ }
59
+ const declaredResumption = adapter.resumption;
60
+ const resumption = declaredResumption.kind === "unsupported" ? Object.freeze({ kind: "unsupported" }) : Object.freeze({
61
+ kind: "supported",
62
+ resumeSession: async (resumeInput) => {
63
+ throwIfAgentOperationAborted(resumeInput.signal);
64
+ const parsed = parseAgentSessionOpenInput({
65
+ operation: "resume",
66
+ sessionId: resumeInput.sessionId,
67
+ binding: resumeInput.binding,
68
+ configuration: resumeInput.configuration
69
+ });
70
+ if (parsed.operation !== "resume") {
71
+ throw new TypeError("Expected a resume session input.");
72
+ }
73
+ assertAgentSessionConfigurationSupported(
74
+ capabilities,
75
+ parsed.configuration
76
+ );
77
+ const workingDirectory = parseWorkingDirectory(
78
+ resumeInput.workingDirectory
79
+ );
80
+ const binding = parsed.binding;
81
+ const candidate = await declaredResumption.resumeSession({
82
+ sessionId: parsed.sessionId,
83
+ workingDirectory,
84
+ binding,
85
+ configuration: parsed.configuration,
86
+ ...resumeInput.signal === void 0 ? {} : { signal: resumeInput.signal }
87
+ });
88
+ try {
89
+ return validateAgentProviderSession({
90
+ capabilities,
91
+ sessionId: parsed.sessionId,
92
+ candidate,
93
+ expectedBinding: binding
94
+ });
95
+ } catch (error) {
96
+ return closeRejectedAgentProviderSession(candidate, error);
97
+ }
98
+ }
99
+ });
100
+ const declaredBranching = adapter.branching;
101
+ const branching = declaredBranching.kind === "unsupported" ? Object.freeze({ kind: "unsupported" }) : Object.freeze({
102
+ kind: "through_turn",
103
+ branchSession: async (branchInput) => {
104
+ throwIfAgentOperationAborted(branchInput.signal);
105
+ const parsed = parseAgentSessionOpenInput({
106
+ operation: "branch",
107
+ sessionId: branchInput.sessionId,
108
+ source: branchInput.source,
109
+ configuration: branchInput.configuration
110
+ });
111
+ if (parsed.operation !== "branch") {
112
+ throw new TypeError("Expected a branch session input.");
113
+ }
114
+ assertAgentSessionConfigurationSupported(
115
+ capabilities,
116
+ parsed.configuration
117
+ );
118
+ const workingDirectory = parseWorkingDirectory(
119
+ branchInput.workingDirectory
120
+ );
121
+ const sourceBinding = parsed.source.binding;
122
+ return openIdentityCreatingAgentProviderSession({
123
+ capabilities,
124
+ sessionId: parsed.sessionId,
125
+ observer: branchInput.onBindingCreated,
126
+ sourceBinding,
127
+ open: (observer) => declaredBranching.branchSession({
128
+ sessionId: parsed.sessionId,
129
+ workingDirectory,
130
+ source: parsed.source,
131
+ configuration: parsed.configuration,
132
+ onBindingCreated: observer,
133
+ ...branchInput.signal === void 0 ? {} : { signal: branchInput.signal }
134
+ })
135
+ });
136
+ }
137
+ });
138
+ const declaredAuthentication = adapter.authentication;
139
+ const authenticationFlows = capabilities.authentication.kind === "supported" ? capabilities.authentication.flows : [];
140
+ const authentication = declaredAuthentication.kind === "unsupported" ? Object.freeze({ kind: "unsupported" }) : Object.freeze({
141
+ kind: "supported",
142
+ start: async function* (authInput) {
143
+ throwIfAgentOperationAborted(authInput.signal);
144
+ const attemptId = parseAgentProviderTechnicalId(
145
+ authInput.attemptId,
146
+ "authentication attemptId"
147
+ );
148
+ if (!authenticationFlows.includes(authInput.flow)) {
149
+ throwAgentProviderContractError(
150
+ capabilities.providerKey,
151
+ "input_capability_mismatch",
152
+ "Agent authentication flow is not declared by provider capabilities."
153
+ );
154
+ }
155
+ const deadlineAt = authInput.deadlineAt === void 0 ? void 0 : parseAgentIsoDateTime(authInput.deadlineAt);
156
+ for await (const candidate of declaredAuthentication.start({
157
+ attemptId,
158
+ flow: authInput.flow,
159
+ ...deadlineAt === void 0 ? {} : { deadlineAt },
160
+ ...authInput.signal === void 0 ? {} : { signal: authInput.signal }
161
+ })) {
162
+ const output = validateAgentProviderOutputForContext(candidate, {
163
+ capabilities,
164
+ providerKey: capabilities.providerKey,
165
+ authenticationAttemptId: attemptId
166
+ });
167
+ assertAuthenticationOutputKind(capabilities.providerKey, output);
168
+ yield output;
169
+ }
170
+ },
171
+ cancel: async (authInput) => {
172
+ throwIfAgentOperationAborted(authInput.signal);
173
+ const attemptId = parseAgentProviderTechnicalId(
174
+ authInput.attemptId,
175
+ "authentication attemptId"
176
+ );
177
+ const providerLoginId = authInput.providerLoginId === void 0 ? void 0 : parseAgentProviderTechnicalId(
178
+ authInput.providerLoginId,
179
+ "providerLoginId"
180
+ );
181
+ if (authInput.reason !== void 0 && !["user_requested", "timeout", "shutdown", "other"].includes(
182
+ authInput.reason
183
+ )) {
184
+ throw new TypeError(
185
+ "Agent authentication cancel reason is unsupported."
186
+ );
187
+ }
188
+ const result = validateAgentProviderOperationResult(
189
+ await declaredAuthentication.cancel({
190
+ attemptId,
191
+ ...providerLoginId === void 0 ? {} : { providerLoginId },
192
+ ...authInput.reason === void 0 ? {} : { reason: authInput.reason },
193
+ ...authInput.signal === void 0 ? {} : { signal: authInput.signal }
194
+ }),
195
+ {
196
+ capabilities,
197
+ providerKey: capabilities.providerKey,
198
+ authenticationAttemptId: attemptId
199
+ }
200
+ );
201
+ for (const output of result.outputs ?? []) {
202
+ assertAuthenticationOutputKind(capabilities.providerKey, output);
203
+ }
204
+ return result;
205
+ }
206
+ });
207
+ return Object.freeze({
208
+ createSession: async (createInput) => {
209
+ throwIfAgentOperationAborted(createInput.signal);
210
+ const parsed = parseAgentSessionOpenInput({
211
+ operation: "create",
212
+ sessionId: createInput.sessionId,
213
+ configuration: createInput.configuration
214
+ });
215
+ assertAgentSessionConfigurationSupported(
216
+ capabilities,
217
+ parsed.configuration
218
+ );
219
+ const workingDirectory = parseWorkingDirectory(
220
+ createInput.workingDirectory
221
+ );
222
+ return openIdentityCreatingAgentProviderSession({
223
+ capabilities,
224
+ sessionId: parsed.sessionId,
225
+ observer: createInput.onBindingCreated,
226
+ open: (observer) => adapter.createSession({
227
+ sessionId: parsed.sessionId,
228
+ workingDirectory,
229
+ configuration: parsed.configuration,
230
+ onBindingCreated: observer,
231
+ ...createInput.signal === void 0 ? {} : { signal: createInput.signal }
232
+ })
233
+ });
234
+ },
235
+ resumption,
236
+ branching,
237
+ authentication
238
+ });
239
+ }
240
+ export {
241
+ validateAgentProviderAdapter
242
+ };
@@ -0,0 +1,28 @@
1
+ import { type AgentArtifactDescriptor } from "@agen-ai/agent-protocol";
2
+ export declare const AGENT_ARTIFACT_CANDIDATE_MAX_BYTES: number;
3
+ export type AgentArtifactDeliveryRequirement = "best_effort" | "required_before_reference";
4
+ export type AgentArtifactCandidateSource = Readonly<{
5
+ kind: "bytes";
6
+ bytes: Uint8Array;
7
+ }> | Readonly<{
8
+ kind: "file";
9
+ filePath: string;
10
+ }>;
11
+ export interface AgentArtifactCandidate {
12
+ readonly descriptor: AgentArtifactDescriptor;
13
+ readonly source: AgentArtifactCandidateSource;
14
+ readonly delivery: AgentArtifactDeliveryRequirement;
15
+ }
16
+ export interface CreateAgentArtifactCandidateInput {
17
+ readonly descriptor: AgentArtifactDescriptor;
18
+ readonly source: AgentArtifactCandidateSource;
19
+ readonly delivery: AgentArtifactDeliveryRequirement;
20
+ }
21
+ export declare const AGENT_ARTIFACT_CANDIDATE_ERROR_CODES: readonly ["invalid_descriptor", "invalid_source", "source_too_large", "byte_size_mismatch", "digest_mismatch", "invalid_delivery"];
22
+ export type AgentArtifactCandidateErrorCode = (typeof AGENT_ARTIFACT_CANDIDATE_ERROR_CODES)[number];
23
+ export declare class AgentArtifactCandidateError extends TypeError {
24
+ readonly code: AgentArtifactCandidateErrorCode;
25
+ constructor(code: AgentArtifactCandidateErrorCode);
26
+ }
27
+ export declare function createAgentArtifactCandidate(input: CreateAgentArtifactCandidateInput): AgentArtifactCandidate;
28
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1,87 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ parseAgentArtifactDescriptor
4
+ } from "@agen-ai/agent-protocol";
5
+ import { containsAgentControlCharacter } from "./internal/controlCharacters.js";
6
+ const AGENT_ARTIFACT_CANDIDATE_MAX_BYTES = 10 * 1024 * 1024;
7
+ const AGENT_ARTIFACT_CANDIDATE_ERROR_CODES = [
8
+ "invalid_descriptor",
9
+ "invalid_source",
10
+ "source_too_large",
11
+ "byte_size_mismatch",
12
+ "digest_mismatch",
13
+ "invalid_delivery"
14
+ ];
15
+ class AgentArtifactCandidateError extends TypeError {
16
+ constructor(code) {
17
+ super(`Agent artifact candidate is invalid: ${code}.`);
18
+ this.code = code;
19
+ this.name = "AgentArtifactCandidateError";
20
+ }
21
+ code;
22
+ }
23
+ function candidateError(code) {
24
+ throw new AgentArtifactCandidateError(code);
25
+ }
26
+ function bytesCandidateDescriptor(descriptor, bytes) {
27
+ if (bytes.byteLength > AGENT_ARTIFACT_CANDIDATE_MAX_BYTES) {
28
+ candidateError("source_too_large");
29
+ }
30
+ if (descriptor.byteSize !== void 0 && descriptor.byteSize !== bytes.byteLength) {
31
+ candidateError("byte_size_mismatch");
32
+ }
33
+ const digest = createHash("sha256").update(bytes).digest("hex");
34
+ if (descriptor.digest !== void 0 && descriptor.digest.value !== digest) {
35
+ candidateError("digest_mismatch");
36
+ }
37
+ return parseAgentArtifactDescriptor({
38
+ ...descriptor,
39
+ byteSize: bytes.byteLength,
40
+ digest: { algorithm: "sha256", value: digest }
41
+ });
42
+ }
43
+ function fileCandidateSource(filePath) {
44
+ if (filePath.length < 1 || filePath.length > 4096 || filePath !== filePath.trim() || containsAgentControlCharacter(filePath)) {
45
+ candidateError("invalid_source");
46
+ }
47
+ return Object.freeze({ kind: "file", filePath });
48
+ }
49
+ function createAgentArtifactCandidate(input) {
50
+ let descriptor;
51
+ try {
52
+ descriptor = parseAgentArtifactDescriptor(input.descriptor);
53
+ } catch {
54
+ candidateError("invalid_descriptor");
55
+ }
56
+ if (!["best_effort", "required_before_reference"].includes(input.delivery)) {
57
+ candidateError("invalid_delivery");
58
+ }
59
+ if (descriptor.kind === "plan" && input.delivery !== "required_before_reference") {
60
+ candidateError("invalid_delivery");
61
+ }
62
+ if (input.source === null || typeof input.source !== "object") {
63
+ candidateError("invalid_source");
64
+ }
65
+ let source;
66
+ if (input.source.kind === "bytes") {
67
+ if (!(input.source.bytes instanceof Uint8Array))
68
+ candidateError("invalid_source");
69
+ source = Object.freeze({
70
+ kind: "bytes",
71
+ bytes: new Uint8Array(input.source.bytes)
72
+ });
73
+ } else if (input.source.kind === "file") {
74
+ source = fileCandidateSource(input.source.filePath);
75
+ } else {
76
+ candidateError("invalid_source");
77
+ }
78
+ if (source.kind === "bytes")
79
+ descriptor = bytesCandidateDescriptor(descriptor, source.bytes);
80
+ return Object.freeze({ descriptor, source, delivery: input.delivery });
81
+ }
82
+ export {
83
+ AGENT_ARTIFACT_CANDIDATE_ERROR_CODES,
84
+ AGENT_ARTIFACT_CANDIDATE_MAX_BYTES,
85
+ AgentArtifactCandidateError,
86
+ createAgentArtifactCandidate
87
+ };
@@ -0,0 +1,3 @@
1
+ import type { AgentCapabilities, AgentSessionConfiguration } from "@agen-ai/agent-protocol";
2
+ export declare function assertAgentSessionConfigurationSupported(capabilities: AgentCapabilities, configuration: AgentSessionConfiguration): void;
3
+ //# sourceMappingURL=configurationValidation.d.ts.map
@@ -0,0 +1,35 @@
1
+ import { throwAgentProviderContractError } from "./contractErrors.js";
2
+ function assertAgentSessionConfigurationSupported(capabilities, configuration) {
3
+ const entries = Object.entries(configuration.values);
4
+ if (capabilities.configuration.kind === "managed") {
5
+ if (entries.length === 0) return;
6
+ throwAgentProviderContractError(
7
+ capabilities.providerKey,
8
+ "configuration_key_unsupported",
9
+ "Managed provider configuration values must be empty."
10
+ );
11
+ }
12
+ const fields = new Map(
13
+ capabilities.configuration.fields.map((field) => [field.key, field])
14
+ );
15
+ for (const [key, value] of entries) {
16
+ const field = fields.get(key);
17
+ if (!field) {
18
+ throwAgentProviderContractError(
19
+ capabilities.providerKey,
20
+ "configuration_key_unsupported",
21
+ "Provider configuration contains a key not declared by its capabilities."
22
+ );
23
+ }
24
+ if (typeof value !== "string" || !field.optionIds.includes(value)) {
25
+ throwAgentProviderContractError(
26
+ capabilities.providerKey,
27
+ "configuration_value_unsupported",
28
+ "Provider configuration contains an option not declared by its capabilities."
29
+ );
30
+ }
31
+ }
32
+ }
33
+ export {
34
+ assertAgentSessionConfigurationSupported
35
+ };
@@ -0,0 +1,17 @@
1
+ import type { AgentProviderKey } from "@agen-ai/agent-protocol";
2
+ export declare const AGENT_PROVIDER_CONTRACT_ERROR_CODES: readonly ["capability_port_mismatch", "invalid_adapter", "invalid_session", "invalid_binding", "binding_callback_missing", "binding_callback_repeated", "binding_callback_mismatch", "resume_binding_mismatch", "branch_binding_reused", "session_closed", "session_unusable", "concurrent_turn", "active_turn_mismatch", "invalid_operation_result", "output_session_mismatch", "output_turn_mismatch", "output_authentication_attempt_mismatch", "output_capability_mismatch", "input_capability_mismatch", "invalid_turn_sequence", "request_resolution_mismatch", "configuration_key_unsupported", "configuration_value_unsupported", "request_pending"];
3
+ export type AgentProviderContractErrorCode = (typeof AGENT_PROVIDER_CONTRACT_ERROR_CODES)[number];
4
+ export type AgentProviderDelegatedOperation = "steer_turn";
5
+ export declare class AgentProviderContractError extends Error {
6
+ readonly providerKey: AgentProviderKey;
7
+ readonly code: AgentProviderContractErrorCode;
8
+ constructor(providerKey: AgentProviderKey, code: AgentProviderContractErrorCode, message: string);
9
+ }
10
+ export declare class AgentProviderDelegatedOperationError extends Error {
11
+ readonly providerKey: AgentProviderKey;
12
+ readonly operation: AgentProviderDelegatedOperation;
13
+ readonly providerExecution: "started";
14
+ constructor(providerKey: AgentProviderKey, operation: AgentProviderDelegatedOperation, cause: unknown);
15
+ }
16
+ export declare function throwAgentProviderContractError(providerKey: AgentProviderKey, code: AgentProviderContractErrorCode, message: string): never;
17
+ //# sourceMappingURL=contractErrors.d.ts.map
@@ -0,0 +1,59 @@
1
+ const AGENT_PROVIDER_CONTRACT_ERROR_CODES = [
2
+ "capability_port_mismatch",
3
+ "invalid_adapter",
4
+ "invalid_session",
5
+ "invalid_binding",
6
+ "binding_callback_missing",
7
+ "binding_callback_repeated",
8
+ "binding_callback_mismatch",
9
+ "resume_binding_mismatch",
10
+ "branch_binding_reused",
11
+ "session_closed",
12
+ "session_unusable",
13
+ "concurrent_turn",
14
+ "active_turn_mismatch",
15
+ "invalid_operation_result",
16
+ "output_session_mismatch",
17
+ "output_turn_mismatch",
18
+ "output_authentication_attempt_mismatch",
19
+ "output_capability_mismatch",
20
+ "input_capability_mismatch",
21
+ "invalid_turn_sequence",
22
+ "request_resolution_mismatch",
23
+ "configuration_key_unsupported",
24
+ "configuration_value_unsupported",
25
+ "request_pending"
26
+ ];
27
+ class AgentProviderContractError extends Error {
28
+ constructor(providerKey, code, message) {
29
+ super(message);
30
+ this.providerKey = providerKey;
31
+ this.code = code;
32
+ this.name = "AgentProviderContractError";
33
+ }
34
+ providerKey;
35
+ code;
36
+ }
37
+ class AgentProviderDelegatedOperationError extends Error {
38
+ constructor(providerKey, operation, cause) {
39
+ super(
40
+ cause instanceof Error ? cause.message : `Provider ${providerKey} failed after ${operation} delegation.`,
41
+ { cause }
42
+ );
43
+ this.providerKey = providerKey;
44
+ this.operation = operation;
45
+ this.name = "AgentProviderDelegatedOperationError";
46
+ }
47
+ providerKey;
48
+ operation;
49
+ providerExecution = "started";
50
+ }
51
+ function throwAgentProviderContractError(providerKey, code, message) {
52
+ throw new AgentProviderContractError(providerKey, code, message);
53
+ }
54
+ export {
55
+ AGENT_PROVIDER_CONTRACT_ERROR_CODES,
56
+ AgentProviderContractError,
57
+ AgentProviderDelegatedOperationError,
58
+ throwAgentProviderContractError
59
+ };