@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.
- package/README.md +297 -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/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 +13 -3
- package/dist/sessionValidation.js +80 -6
- 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
package/README.md
CHANGED
|
@@ -9,14 +9,20 @@ sessions; each returned session owns its binding and conversation-local operatio
|
|
|
9
9
|
The runtime depends only on `@agen-ai/agent-protocol`. It has no concept of tenants, SaaS
|
|
10
10
|
workspaces, assigned users, database rows, persistence sequence, visibility, billing, host boots,
|
|
11
11
|
distributed leases, or storage policy. A host must authorize and select an instance before calling this SPI.
|
|
12
|
-
|
|
12
|
+
Current source implements Agent Protocol V13 in the unpublished coordinated eight-package `0.4.4`
|
|
13
|
+
candidate, including structured final output. Published `0.4.3` is the seven-package V12 release,
|
|
13
14
|
including tagged decision responses and exact turn request unavailability. Published `0.4.1`
|
|
14
15
|
retains V11 and its qualification evidence; the earlier `0.4.0` release retains V10.
|
|
15
|
-
The runtime also provides neutral session forms, plan reviews, staged native continuations
|
|
16
|
-
explicit human-wait policies
|
|
16
|
+
The runtime also provides neutral session forms, plan reviews, staged native continuations,
|
|
17
|
+
explicit human-wait policies and optional input during an owned execution. Provider mappings
|
|
18
|
+
require their own support and qualification. The candidate ships no public native provider with
|
|
19
|
+
execution-input support; the separately controlled private Claude diagnostic mapping does not
|
|
20
|
+
introduce a public Claude constructor.
|
|
17
21
|
Keep all installed SDK packages at the same version; the [0.4.2 migration
|
|
18
22
|
guide](../../MIGRATING-TO-0.4.2.md) covers tagged responses, continuous request output and store
|
|
19
23
|
contract changes. Generic contract proof and exact native qualification are separate boundaries.
|
|
24
|
+
The [0.4.4 upgrade guide](../../UPGRADING-TO-0.4.4.md) covers V13 and the optional
|
|
25
|
+
`@agen-ai/agent-history` package, whose native conversation browsing remains independent of execution.
|
|
20
26
|
The SDK contract version is independent of private transport and product persistence versions. This
|
|
21
27
|
is intentionally one coordinated tuple rather than a deployable mixed-version graph.
|
|
22
28
|
|
|
@@ -25,10 +31,177 @@ is intentionally one coordinated tuple rather than a deployable mixed-version gr
|
|
|
25
31
|
- `@agen-ai/agent-runtime` exports the public driver, instance, adapter, session, output,
|
|
26
32
|
readiness, account-quota port validation, bounded-evidence, artifact-candidate,
|
|
27
33
|
capability-bound interaction validation, session-lifetime interaction and cleanup APIs, and registry APIs.
|
|
34
|
+
It also exports `parseAgentExecutionInputMessageId` and the execution-input support, message,
|
|
35
|
+
port, receipt and outcome types; execution input has no separate package or entrypoint.
|
|
28
36
|
- `@agen-ai/agent-runtime/environment` exports the instance discovery and session observation ports.
|
|
37
|
+
- `@agen-ai/agent-runtime/generation` exports `generateObject`, `AgentGenerationError`,
|
|
38
|
+
`AgentGenerationCleanupError`, and their input/result/error types. Generation is an explicit
|
|
39
|
+
entrypoint; importing the ordinary runtime does not select a provider or start work.
|
|
29
40
|
- `@agen-ai/agent-runtime/testing` exports the deterministic fake provider and reusable
|
|
30
41
|
conformance runner.
|
|
31
42
|
|
|
43
|
+
## Generate a typed object
|
|
44
|
+
|
|
45
|
+
`generateObject` borrows an explicitly selected `ValidatedMaterializedAgentProviderInstance`,
|
|
46
|
+
opens a fresh native session, owns one continuous output reader and request delivery, validates
|
|
47
|
+
the terminal object, runs a value-preserving decoder, and closes that session before returning.
|
|
48
|
+
The caller retains the instance and its registry; generation never disposes them. It does not
|
|
49
|
+
accept an existing session or resume/branch a prior conversation. Its result contains the inferred
|
|
50
|
+
`value` and the caller's `sessionId` and `turnId`.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import {
|
|
54
|
+
createAgentOutputDefinition,
|
|
55
|
+
parseAgentConfigurationRevisionId,
|
|
56
|
+
parseAgentSessionId,
|
|
57
|
+
parseAgentTurnId,
|
|
58
|
+
} from '@agen-ai/agent-protocol';
|
|
59
|
+
import type { ValidatedMaterializedAgentProviderInstance } from '@agen-ai/agent-runtime';
|
|
60
|
+
import { generateObject } from '@agen-ai/agent-runtime/generation';
|
|
61
|
+
|
|
62
|
+
const titleOutput = createAgentOutputDefinition({
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: { title: { type: 'string', minLength: 1, maxLength: 80 } },
|
|
65
|
+
required: ['title'],
|
|
66
|
+
additionalProperties: false,
|
|
67
|
+
}, (value) => typeof value.title === 'string'
|
|
68
|
+
? { success: true, data: { title: value.title } }
|
|
69
|
+
: { success: false, issues: [{ code: 'title_required', path: ['title'], message: 'A title is required.' }] });
|
|
70
|
+
|
|
71
|
+
async function generateTitle(instance: ValidatedMaterializedAgentProviderInstance, workingDirectory: string) {
|
|
72
|
+
const result = await generateObject({
|
|
73
|
+
instance,
|
|
74
|
+
session: {
|
|
75
|
+
sessionId: parseAgentSessionId('title:conversation:42'),
|
|
76
|
+
workingDirectory,
|
|
77
|
+
configuration: { kind: 'managed', revision: parseAgentConfigurationRevisionId('title:configuration:1') },
|
|
78
|
+
},
|
|
79
|
+
turn: {
|
|
80
|
+
turnId: parseAgentTurnId('title:conversation:42:1'),
|
|
81
|
+
interactionMode: 'default',
|
|
82
|
+
parts: [{ type: 'text', text: 'Create a short title for a conversation about investigating payment failures.' }],
|
|
83
|
+
},
|
|
84
|
+
output: titleOutput,
|
|
85
|
+
timeoutMs: 30_000,
|
|
86
|
+
});
|
|
87
|
+
// The generation session and its reader are closed before this value is returned.
|
|
88
|
+
return result.value.title; // string, inferred from the decoder
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Choose configuration that fits the selected instance; the example uses a managed instance.
|
|
93
|
+
Use fresh caller-owned correlation IDs for each generation. The shipped public
|
|
94
|
+
[`examples/generate-title.ts`](../../examples/generate-title.ts) additionally saves the title after
|
|
95
|
+
successful cleanup. The application selects credentials, working-directory access and native
|
|
96
|
+
tool/sandbox policy. A title prompt and an output schema do not disable tools or grant permission.
|
|
97
|
+
|
|
98
|
+
For Zod authoring, use the explicit protocol adapter:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { z } from 'zod/v4';
|
|
102
|
+
import { zodOutput } from '@agen-ai/agent-protocol/zod';
|
|
103
|
+
|
|
104
|
+
const titleOutput = zodOutput(z.strictObject({ title: z.string() }));
|
|
105
|
+
// generateObject({ ..., output: titleOutput }) infers result.value as { title: string }.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A schema-only `createAgentOutputDefinition(schema)` returns `AgentJsonObject`. A typed value needs
|
|
109
|
+
a real decoder or `zodOutput`; there is no unchecked `generateObject<MyType>` shortcut that omits
|
|
110
|
+
that evidence. Decoders validate synchronously and must preserve the generated JSON exactly. The
|
|
111
|
+
runtime rejects transformed/coerced values, freezes the successful JSON value, and leaves later
|
|
112
|
+
presentation transforms to the application. See the
|
|
113
|
+
[protocol profile and authoring limits](../agent-protocol/README.md#structured-final-output),
|
|
114
|
+
including the distinct unsupported Zod string/array length checks and their neutral-schema path.
|
|
115
|
+
|
|
116
|
+
### Capability and schema lifetime
|
|
117
|
+
|
|
118
|
+
Generation preflights `instance.capabilities.turns.structuredOutput`. Unsupported support, wrong
|
|
119
|
+
scope, unsupported schema, configuration/input mismatch or excessive schema bytes fail before
|
|
120
|
+
native opening. A supported declaration has `mechanism: 'native'`,
|
|
121
|
+
`schemaProfile: 'agenai.output-schema.v1'`, `scope: 'turn' | 'session'`, bounded
|
|
122
|
+
`maxSchemaBytes`/`maxOutputBytes`, and `resume: false`, `branch: false`. `generateObject` supplies
|
|
123
|
+
the schema at the declared boundary: opening for session scope, start-turn for turn scope.
|
|
124
|
+
It owns `output`, `signal`, binding/start callbacks and native continuation control in those
|
|
125
|
+
inputs; supplying even an explicitly `undefined` reserved property is rejected.
|
|
126
|
+
|
|
127
|
+
With the lower-level API, a turn-scoped request applies only to that turn; omit `output` on the
|
|
128
|
+
next turn for ordinary text. A session-scoped request is an immutable opening binding inherited
|
|
129
|
+
by every turn. Supplying any turn `output` property, including the same schema or `undefined`,
|
|
130
|
+
cannot override or remove it. Steering cannot carry an `output` property. Requests to resume or
|
|
131
|
+
branch with structured output fail before native calls; ordinary resume/branch remain available
|
|
132
|
+
when separately supported. Schema-bound native continuations are not admitted. Admitted schemas
|
|
133
|
+
are detached frozen snapshots, so mutating the original object cannot alter running work.
|
|
134
|
+
|
|
135
|
+
Every `turn.completed` carries `payload.structuredOutput`: `not_requested`, `json` with a complete
|
|
136
|
+
object, or `unavailable` with a reason. Only a native `completed` outcome can contain `json`.
|
|
137
|
+
Native completion can still be `unavailable`, for example when output is missing or fails schema
|
|
138
|
+
validation. The validated runtime independently checks the terminal candidate against its exact
|
|
139
|
+
admitted schema and converts a well-formed mismatch into `unavailable/schema_mismatch` while
|
|
140
|
+
preserving the native outcome. Malformed envelopes, unsolicited output, duplicate terminals and
|
|
141
|
+
wrong identities remain contract failures. A stream ending without a terminal never manufactures
|
|
142
|
+
success. No partial JSON is exposed as a validated object, and there is no prose extraction,
|
|
143
|
+
model repair, automatic generation retry or provider/tool replay.
|
|
144
|
+
|
|
145
|
+
### Deadlines, requests and cleanup
|
|
146
|
+
|
|
147
|
+
`onOutput` observes the same reader owned by the helper and applies backpressure; it must not
|
|
148
|
+
acquire another reader. An optional `onRequest(request, { signal })` returns an exact
|
|
149
|
+
`AgentRequestResolution`; the helper validates/delivers it while continuing output. Honor its
|
|
150
|
+
signal when a request is retired or generation stops. Without a handler, a turn request fails as
|
|
151
|
+
`interaction_required`; the helper never fabricates approval, denial or an answer. Any opening
|
|
152
|
+
session-interaction handler remains an explicit `session.interactions` choice. A generation
|
|
153
|
+
helper supplies no new effect authority.
|
|
154
|
+
|
|
155
|
+
| Generation bound | Value |
|
|
156
|
+
| --- | --- |
|
|
157
|
+
| Overall timeout | Five minutes by default; `timeoutMs` is a positive integer up to one hour |
|
|
158
|
+
| Effective execution deadline | Earlier of the overall timeout and `turn.deadlineAt`; caller abort also stops generation |
|
|
159
|
+
| Output observer / request handler / response delivery | 30 seconds / five minutes / 30 seconds, each still bounded by the generation deadline |
|
|
160
|
+
| Active request handlers | 8 retained request records; a record remains owned while its callback/delivery is pending |
|
|
161
|
+
| Cleanup attempt | 30 seconds, retaining actual pending work for retry |
|
|
162
|
+
|
|
163
|
+
The schema/value profile caps each at 16,384 serialized UTF-8 bytes; the provider can advertise
|
|
164
|
+
smaller byte limits. Other shape and raw-candidate limits belong to the
|
|
165
|
+
[protocol profile](../agent-protocol/README.md#the-agenaioutput-schemav1-profile).
|
|
166
|
+
Successful return means stream settlement, local decoding and session cleanup all succeeded.
|
|
167
|
+
On abort or failure, the helper initiates native interruption when applicable and session close
|
|
168
|
+
before joining entered reader/observer/request work. An uncooperative callback remains owned;
|
|
169
|
+
its timeout is not proof it stopped.
|
|
170
|
+
|
|
171
|
+
| Error | Application handling |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `AgentGenerationError` | Inspect `code`: `unsupported`, `interaction_required`, `generation_failed`, `decoding_failed`, `observer_failed`, `request_failed`, or `timeout`. A generation failure may carry the unavailable `reason` and bounded `issues`; request failure may carry the exact delivery `receipt`. |
|
|
174
|
+
| `AgentProtocolValidationError` / `AgentProviderContractError` | Correct input or adapter contract faults; they retain their existing public semantics. |
|
|
175
|
+
| Caller cancellation | Retains the runtime's operation-abort semantics after cleanup. |
|
|
176
|
+
| `AgentGenerationCleanupError` | Retain the original object and borrowed instance/registry; its `retryCleanup()` owns remaining work. It may carry `primaryError` and a validated `result`, but the original call has not succeeded. |
|
|
177
|
+
| `AgentProviderSessionCleanupError` during opening | Retain the exact original opening receipt and its retry callback. |
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { AgentGenerationCleanupError, AgentGenerationError } from '@agen-ai/agent-runtime/generation';
|
|
181
|
+
import { AgentProviderSessionCleanupError } from '@agen-ai/agent-runtime';
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
const title = await generateTitle(instance, workingDirectory);
|
|
185
|
+
await saveTitle(title);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
if (error instanceof AgentGenerationCleanupError || error instanceof AgentProviderSessionCleanupError) {
|
|
188
|
+
await error.retryCleanup(); // If it rejects, retain this same callable owner for recovery.
|
|
189
|
+
throw error; // Cleanup recovery does not replay generation or change the original verdict.
|
|
190
|
+
}
|
|
191
|
+
if (error instanceof AgentGenerationError && error.code === 'unsupported') {
|
|
192
|
+
showStructuredOutputUnavailable();
|
|
193
|
+
} else {
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Do not serialize the error in place of retaining its callable cleanup owner or dispose dependent
|
|
200
|
+
resources while cleanup remains incomplete. A later application retry is a separate explicitly
|
|
201
|
+
chosen generation with its own effect and cost assessment. Generic ACP declares unsupported;
|
|
202
|
+
the public provider's exact opt-in Grok mapping and installed native qualification are described
|
|
203
|
+
in [`@agen-ai/provider-acp`](../provider-acp/README.md#structured-final-output).
|
|
204
|
+
|
|
32
205
|
## Lifecycle and ownership
|
|
33
206
|
|
|
34
207
|
1. Define an `AgentProviderDriver` with `defineAgentProviderDriver`.
|
|
@@ -107,7 +280,7 @@ provider that replaces that process emits a `process.started` lifecycle output a
|
|
|
107
280
|
boundary before reporting usage from the replacement. Validation then clears only the
|
|
108
281
|
`materialization` occupancy, cumulative counters, and compaction allowance; logical `session`
|
|
109
282
|
measurements remain continuous.
|
|
110
|
-
`startTurn(input)` returns `{ turnId, outputs, resolveRequest }`. `outputs` preserves per-output
|
|
283
|
+
`startTurn(input)` returns `{ turnId, outputs, resolveRequest, input? }`. `outputs` preserves per-output
|
|
111
284
|
backpressure and stays open during `waiting_for_request`; the consumer can call
|
|
112
285
|
`execution.resolveRequest({ resolution })` as soon as it receives `request.opened`, before its next
|
|
113
286
|
pull. A later queued waiting observation cannot revive an already answered request. No response
|
|
@@ -194,8 +367,8 @@ descriptor validation, through native settlement and awaited output acceptance.
|
|
|
194
367
|
native continuations cannot overlap that reservation. Exact cached idempotent results are returned
|
|
195
368
|
before reserving another execution. Close stops admission and initiates native quiescence before
|
|
196
369
|
joining entered operation work; failed cleanup retains its stopped owner for retry. This lifecycle
|
|
197
|
-
correction and operation retry observations
|
|
198
|
-
Agent Protocol V12 and operation SPI.
|
|
370
|
+
correction and operation retry observations were included in published `0.4.3`, using its
|
|
371
|
+
Agent Protocol V12 and operation SPI; current V13 source retains that behavior.
|
|
199
372
|
|
|
200
373
|
Discover the operation through `session.operations` and its offered descriptor, using an exact
|
|
201
374
|
application-configured ID. Pass the descriptor revision as `expectedRevision`, its exact fields,
|
|
@@ -219,6 +392,118 @@ identity, declared bounds, forward-only lifecycle transitions, and per-output ba
|
|
|
219
392
|
the operation result may settle. Collaboration and generated-resource observations retain the
|
|
220
393
|
same correlation and lifecycle validation at their respective ports.
|
|
221
394
|
|
|
395
|
+
## Input during an owned execution
|
|
396
|
+
|
|
397
|
+
The unpublished `0.4.4` candidate adds optional provider-neutral input on a caller-started
|
|
398
|
+
execution. **No public native provider ships with support for this domain.** Public ACP,
|
|
399
|
+
including Grok compositions, remains unsupported. Positive native qualification belongs only to
|
|
400
|
+
a separately controlled private Claude SDK `0.3.309` / Code `2.1.309` diagnostic composition on
|
|
401
|
+
Linux x86_64 / Node `24.18.0`; there is no public Claude execution constructor. That evidence does
|
|
402
|
+
not qualify production/fleet execution, subscription authentication or billing. Other features'
|
|
403
|
+
provider selections and qualification remain independent.
|
|
404
|
+
|
|
405
|
+
An adapter optionally declares `executionInput?: AgentExecutionInputSupport`. An execution
|
|
406
|
+
optionally exposes `input?: AgentExecutionInput`; absence and `{ kind: 'unsupported' }` both mean
|
|
407
|
+
unsupported. Check `execution.input?.kind === 'supported'` before calling `sendMessage`. A supported
|
|
408
|
+
port must match the adapter's delivery, consumption reporting, input and limit declaration.
|
|
409
|
+
Legacy adapters can continue omitting the domain. Executions adopted from session human-response
|
|
410
|
+
native continuations expose input as unsupported even when caller-started executions support it.
|
|
411
|
+
|
|
412
|
+
The runtime root exports `parseAgentExecutionInputMessageId` and all six execution-input types:
|
|
413
|
+
`AgentExecutionInputMessageId`, `AgentExecutionInputMessage`, `AgentExecutionInputSupport`,
|
|
414
|
+
`AgentExecutionInput`, `AgentExecutionInputReceipt` and `AgentExecutionInputOutcome`.
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
import {
|
|
418
|
+
parseAgentExecutionInputMessageId,
|
|
419
|
+
type AgentExecutionInputMessage,
|
|
420
|
+
} from '@agen-ai/agent-runtime';
|
|
421
|
+
|
|
422
|
+
const message: AgentExecutionInputMessage = {
|
|
423
|
+
messageId: parseAgentExecutionInputMessageId('conversation:42:requirement:2'),
|
|
424
|
+
parts: [{ type: 'text', text: 'Include the corrected requirement in the owned task.' }],
|
|
425
|
+
};
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
Message IDs are branded separately from turn and human-request IDs. The parser accepts canonical
|
|
429
|
+
nonempty text up to 256 characters, without outer whitespace or control characters. Use a fresh ID
|
|
430
|
+
for every submission; parsing does not make the provider idempotent.
|
|
431
|
+
|
|
432
|
+
The delivery contract is `current_or_owned_continuation`: the message can be consumed in the
|
|
433
|
+
original native command or an additional native command owned by the same SDK execution. It keeps
|
|
434
|
+
one turn ID, output reader and cleanup owner. Existing `capabilities.turns.steer` /
|
|
435
|
+
`session.steering.steerTurn` retains strict running-native-command semantics. Do not substitute
|
|
436
|
+
input for steering or manufacture a fallback turn when input is unsupported.
|
|
437
|
+
|
|
438
|
+
`sendMessage({ messageId, parts, summary?, signal? })` accepts text only and returns one of:
|
|
439
|
+
|
|
440
|
+
| Receipt | Meaning |
|
|
441
|
+
| --- | --- |
|
|
442
|
+
| `accepted` | The native handler authoritatively acknowledged the exact submission. Includes `settled: Promise<AgentExecutionInputOutcome>`; does not establish consumption, compliance or completion. |
|
|
443
|
+
| `rejected` | Definite refusal to admit the message, with a bounded `AgentError` and no settlement promise. The original execution remains owned. |
|
|
444
|
+
| `delivery_uncertain` | Delivery may have started without an authoritative acknowledgement, with a bounded `AgentError`. The runtime fences further mutation while the original output reader can still drain. Never replay the message. |
|
|
445
|
+
|
|
446
|
+
An accepted receipt settles to `consumed` with its `messageId`, original SDK `turnId` and
|
|
447
|
+
`placement: 'original_native_command' | 'owned_native_continuation'`, or to `unconfirmed` with its
|
|
448
|
+
`messageId` and reason. The unconfirmed reasons are `provider_does_not_report_consumption`,
|
|
449
|
+
`closed`, `interrupted`, `native_failed` and `correlation_lost`; that variant has no turn ID or
|
|
450
|
+
placement. Only support declaring `consumptionReporting: 'message_ids'` can report `consumed`.
|
|
451
|
+
Support declaring `'unavailable'` may report `provider_does_not_report_consumption` instead.
|
|
452
|
+
An unconfirmed outcome preserves acceptance and does not prove non-consumption. Attributed
|
|
453
|
+
consumption still does not prove the model obeyed the instruction. These in-process receipts and
|
|
454
|
+
promise handles are not wire or persistence formats and grant no permission or tool authority.
|
|
455
|
+
|
|
456
|
+
Start the sole `outputs` reader before sending, then keep it running during both the receipt and
|
|
457
|
+
settlement waits. `startTurn` reserves the existing execution slot synchronously, but provider
|
|
458
|
+
entry is lazy until the first output pull. A retained handle or acquired iterator is insufficient.
|
|
459
|
+
Input on a reserved, idle, stale, completed or closed execution rejects before provider entry.
|
|
460
|
+
There is no idle-session input method; use ordinary `startTurn` when idle. A structured-output
|
|
461
|
+
turn or schema-bound session, a pending turn human request or its unsettled response, and a live
|
|
462
|
+
session interaction also reject input before native entry. Admitted continuations remain in the
|
|
463
|
+
same execution slot through settlement; native result frames cannot end ownership prematurely.
|
|
464
|
+
|
|
465
|
+
| Bound | SDK ceiling; a provider may declare a smaller positive limit |
|
|
466
|
+
| --- | --- |
|
|
467
|
+
| Outstanding entered/accepted messages awaiting actual settlement | 2 per execution |
|
|
468
|
+
| Entered messages, including definite provider rejections | 16 per execution |
|
|
469
|
+
| Buffered messages | 1,048,576 serialized UTF-8 bytes across message IDs, parts and summaries, excluding signals |
|
|
470
|
+
| Message identity retention | 4,096 IDs and 1,048,576 UTF-8 ID bytes per session generation |
|
|
471
|
+
| Receipt observation / input drain | 30 seconds / 30 seconds; actual entered work remains owned |
|
|
472
|
+
|
|
473
|
+
Existing turn-content validation also applies, including its 1 MiB plus 16 KiB serialized content
|
|
474
|
+
envelope. Execution input additionally rejects images/content references and must fit its stricter
|
|
475
|
+
buffered-envelope limit. After candidate entry, rejected and settled IDs stay reserved for the
|
|
476
|
+
session generation. Local duplicate, capacity and census failures use
|
|
477
|
+
`execution_input_identity_reused`, `execution_input_capacity_exhausted` and
|
|
478
|
+
`execution_input_identity_limit_exceeded`; census exhaustion initiates owned cleanup. Malformed
|
|
479
|
+
input and pre-abort failures preserve their pre-entry errors. Provider-invoked failures can throw
|
|
480
|
+
`AgentProviderDelegatedOperationError` with `operation: 'send_execution_input'` and started-execution
|
|
481
|
+
evidence. Post-entry abort or a lost receipt can mean uncertain delivery.
|
|
482
|
+
|
|
483
|
+
For a complete runnable caller flow, use
|
|
484
|
+
[`examples/execution-input`](../../examples/execution-input/README.md) in the public SDK checkout:
|
|
485
|
+
|
|
486
|
+
```sh
|
|
487
|
+
pnpm exec tsx examples/execution-input/main.ts
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Its caller-owned teaching provider uses the actual runtime validator and no native process,
|
|
491
|
+
model, credentials, network, tools or storage. Five synthetic scenarios cover consumed,
|
|
492
|
+
unconfirmed, rejected, uncertain and unsupported input. `application.ts` waits for `turn.started`,
|
|
493
|
+
checks support and keeps the original reader progressing through both waits. Its result and
|
|
494
|
+
reader-join handles preserve ownership on failure. `main.ts` starts session close before joining
|
|
495
|
+
the reader, then disposes the instance; cleanup failure retains its callable retry owner. The same
|
|
496
|
+
source is compiled and run from the installed tarballs. Synthetic success qualifies no native
|
|
497
|
+
provider mapping.
|
|
498
|
+
|
|
499
|
+
On uncertainty, stop mutation, retain the reader and close the unusable session when needed.
|
|
500
|
+
Do not resend, steer, interrupt or start another turn to simulate delivery. Close starts native
|
|
501
|
+
quiescence before joining entered input, output and callbacks; elapsed observation time does not
|
|
502
|
+
prove they stopped. Keep the session or exact opening cleanup error and dependent instance,
|
|
503
|
+
registry and host resources until cleanup succeeds. Retry joins that same cleanup owner without
|
|
504
|
+
replaying input; rematerializing does not authorize an uncertain message's replay. This optional
|
|
505
|
+
runtime domain adds no Agent Protocol V13 change, private wire change or persistence migration.
|
|
506
|
+
|
|
222
507
|
## Session-lifetime interactions
|
|
223
508
|
|
|
224
509
|
An adapter can offer a decision, form or plan review outside a model turn through
|
|
@@ -551,14 +836,16 @@ close before joining its reader and actual callback tasks; failure also starts c
|
|
|
551
836
|
failures and cleanup failures remain observable. A callback that ignores cancellation
|
|
552
837
|
remains owned until its actual promise settles.
|
|
553
838
|
|
|
554
|
-
The coordinated
|
|
839
|
+
The coordinated eight-package `0.4.4` source candidate implements Agent Protocol V13 and remains
|
|
840
|
+
unpublished. Published `0.4.3` is the seven-package V12 release.
|
|
555
841
|
The earlier `0.4.1` release retains V11.
|
|
556
842
|
The earlier `0.4.0` release retains V10.
|
|
557
843
|
The earlier public `0.3.0` and `0.3.1` releases implemented V9 and remain historical.
|
|
558
|
-
Keep installed packages in
|
|
559
|
-
|
|
844
|
+
Keep installed packages in a release family on its coordinated version; orchestration, ACP and
|
|
845
|
+
history packages remain optional. History browsing owns no execution turn and does not establish
|
|
846
|
+
structured-output support. Every materialized instance requires `environment` and
|
|
560
847
|
`accountQuota`; every session requires `environment`. The former standalone `integrations`
|
|
561
|
-
observation port is removed. The public runtime implements Agent Protocol
|
|
848
|
+
observation port is removed. The public runtime implements Agent Protocol V13 with one current
|
|
562
849
|
adapter/session surface. Package versions remain independent of private transport and product
|
|
563
850
|
persistence versions.
|
|
564
851
|
|
|
@@ -16,8 +16,10 @@ import { containsAgentControlCharacter } from "./internal/controlCharacters.js";
|
|
|
16
16
|
import { withAgentSessionHostBinding } from "./hostBindings/lifetime.js";
|
|
17
17
|
import { invokeAgentSessionOpening } from "./hostBindings/opening.js";
|
|
18
18
|
import { validateAgentSessionHostBindingSupport } from "./hostBindings/validation.js";
|
|
19
|
+
import { validateAgentExecutionInputSupport } from "./executionInput/validation.js";
|
|
19
20
|
import { createSessionInteractionOwner } from "./sessionInteractions/lifetime.js";
|
|
20
21
|
import { validateSessionInteractionSupport, validateNativeContinuationSupport } from "./sessionInteractions/validation.js";
|
|
22
|
+
import { admitAgentStructuredOutputOpening } from "./structuredOutput/admission.js";
|
|
21
23
|
import {
|
|
22
24
|
validateAgentProviderOperationResult,
|
|
23
25
|
validateAgentProviderOutputForContext
|
|
@@ -78,6 +80,16 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
78
80
|
const declaredResumption = adapter.resumption;
|
|
79
81
|
const sessionInteractions = validateSessionInteractionSupport(capabilities, adapter);
|
|
80
82
|
const nativeContinuations = validateNativeContinuationSupport(capabilities, adapter, sessionInteractions);
|
|
83
|
+
let executionInput;
|
|
84
|
+
try {
|
|
85
|
+
executionInput = validateAgentExecutionInputSupport(adapter.executionInput);
|
|
86
|
+
} catch {
|
|
87
|
+
return throwAgentProviderContractError(
|
|
88
|
+
capabilities.providerKey,
|
|
89
|
+
"invalid_adapter",
|
|
90
|
+
"Provider declared invalid execution-input support."
|
|
91
|
+
);
|
|
92
|
+
}
|
|
81
93
|
let hostBinding;
|
|
82
94
|
try {
|
|
83
95
|
hostBinding = validateAgentSessionHostBindingSupport(adapter.hostBinding);
|
|
@@ -97,6 +109,13 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
97
109
|
support: hostBinding,
|
|
98
110
|
open: async (lease) => {
|
|
99
111
|
throwIfAgentOperationAborted(resumeInput.signal);
|
|
112
|
+
if (Reflect.has(resumeInput, "output")) {
|
|
113
|
+
throwAgentProviderContractError(
|
|
114
|
+
capabilities.providerKey,
|
|
115
|
+
"structured_output_unsupported",
|
|
116
|
+
"Structured-output requests are unsupported when resuming a session."
|
|
117
|
+
);
|
|
118
|
+
}
|
|
100
119
|
const parsed = parseAgentSessionOpenInput({
|
|
101
120
|
operation: "resume",
|
|
102
121
|
sessionId: resumeInput.sessionId,
|
|
@@ -114,7 +133,7 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
114
133
|
resumeInput.workingDirectory
|
|
115
134
|
);
|
|
116
135
|
const binding = parsed.binding;
|
|
117
|
-
const validationOwner = createAgentSessionValidationOwner(capabilities, parsed.sessionId);
|
|
136
|
+
const validationOwner = createAgentSessionValidationOwner(capabilities, parsed.sessionId, void 0, executionInput);
|
|
118
137
|
const interactions = createSessionInteractionOwner({
|
|
119
138
|
providerKey: capabilities.providerKey,
|
|
120
139
|
sessionId: parsed.sessionId,
|
|
@@ -178,6 +197,13 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
178
197
|
support: hostBinding,
|
|
179
198
|
open: async (lease) => {
|
|
180
199
|
throwIfAgentOperationAborted(branchInput.signal);
|
|
200
|
+
if (Reflect.has(branchInput, "output")) {
|
|
201
|
+
throwAgentProviderContractError(
|
|
202
|
+
capabilities.providerKey,
|
|
203
|
+
"structured_output_unsupported",
|
|
204
|
+
"Structured-output requests are unsupported when branching a session."
|
|
205
|
+
);
|
|
206
|
+
}
|
|
181
207
|
const parsed = parseAgentSessionOpenInput({
|
|
182
208
|
operation: "branch",
|
|
183
209
|
sessionId: branchInput.sessionId,
|
|
@@ -195,7 +221,7 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
195
221
|
branchInput.workingDirectory
|
|
196
222
|
);
|
|
197
223
|
const sourceBinding = parsed.source.binding;
|
|
198
|
-
const validationOwner = createAgentSessionValidationOwner(capabilities, parsed.sessionId);
|
|
224
|
+
const validationOwner = createAgentSessionValidationOwner(capabilities, parsed.sessionId, void 0, executionInput);
|
|
199
225
|
const interactions = createSessionInteractionOwner({
|
|
200
226
|
providerKey: capabilities.providerKey,
|
|
201
227
|
sessionId: parsed.sessionId,
|
|
@@ -317,7 +343,8 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
317
343
|
const parsed = parseAgentSessionOpenInput({
|
|
318
344
|
operation: "create",
|
|
319
345
|
sessionId: createInput.sessionId,
|
|
320
|
-
configuration: createInput.configuration
|
|
346
|
+
configuration: createInput.configuration,
|
|
347
|
+
...createInput.output === void 0 ? {} : { output: createInput.output }
|
|
321
348
|
});
|
|
322
349
|
assertAgentSessionConfigurationSupported(
|
|
323
350
|
capabilities,
|
|
@@ -326,7 +353,12 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
326
353
|
const workingDirectory = parseWorkingDirectory(
|
|
327
354
|
createInput.workingDirectory
|
|
328
355
|
);
|
|
329
|
-
const
|
|
356
|
+
const structuredOutputBinding = admitAgentStructuredOutputOpening({
|
|
357
|
+
capabilities,
|
|
358
|
+
operation: "create",
|
|
359
|
+
output: parsed.operation === "create" ? parsed.output : void 0
|
|
360
|
+
});
|
|
361
|
+
const validationOwner = createAgentSessionValidationOwner(capabilities, parsed.sessionId, structuredOutputBinding, executionInput);
|
|
330
362
|
const interactions = createSessionInteractionOwner({
|
|
331
363
|
providerKey: capabilities.providerKey,
|
|
332
364
|
sessionId: parsed.sessionId,
|
|
@@ -357,6 +389,7 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
357
389
|
sessionId: parsed.sessionId,
|
|
358
390
|
workingDirectory,
|
|
359
391
|
configuration: parsed.configuration,
|
|
392
|
+
...structuredOutputBinding === void 0 ? {} : { output: structuredOutputBinding.request },
|
|
360
393
|
onBindingCreated: observer,
|
|
361
394
|
...lease === void 0 ? {} : { hostBinding: lease.binding },
|
|
362
395
|
...interactions === void 0 ? {} : { interactions: interactions.facade },
|
|
@@ -367,6 +400,7 @@ function validateAgentProviderAdapter(capabilityInput, adapterInput) {
|
|
|
367
400
|
}
|
|
368
401
|
});
|
|
369
402
|
const openingAdapter = Object.freeze({
|
|
403
|
+
...executionInput === void 0 ? {} : { executionInput },
|
|
370
404
|
hostBinding,
|
|
371
405
|
sessionInteractions,
|
|
372
406
|
nativeContinuations,
|
package/dist/contractErrors.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { AgentProviderKey } from "@agen-ai/agent-protocol";
|
|
2
2
|
import type { MaybePromise } from "./foundation.js";
|
|
3
|
-
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", "invalid_inventory", "invalid_collaboration_transition", "input_operation_mismatch", "output_session_mismatch", "output_turn_mismatch", "output_authentication_attempt_mismatch", "output_operation_mismatch", "output_collaboration_mismatch", "output_resource_mismatch", "output_capability_mismatch", "input_capability_mismatch", "invalid_turn_sequence", "request_resolution_mismatch", "request_identity_limit_exceeded", "configuration_key_unsupported", "configuration_value_unsupported", "request_pending", "invalid_host_binding", "host_binding_unsupported", "host_binding_reused", "host_binding_closed", "host_tool_name_conflict", "host_tool_input_invalid", "host_tool_result_invalid", "host_tool_capacity_exhausted", "invalid_session_interaction", "session_interactions_unsupported", "native_continuations_unsupported", "native_continuation_preparation_failed", "native_continuation_reader_not_ready", "native_continuation_limit_exceeded", "invalid_native_continuation"];
|
|
3
|
+
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", "invalid_inventory", "invalid_collaboration_transition", "input_operation_mismatch", "output_session_mismatch", "output_turn_mismatch", "output_authentication_attempt_mismatch", "output_operation_mismatch", "output_collaboration_mismatch", "output_resource_mismatch", "output_capability_mismatch", "input_capability_mismatch", "invalid_turn_sequence", "request_resolution_mismatch", "request_identity_limit_exceeded", "configuration_key_unsupported", "configuration_value_unsupported", "request_pending", "invalid_host_binding", "host_binding_unsupported", "host_binding_reused", "host_binding_closed", "host_tool_name_conflict", "host_tool_input_invalid", "host_tool_result_invalid", "host_tool_capacity_exhausted", "invalid_session_interaction", "session_interactions_unsupported", "native_continuations_unsupported", "native_continuation_preparation_failed", "native_continuation_reader_not_ready", "native_continuation_limit_exceeded", "invalid_native_continuation", "structured_output_unsupported", "structured_output_scope_mismatch", "invalid_structured_output", "execution_input_capacity_exhausted", "execution_input_identity_reused", "execution_input_identity_limit_exceeded", "execution_input_correlation_lost"];
|
|
4
4
|
export type AgentProviderContractErrorCode = (typeof AGENT_PROVIDER_CONTRACT_ERROR_CODES)[number];
|
|
5
|
-
export type AgentProviderDelegatedOperation = "resolve_request" | "steer_turn" | "invoke_operation" | "apply_configuration" | "spawn_collaboration" | "control_collaboration";
|
|
5
|
+
export type AgentProviderDelegatedOperation = "resolve_request" | "steer_turn" | "send_execution_input" | "invoke_operation" | "apply_configuration" | "spawn_collaboration" | "control_collaboration";
|
|
6
6
|
export declare class AgentProviderContractError extends Error {
|
|
7
7
|
readonly providerKey: AgentProviderKey;
|
|
8
8
|
readonly code: AgentProviderContractErrorCode;
|
package/dist/contractErrors.js
CHANGED
|
@@ -44,7 +44,14 @@ const AGENT_PROVIDER_CONTRACT_ERROR_CODES = [
|
|
|
44
44
|
"native_continuation_preparation_failed",
|
|
45
45
|
"native_continuation_reader_not_ready",
|
|
46
46
|
"native_continuation_limit_exceeded",
|
|
47
|
-
"invalid_native_continuation"
|
|
47
|
+
"invalid_native_continuation",
|
|
48
|
+
"structured_output_unsupported",
|
|
49
|
+
"structured_output_scope_mismatch",
|
|
50
|
+
"invalid_structured_output",
|
|
51
|
+
"execution_input_capacity_exhausted",
|
|
52
|
+
"execution_input_identity_reused",
|
|
53
|
+
"execution_input_identity_limit_exceeded",
|
|
54
|
+
"execution_input_correlation_lost"
|
|
48
55
|
];
|
|
49
56
|
class AgentProviderContractError extends Error {
|
|
50
57
|
constructor(providerKey, code, message, options) {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { AgentExecutionInput, AgentExecutionInputMessage, AgentExecutionInputMessageId, AgentExecutionInputOutcome, AgentExecutionInputReceipt, AgentExecutionInputSupport, } from "./types.js";
|
|
2
|
+
export { parseAgentExecutionInputMessageId } from "./validation.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AgentProviderKey, AgentTurnId } from "@agen-ai/agent-protocol";
|
|
2
|
+
import type { AgentExecutionInput, AgentExecutionInputMessage, AgentExecutionInputMessageId, AgentExecutionInputOutcome, AgentExecutionInputReceipt, AgentExecutionInputSupport } from "./types.js";
|
|
3
|
+
export declare function createExecutionInputCensus(providerKey: AgentProviderKey, exhausted: () => void): {
|
|
4
|
+
claim(messageId: AgentExecutionInputMessageId): void;
|
|
5
|
+
};
|
|
6
|
+
type UnconfirmedReason = Extract<AgentExecutionInputOutcome, {
|
|
7
|
+
status: "unconfirmed";
|
|
8
|
+
}>["reason"];
|
|
9
|
+
type SupportedInput = Extract<AgentExecutionInput, {
|
|
10
|
+
kind: "supported";
|
|
11
|
+
}>;
|
|
12
|
+
/** One execution's admission and observations; the existing execution owns its native output reader. */
|
|
13
|
+
export declare function createExecutionInputOwner(input: Readonly<{
|
|
14
|
+
providerKey: AgentProviderKey;
|
|
15
|
+
turnId: AgentTurnId;
|
|
16
|
+
support: Extract<AgentExecutionInputSupport, {
|
|
17
|
+
kind: "supported";
|
|
18
|
+
}>;
|
|
19
|
+
census: ReturnType<typeof createExecutionInputCensus>;
|
|
20
|
+
signal: AbortSignal;
|
|
21
|
+
requireAdmission: () => void;
|
|
22
|
+
fence: () => void;
|
|
23
|
+
}>): {
|
|
24
|
+
port: Readonly<{
|
|
25
|
+
kind: "supported";
|
|
26
|
+
support: Readonly<{
|
|
27
|
+
kind: "supported";
|
|
28
|
+
delivery: "current_or_owned_continuation";
|
|
29
|
+
consumptionReporting: "message_ids" | "unavailable";
|
|
30
|
+
input: import("@agen-ai/agent-protocol").AgentOperationInputCapability;
|
|
31
|
+
limits: Readonly<{
|
|
32
|
+
maxOutstandingMessages: number;
|
|
33
|
+
maxMessagesPerExecution: number;
|
|
34
|
+
maxBufferedBytes: number;
|
|
35
|
+
}>;
|
|
36
|
+
}>;
|
|
37
|
+
sendMessage: (candidate: AgentExecutionInputMessage) => Promise<AgentExecutionInputReceipt>;
|
|
38
|
+
}>;
|
|
39
|
+
attach(port: SupportedInput): void;
|
|
40
|
+
closeAdmission: (reason?: UnconfirmedReason) => void;
|
|
41
|
+
drain(producer?: Promise<void>): Promise<void>;
|
|
42
|
+
join: (producer?: Promise<void>) => Promise<void>;
|
|
43
|
+
readonly failed: boolean;
|
|
44
|
+
readonly retainsOwnership: boolean;
|
|
45
|
+
};
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=lifetime.d.ts.map
|