@agen-ai/provider-acp 0.0.0-stage → 0.4.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.
- package/LICENSE +21 -0
- package/README.md +480 -2
- package/dist/auth/controller.d.ts +23 -0
- package/dist/auth/controller.js +170 -0
- package/dist/auth/methods.d.ts +12 -0
- package/dist/auth/methods.js +51 -0
- package/dist/capabilities.d.ts +4 -0
- package/dist/capabilities.js +46 -0
- package/dist/configuration/catalog.d.ts +35 -0
- package/dist/configuration/catalog.js +222 -0
- package/dist/configuration/control.d.ts +19 -0
- package/dist/configuration/control.js +109 -0
- package/dist/configuration/errors.d.ts +6 -0
- package/dist/configuration/errors.js +15 -0
- package/dist/configuration.d.ts +3 -0
- package/dist/configuration.js +9 -0
- package/dist/connection/acquire.d.ts +6 -0
- package/dist/connection/acquire.js +30 -0
- package/dist/connection/contracts.d.ts +28 -0
- package/dist/connection/contracts.js +0 -0
- package/dist/connection/errors.d.ts +5 -0
- package/dist/connection/errors.js +11 -0
- package/dist/connection/initialize.d.ts +16 -0
- package/dist/connection/initialize.js +225 -0
- package/dist/connection/negotiation.d.ts +6 -0
- package/dist/connection/negotiation.js +43 -0
- package/dist/contracts.d.ts +62 -0
- package/dist/contracts.js +0 -0
- package/dist/driver.d.ts +4 -0
- package/dist/driver.js +44 -0
- package/dist/environment/commands.d.ts +17 -0
- package/dist/environment/commands.js +104 -0
- package/dist/host/contracts.d.ts +108 -0
- package/dist/host/contracts.js +0 -0
- package/dist/host/interactions.d.ts +22 -0
- package/dist/host/interactions.js +146 -0
- package/dist/host/leases.d.ts +18 -0
- package/dist/host/leases.js +69 -0
- package/dist/host/lifecycle.d.ts +9 -0
- package/dist/host/lifecycle.js +56 -0
- package/dist/host/router.d.ts +47 -0
- package/dist/host/router.js +165 -0
- package/dist/host/terminals.d.ts +15 -0
- package/dist/host/terminals.js +94 -0
- package/dist/host/validation.d.ts +13 -0
- package/dist/host/validation.js +69 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +10 -0
- package/dist/instance.d.ts +20 -0
- package/dist/instance.js +248 -0
- package/dist/limits.d.ts +14 -0
- package/dist/limits.js +42 -0
- package/dist/mcp.d.ts +9 -0
- package/dist/mcp.js +62 -0
- package/dist/node/contracts.d.ts +15 -0
- package/dist/node/contracts.js +0 -0
- package/dist/node/index.d.ts +6 -0
- package/dist/node/index.js +20 -0
- package/dist/node/launch.d.ts +10 -0
- package/dist/node/launch.js +36 -0
- package/dist/node/process.d.ts +4 -0
- package/dist/node/process.js +98 -0
- package/dist/session/completion.d.ts +4 -0
- package/dist/session/completion.js +59 -0
- package/dist/session/create.d.ts +21 -0
- package/dist/session/create.js +27 -0
- package/dist/session/errors.d.ts +6 -0
- package/dist/session/errors.js +15 -0
- package/dist/session/files.d.ts +8 -0
- package/dist/session/files.js +35 -0
- package/dist/session/mapping.d.ts +36 -0
- package/dist/session/mapping.js +231 -0
- package/dist/session/media.d.ts +5 -0
- package/dist/session/media.js +22 -0
- package/dist/session/native.d.ts +7 -0
- package/dist/session/native.js +34 -0
- package/dist/session/opening.d.ts +22 -0
- package/dist/session/opening.js +67 -0
- package/dist/session/plans.d.ts +5 -0
- package/dist/session/plans.js +20 -0
- package/dist/session/queue.d.ts +32 -0
- package/dist/session/queue.js +105 -0
- package/dist/session/requests/elicitation.d.ts +14 -0
- package/dist/session/requests/elicitation.js +24 -0
- package/dist/session/requests/forms.d.ts +31 -0
- package/dist/session/requests/forms.js +241 -0
- package/dist/session/requests/pending.d.ts +46 -0
- package/dist/session/requests/pending.js +79 -0
- package/dist/session/requests/resolution.d.ts +5 -0
- package/dist/session/requests/resolution.js +32 -0
- package/dist/session/resources.d.ts +30 -0
- package/dist/session/resources.js +99 -0
- package/dist/session/session.d.ts +43 -0
- package/dist/session/session.js +479 -0
- package/dist/session/turn.d.ts +33 -0
- package/dist/session/turn.js +0 -0
- package/package.json +58 -3
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
CHANGED
|
@@ -1,3 +1,481 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @agen-ai/provider-acp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An optional provider for the AgenAI coding-agent runtime. It translates the stable
|
|
4
|
+
Agent Client Protocol wire version 1 into the existing Agent Protocol V10 session
|
|
5
|
+
API at coordinated SDK version `0.4.0`.
|
|
6
|
+
The package is ESM, MIT licensed, side-effect-free on import and requires Node.js
|
|
7
|
+
22 or newer. It depends only on the public transport, runtime and protocol packages;
|
|
8
|
+
the core packages remain independent of ACP.
|
|
9
|
+
|
|
10
|
+
The provider pins the transport's `schema-v1.23.0` stable profile. It translates
|
|
11
|
+
ACP into existing V10 capabilities and rejects unsupported semantics explicitly.
|
|
12
|
+
Connection negotiation, configured host facilities, and mapping policy fix one
|
|
13
|
+
capability envelope per instance; every later connection must match it.
|
|
14
|
+
|
|
15
|
+
## Unknown extensions
|
|
16
|
+
|
|
17
|
+
Both `createAcpProviderDriver` and `createNodeAcpProviderDriver` default to
|
|
18
|
+
`unknownExtensionPolicy: 'standard'`. This deliberately changes the public
|
|
19
|
+
provider default in `0.4.0`. Direct transport clients
|
|
20
|
+
continue to default to `'reject'`. AgenAI's controlled private Hostd composition
|
|
21
|
+
explicitly selects `'reject'`; public interoperability does not change that policy.
|
|
22
|
+
|
|
23
|
+
Standard handling discards otherwise unregistered underscore notifications after
|
|
24
|
+
the transport's envelope, size and notification-rate checks. An unsupported
|
|
25
|
+
underscore request receives a correlated `-32601` response without invoking a
|
|
26
|
+
host callback. Core methods, exact registered extensions and protocol controls
|
|
27
|
+
keep their existing validation; malformed registered payloads and unknown `$/`
|
|
28
|
+
controls still fail the connection. Ignoring an optional message such as
|
|
29
|
+
`_x.ai/mcp/servers_updated` establishes no MCP tool exposure or feature support.
|
|
30
|
+
Discarded notifications produce no neutral event or effect authority. Request
|
|
31
|
+
errors remain within the existing outbound byte/backpressure budget and retain
|
|
32
|
+
their IDs until writing finishes; all other transport/provider bounds remain
|
|
33
|
+
unchanged. Required vendor features still need an explicit supported mapping.
|
|
34
|
+
|
|
35
|
+
Set `unknownExtensionPolicy: 'reject'` on either provider constructor to retain
|
|
36
|
+
strict handling on every connection, including authentication reconnects and
|
|
37
|
+
native resume. Only `undefined` selects the default; other values outside
|
|
38
|
+
`'standard'` and `'reject'` throw `TypeError` before connection acquisition or
|
|
39
|
+
process launch. The constructor captures the resolved policy, so later mutation
|
|
40
|
+
of its options cannot change it. The policy is host composition and is absent
|
|
41
|
+
from the closed, empty serialized `driverConfiguration`. Changing policy needs
|
|
42
|
+
a fresh driver and materialization; uncertain native work must not be retried
|
|
43
|
+
under a different policy.
|
|
44
|
+
|
|
45
|
+
## Capability matrix
|
|
46
|
+
|
|
47
|
+
| Surface | Supported behavior and requirements |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| Turns and requests | Default text turns, streamed assistant/reasoning text, tool progress, cancellation and once-only exact-action permissions. One execution retains the original native prompt across request waits and answers. |
|
|
50
|
+
| Resume | Exact persisted binding using advertised `session/resume`, otherwise advertised `session/load`. Load history is bounded and suppressed from new-turn output. No automatic recreation after failure. |
|
|
51
|
+
| Configuration | Managed by default. Explicit `configuration: 'selectable'` maps observed boolean/select catalogs, with a session-mode fallback when config options are absent. Unknown metadata differs from observed empty metadata. |
|
|
52
|
+
| Forms | Canonical boolean/single-select/multi-select forms that fit V10 constraints. An intent stage preserves decline separately from cancel, followed by answers on the same native waiter. Explicit host form facilities can handle broader native forms. |
|
|
53
|
+
| Images | Inline base64 PNG/JPEG/WebP only when the peer advertises image input, within image and total turn budgets. No implicit local-file read or URL fetch. |
|
|
54
|
+
| Plans | Complete replacements of observed turn plans. A mode called “plan” does not establish enforced planning behavior or approval authority. |
|
|
55
|
+
| File changes | Partial structured observations from native tool diffs. Canonical paths contained by the working directory become sorted relative display paths without filesystem reads. Unfinished tools remain unknown at ordinary turn completion. No final workspace diff or Review artifact is inferred. |
|
|
56
|
+
| Commands | Session catalogs and invalidations from `available_commands_update`. Missing metadata remains uninitialized; an observed empty list is available and empty. |
|
|
57
|
+
| Authentication | Explicit method-to-flow selection and host interaction facilities. Agent methods retain the authenticated connection; terminal methods require a host facility and fresh verified initialization afterward. |
|
|
58
|
+
| Files and terminals | Explicit host callbacks, correlated to the bound native session. Terminal support requires the complete output/wait/kill/release lifecycle; embedded terminal transcript references remain unsupported. |
|
|
59
|
+
| MCP setup | Static host-approved `mcpServers` and optional owned `sessionMcpBinding` factory for creation/resume. HTTP/SSE require advertised peer support. Configuration is not observed tool exposure. |
|
|
60
|
+
|
|
61
|
+
Through-turn branching, same-turn steering, enforced plan mode, persistent
|
|
62
|
+
permission grants, context usage/compaction, account quota, effective skill/rule
|
|
63
|
+
inventory, collaboration, generated resources and artifact publication remain
|
|
64
|
+
unsupported. ACP usage counters can decrease without confirmed compaction and
|
|
65
|
+
cannot satisfy V10's context continuity contract. Unsupported media output fails
|
|
66
|
+
explicitly rather than disappearing from an otherwise successful transcript.
|
|
67
|
+
Embedded terminal references also fail explicitly: a mutable, possibly truncated
|
|
68
|
+
terminal snapshot does not provide an ordered append-only transcript. Agents can
|
|
69
|
+
use terminal RPCs and emit their observed output as ordinary text/tool content.
|
|
70
|
+
|
|
71
|
+
ACP administration (list/delete/logout/import) has no portable provider API in
|
|
72
|
+
this release. Host-owned integrations may use the transport directly with their
|
|
73
|
+
own authorization and native lifecycle policy. No capability grants authority
|
|
74
|
+
over other conversations or account state.
|
|
75
|
+
|
|
76
|
+
## Operational failures and uncertainty
|
|
77
|
+
|
|
78
|
+
The provider maps supported standard `schema-v1.23.0` prompt errors into V10 `AgentError` values.
|
|
79
|
+
Standard `-32000` reports `authentication` with an `authenticate` user-action hint; `-32602` reports
|
|
80
|
+
`invalid_request`; `-32603` reports `provider`; standard parse/request/method errors report `protocol`.
|
|
81
|
+
Other remote codes remain `unknown` with unknown recovery. Mapping uses the standard error code,
|
|
82
|
+
without copying remote messages, arbitrary data or xAI-specific meanings into a canonical failure.
|
|
83
|
+
Generic ACP does not infer rate limits or exhausted allowance from vendor code `-32003`, and its
|
|
84
|
+
account-quota capability remains unsupported.
|
|
85
|
+
|
|
86
|
+
A validated prompt error response establishes a failed terminal result. A lost response, process loss,
|
|
87
|
+
or unconfirmed cancellation after dispatch does not establish that result; preserve uncertainty and
|
|
88
|
+
close the unusable session without replaying its prompt. Operational classification cannot override
|
|
89
|
+
native settlement or cleanup ownership. The provider does not infer `runtime.retrying` from an RPC
|
|
90
|
+
failure, add a retry loop or enable a vendor retry extension. A future faithful mapping still needs
|
|
91
|
+
explicit native evidence and turn correlation.
|
|
92
|
+
|
|
93
|
+
## Explicit Node process launch
|
|
94
|
+
|
|
95
|
+
Import process construction through the exact `/node` entrypoint. Supply an
|
|
96
|
+
absolute executable and working directory. Arguments are literal strings and
|
|
97
|
+
spawning always uses `shell: false`. Only the supplied environment is passed to
|
|
98
|
+
the child; the current process environment is never inherited.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import {
|
|
102
|
+
parseAgentConfigurationRevisionId,
|
|
103
|
+
parseAgentInstanceId,
|
|
104
|
+
parseAgentProviderKey,
|
|
105
|
+
parseAgentSessionId,
|
|
106
|
+
parseAgentTurnId,
|
|
107
|
+
} from '@agen-ai/agent-protocol';
|
|
108
|
+
import {
|
|
109
|
+
createAgentProviderRegistry,
|
|
110
|
+
isAgentProviderSessionCleanupErrorFor,
|
|
111
|
+
type AgentProviderCreateSessionInput,
|
|
112
|
+
type AgentProviderSession,
|
|
113
|
+
} from '@agen-ai/agent-runtime';
|
|
114
|
+
import { createNodeAcpProviderDriver } from '@agen-ai/provider-acp/node';
|
|
115
|
+
|
|
116
|
+
const providerKey = parseAgentProviderKey('my-acp-agent');
|
|
117
|
+
const instanceId = parseAgentInstanceId('my-agent:primary');
|
|
118
|
+
const driver = createNodeAcpProviderDriver({
|
|
119
|
+
providerKey,
|
|
120
|
+
launch: {
|
|
121
|
+
executable: '/opt/my-agent/bin/agent',
|
|
122
|
+
args: ['--acp'],
|
|
123
|
+
cwd: '/work/project',
|
|
124
|
+
env: { HOME: '/work/agent-home', PATH: '/usr/bin:/bin' },
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const registry = await createAgentProviderRegistry({
|
|
128
|
+
drivers: [driver],
|
|
129
|
+
definitions: [{ providerKey, instanceId, driverConfiguration: {} }],
|
|
130
|
+
});
|
|
131
|
+
const instance = registry.requireInstance(instanceId);
|
|
132
|
+
const openingInput: AgentProviderCreateSessionInput = {
|
|
133
|
+
sessionId: parseAgentSessionId('session:example'),
|
|
134
|
+
workingDirectory: '/work/project',
|
|
135
|
+
configuration: {
|
|
136
|
+
kind: 'managed',
|
|
137
|
+
revision: parseAgentConfigurationRevisionId('configuration:1'),
|
|
138
|
+
},
|
|
139
|
+
onBindingCreated(binding) {
|
|
140
|
+
// Persist this exact opaque binding before proceeding with application work.
|
|
141
|
+
console.log(binding);
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
let session: AgentProviderSession | undefined;
|
|
145
|
+
let retainedOpeningCleanup = false;
|
|
146
|
+
try {
|
|
147
|
+
try {
|
|
148
|
+
session = await instance.adapter.createSession(openingInput);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
retainedOpeningCleanup = isAgentProviderSessionCleanupErrorFor(error, openingInput);
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
const execution = session.startTurn({
|
|
154
|
+
turnId: parseAgentTurnId('turn:example'),
|
|
155
|
+
interactionMode: 'default',
|
|
156
|
+
parts: [{ type: 'text', text: 'Explain this project.' }],
|
|
157
|
+
});
|
|
158
|
+
for await (const output of execution.outputs) {
|
|
159
|
+
console.log(output);
|
|
160
|
+
}
|
|
161
|
+
} finally {
|
|
162
|
+
if (!retainedOpeningCleanup) {
|
|
163
|
+
await session?.close({ reason: 'shutdown' });
|
|
164
|
+
await registry.dispose();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
An exact failed-opening cleanup receipt keeps the registry owned. Retain the receipt and call its
|
|
170
|
+
`retryCleanup()` before disposing the registry. A failed session close likewise skips registry
|
|
171
|
+
disposal; retain that session and retry its cleanup before releasing dependent owners.
|
|
172
|
+
|
|
173
|
+
The registry validates instance, adapter, capability, and canonical output
|
|
174
|
+
contracts. `startTurn` reserves one execution; its native prompt starts lazily
|
|
175
|
+
when `execution.outputs` is first consumed. Keep one output consumer through
|
|
176
|
+
actual terminal settlement. Requests are installed before `request.opened`, so
|
|
177
|
+
an answer can be sent immediately from that event with
|
|
178
|
+
`await execution.resolveRequest({ resolution })`, independently of the next
|
|
179
|
+
output pull. One canonical request is offered at a time; additional bounded
|
|
180
|
+
native callbacks retain FIFO order while unrelated output continues.
|
|
181
|
+
The immediate `await` above is appropriate once the answer is already available. If a person must
|
|
182
|
+
choose it, enqueue the exact request to a separately owned, signal-aware handler and keep pulling
|
|
183
|
+
outputs; join that handler after initiating cancellation and close. The public
|
|
184
|
+
[live-output example](../../examples/live-request-output.ts) demonstrates the ownership without
|
|
185
|
+
native launch or credentials, and the [migration guide](../../MIGRATING-TO-0.4.md) shows before/after code.
|
|
186
|
+
|
|
187
|
+
The response Promise reports `delivered`, `rejected` with `requestState` of
|
|
188
|
+
`pending` or `unavailable`, or `delivery_uncertain`. For ACP, `delivered` means the
|
|
189
|
+
exact still-live local callback accepted the answer, or the canonical form flow
|
|
190
|
+
accepted its intent step. An intent receipt does not await the fields answer.
|
|
191
|
+
The later JSON-RPC write has no peer acknowledgment; delivery does not establish
|
|
192
|
+
wire receipt or model consumption. A later transport failure belongs to the
|
|
193
|
+
original execution's output and cannot revoke an accepted response or authorize
|
|
194
|
+
its replay. Local input/correlation and pre-abort failures reject with their
|
|
195
|
+
precise errors. Do not retry an uncertain response or prompt.
|
|
196
|
+
Only `rejected/pending` preserves the exact response's eligibility for a fresh valid answer.
|
|
197
|
+
`rejected/unavailable` removes it without completing the original execution. Request expiry,
|
|
198
|
+
accepted interruption and observed terminality fence later answers; an older waiting observation
|
|
199
|
+
never restores that eligibility. Close starts native cancellation before joining response work.
|
|
200
|
+
If cleanup fails, retain the session or exact opening-cleanup receipt and its dependent registry/MCP
|
|
201
|
+
resources until the owned retry succeeds.
|
|
202
|
+
|
|
203
|
+
The `startTurn` signal and deadline govern the entire native prompt, including
|
|
204
|
+
time spent waiting for permission or a form answer. Keep them valid through
|
|
205
|
+
terminal settlement. `execution.resolveRequest` has its own operation signal,
|
|
206
|
+
which does not replace the original prompt lifetime. Await each output
|
|
207
|
+
destination's acknowledgement before advancing the iterator. Persist the exact
|
|
208
|
+
opaque binding before application work; a display log is not durable session
|
|
209
|
+
storage.
|
|
210
|
+
|
|
211
|
+
To launch a registry installation, first acquire an exact installation reference
|
|
212
|
+
and resolve its verified recipe through `@agen-ai/acp-registry/node`. Pass the
|
|
213
|
+
absolute executable, literal arguments and approved environment to this same
|
|
214
|
+
constructor. Retain that reference until every session and owned process has
|
|
215
|
+
successfully closed. Startup or disposal failure does not authorize releasing it;
|
|
216
|
+
the host must retain ownership and establish native-process quiescence.
|
|
217
|
+
|
|
218
|
+
## Injected connections and ownership
|
|
219
|
+
|
|
220
|
+
The root entrypoint exports `createAcpProviderDriver`. Its constructor accepts
|
|
221
|
+
`providerKey`, `createConnection`, and optional `limits`, `configuration`,
|
|
222
|
+
`authentication`, `host`, `mcpServers`, and `sessionMcpBinding`. The connection factory receives the public
|
|
223
|
+
`instanceId` and an initialization `signal`. Return fresh, exclusive Node
|
|
224
|
+
`stdout`, `stdin`, and optional `stderr` streams for every invocation, with one of:
|
|
225
|
+
|
|
226
|
+
- `{ ownership: 'owned', stdout, stdin, stderr?, release }`: the provider invokes
|
|
227
|
+
the lease's idempotent release callback when it closes the connection.
|
|
228
|
+
Concurrent cleanup is coalesced, successful release is retained, and failed
|
|
229
|
+
cleanup can be explicitly retried through session or registry disposal.
|
|
230
|
+
- `{ ownership: 'borrowed', stdout, stdin, stderr? }`: the provider removes its
|
|
231
|
+
stream listeners on close and leaves stream destruction to the caller.
|
|
232
|
+
|
|
233
|
+
The factory owns acquisition work until it returns a lease and must honor its
|
|
234
|
+
abort signal. Initialization has one deadline covering acquisition and the
|
|
235
|
+
initialize request. If an uncooperative factory delivers an owned lease after
|
|
236
|
+
that deadline, the provider invokes its release callback asynchronously; callers
|
|
237
|
+
remain responsible for factory work that never returns a lease. A release
|
|
238
|
+
callback owns only the resources of its own lease.
|
|
239
|
+
|
|
240
|
+
Materialization eagerly initializes one connection and reserves it for the
|
|
241
|
+
first session. Later sessions acquire fresh connections, verify the same frozen
|
|
242
|
+
initialization envelope, then create their own native session. Driver
|
|
243
|
+
configuration is strictly `{}`; launch and connection authority belong to the
|
|
244
|
+
driver constructor. The built-in `/node` launcher supports POSIX systems and creates
|
|
245
|
+
a separate process group for each connection. Closing a session or instance sends
|
|
246
|
+
`SIGTERM` to that group, then escalates to `SIGKILL` if necessary. Each phase waits
|
|
247
|
+
up to `shutdownTimeoutMs`; successful cleanup requires both group disappearance and
|
|
248
|
+
closed child streams, including when the leader exited first or descendants closed
|
|
249
|
+
their streams. Failed cleanup remains available for explicit retry.
|
|
250
|
+
|
|
251
|
+
This process-group ownership is not a sandbox: descendants that deliberately leave
|
|
252
|
+
the group require host-provided OS containment. The host must reap exited children.
|
|
253
|
+
The built-in launcher rejects Windows before spawning with
|
|
254
|
+
`acp_provider_process_platform_unsupported`. Windows hosts can use
|
|
255
|
+
`createAcpProviderDriver` with an owned connection factory backed by their own process
|
|
256
|
+
supervisor, such as a Windows Job Object; the SDK does not supply a native Windows
|
|
257
|
+
process-tree launcher in `0.4.0`.
|
|
258
|
+
|
|
259
|
+
## Session-scoped MCP bindings
|
|
260
|
+
|
|
261
|
+
`sessionMcpBinding: { transport, create }` pairs a host-certified `http` or `sse` transport
|
|
262
|
+
with an owned factory. The provider declares runtime host-binding support only when that transport
|
|
263
|
+
was negotiated with the peer. The factory runs only when an opening carries a `hostBinding`, after
|
|
264
|
+
connection initialization and before native session creation or resume. Its trusted context carries
|
|
265
|
+
the instance/session IDs, working directory, opening operation, validated binding facade and an
|
|
266
|
+
acquisition signal. Parent identity never comes from a model tool argument.
|
|
267
|
+
|
|
268
|
+
An application using the optional orchestration package can compose its explicit bridge:
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
import { startDelegationMcpBridge } from "@agen-ai/agent-orchestration/mcp";
|
|
272
|
+
|
|
273
|
+
const sessionMcpBinding = {
|
|
274
|
+
transport: "http" as const,
|
|
275
|
+
async create({ hostBinding, signal }: import("@agen-ai/provider-acp").AcpSessionMcpBindingContext) {
|
|
276
|
+
const bridge = await startDelegationMcpBridge({ binding: hostBinding, signal });
|
|
277
|
+
return {
|
|
278
|
+
mcpServers: [{ type: "http" as const, name: bridge.server.name, url: bridge.server.url,
|
|
279
|
+
headers: Object.entries(bridge.server.headers).map(([name, value]) => ({ name, value })) }],
|
|
280
|
+
release: bridge.release,
|
|
281
|
+
};
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
// Supply sessionMcpBinding to either ACP driver constructor.
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Each opening needs a fresh binding and lease, including native resume. Dynamic entries must use the
|
|
288
|
+
declared transport and merge with static entries under the existing combined 32-server/512-KiB
|
|
289
|
+
limits. Duplicate names are rejected. The factory installs the binding's actual tools and
|
|
290
|
+
`tool_context` instructions; ACP does not claim a trusted system/developer instruction channel.
|
|
291
|
+
Neither the factory nor its transport may call the facade's `release`: the validated runtime owns
|
|
292
|
+
the original binding.
|
|
293
|
+
|
|
294
|
+
Factory rejection must leave no factory-owned producers. A partially acquired resource must remain
|
|
295
|
+
represented by an owned lease, including a lease delivered after cancellation. Closing quiesces
|
|
296
|
+
the native connection before releasing the MCP lease, then runtime closes the original binding.
|
|
297
|
+
`hostOperationTimeoutMs` bounds acquisition and cleanup waits without discarding the actual pending
|
|
298
|
+
factory or release promise. Pending or failed opening cleanup blocks new openings and authentication
|
|
299
|
+
changes until its retained responsibility is settled.
|
|
300
|
+
Failed opening cleanup retains an explicit retry receipt; failed or pending cleanup cannot be
|
|
301
|
+
treated as successful disposal. Ending a parent turn does not close its session binding or cancel
|
|
302
|
+
independently admitted children.
|
|
303
|
+
|
|
304
|
+
Advertising a transport and accepting a server list are configuration evidence. Qualify each real
|
|
305
|
+
agent/version separately with MCP initialization, tool discovery and an actual invocation. A peer
|
|
306
|
+
that accepts but never exposes tools is not qualified by this adapter. Configuration labels likewise
|
|
307
|
+
do not certify model, reasoning or fast-mode semantics: hosts must map exact selectable session
|
|
308
|
+
configuration, verify it before the first child prompt, and reject shared/global-only changes.
|
|
309
|
+
|
|
310
|
+
From the public SDK repository root, `pnpm examples:delegation:acp` runs a credentialless peer that
|
|
311
|
+
actually discovers and invokes the managed tools. It applies synthetic Standard/Max configuration
|
|
312
|
+
before the child prompt, lets the parent turn finish while the child waits for approval, and later
|
|
313
|
+
delivers the completion through another authorized parent turn. See `examples/delegation/README.md`
|
|
314
|
+
for the shared direct and qualified durable workflows. These fixtures do not qualify a real native
|
|
315
|
+
agent/version. Required vendor features still need an exact supported mapping, and explicit reject
|
|
316
|
+
policy can prevent session opening after successful initialization when the peer emits an
|
|
317
|
+
unregistered vendor extension. AgenAI Workspaces preferences and Hostd production rollout remain
|
|
318
|
+
separate product work.
|
|
319
|
+
|
|
320
|
+
In the standalone repository, the separate opt-in
|
|
321
|
+
[native qualification example](../../examples/delegation/native/README.md) documents the exact
|
|
322
|
+
Grok Build `1.0.50` (`c58f321264ba`) Linux x86_64 pairing qualified on 2026-10-11 with explicit API-key
|
|
323
|
+
authentication, `grok-4.3`, `Low` reasoning and verified request-default standard mapping. Final MS003
|
|
324
|
+
r6 direct and retained-installation reports record actual managed callbacks and once-only approvals,
|
|
325
|
+
real child-result consumption in a later parent turn, cancellation after provider start and closed
|
|
326
|
+
cleanup. Retained mode observes installer exit before a fresh worker reopens the verified store.
|
|
327
|
+
Those immutable version-1 reports use the prior continuation API; the current version-2 execution
|
|
328
|
+
reports require fresh installed qualification. Current hermetic checks establish synthetic behavior.
|
|
329
|
+
The review-applicability record preserves those reports and separately qualifies later preflight,
|
|
330
|
+
deadline and diagnostic-cleanup repairs. The locally authored catalog and transformed binary prove
|
|
331
|
+
exact artifact/launch identity, without authenticating a publisher or certifying backend billing.
|
|
332
|
+
This scope does not qualify browser login, durable native recovery, private Hostd/fleet execution,
|
|
333
|
+
other native pairings, releases or platforms. The qualified SQLite reference remains separate.
|
|
334
|
+
|
|
335
|
+
The 2026-10-10 Grok Build `1.0.34` session-opening failure on `_x.ai/mcp/servers_updated` remains
|
|
336
|
+
historical evidence under the then-strict policy; it involved no model prompt or paid inference.
|
|
337
|
+
The public standard default does not retroactively qualify that binary.
|
|
338
|
+
|
|
339
|
+
## Configuration and resume
|
|
340
|
+
|
|
341
|
+
Choose `configuration: 'selectable'` at driver construction to expose the existing
|
|
342
|
+
runtime configuration port. Preserve native defaults with this bootstrap input:
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
const configuration = {
|
|
346
|
+
kind: 'selected' as const,
|
|
347
|
+
revision: parseAgentConfigurationRevisionId('configuration:1'),
|
|
348
|
+
catalogRevision: 1,
|
|
349
|
+
selections: [],
|
|
350
|
+
};
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
This reserved input is not evidence of an empty catalog. Read `listConfiguration`, present its offered
|
|
354
|
+
fields/options, and submit its exact catalog and field revisions through
|
|
355
|
+
`applyConfigurationSelection`.
|
|
356
|
+
|
|
357
|
+
Native field/option IDs remain behind opaque public IDs. Group labels preserve
|
|
358
|
+
their context. Empty optional descriptions normalize to an omitted description;
|
|
359
|
+
identifiers, labels and metadata bounds remain validated. Changed mapped catalogs advance revisions;
|
|
360
|
+
duplicate observations do not. The provider checks the offered revision immediately before local
|
|
361
|
+
dispatch and requires an acknowledged result. ACP supplies no peer-side
|
|
362
|
+
compare-and-set, so this is not an atomic remote-state guarantee. A dispatched
|
|
363
|
+
selection with a failed, lost or unconfirmed result makes the session unusable;
|
|
364
|
+
close and rematerialize without automatically replaying the selection.
|
|
365
|
+
|
|
366
|
+
Persist the exact binding supplied by `onBindingCreated` and pass it to the
|
|
367
|
+
runtime's normal `resumeSession`. Resume restores that conversation, not a
|
|
368
|
+
requested history anchor or fabricated branch. Load replay has total byte/message
|
|
369
|
+
bounds and an opening deadline. Historical permission requests are rejected.
|
|
370
|
+
|
|
371
|
+
## Host facilities and authentication
|
|
372
|
+
|
|
373
|
+
The typed `host` object supplies optional `form`, `url`, `readTextFile`,
|
|
374
|
+
`writeTextFile`, `createTerminal`, and `authenticateInTerminal` callbacks. There
|
|
375
|
+
are no ambient filesystem, terminal, browser, credential or environment fallbacks.
|
|
376
|
+
Callbacks receive the instance, authorized interaction/session scope and abort
|
|
377
|
+
signal. The application must enforce workspace, network, executable and user
|
|
378
|
+
policy before performing the requested operation. Paths and commands are requests,
|
|
379
|
+
not authorization; these callbacks do not create a sandbox.
|
|
380
|
+
|
|
381
|
+
A URL facility presents consent before opening a URL and never prefetches it. Its
|
|
382
|
+
lease supplies the user's accept/decline/cancel decision, optional completion,
|
|
383
|
+
and idempotent release. Publishing a URL does not count as acceptance. Out-of-turn
|
|
384
|
+
form/URL interactions must match an exact active session-control or authentication
|
|
385
|
+
RPC ID. Unknown/completed IDs are rejected; prompts do not acquire this authority.
|
|
386
|
+
|
|
387
|
+
Enable authentication with an exact selection such as
|
|
388
|
+
`authentication: { browser: { methodId: 'advertised-method-id' } }` and the host
|
|
389
|
+
interactions required by that agent. Browser/device-code flows require an
|
|
390
|
+
agent-managed method. Terminal flows require an advertised terminal method and
|
|
391
|
+
`host.authenticateInTerminal`, which reproduces the host-configured invocation
|
|
392
|
+
with the method's arguments/environment under host policy. Terminal login does
|
|
393
|
+
not send `authenticate` RPC. Native method labels are not used to guess flows.
|
|
394
|
+
|
|
395
|
+
The provider does not copy credentials between connections. A confirmed
|
|
396
|
+
agent-managed login retains that exact idle connection for the next session.
|
|
397
|
+
Authentication changes are rejected while sessions are active. An interrupted
|
|
398
|
+
attempt after dispatch may leave external account state uncertain; the provider
|
|
399
|
+
retires the connection and does not retry login automatically.
|
|
400
|
+
|
|
401
|
+
File callbacks are independently advertised. Terminal support requires a complete
|
|
402
|
+
facility. Handles are scoped to their connection/session; unknown or cross-session
|
|
403
|
+
handles never reach host callbacks. Leases own their resources even when ACP
|
|
404
|
+
streams are borrowed. Idempotent `release` must terminate a running owned process.
|
|
405
|
+
Hosts must honor abort signals; late-acquired leases are released after cancellation.
|
|
406
|
+
Pending terminal, URL and authentication lease acquisitions remain owned and count
|
|
407
|
+
against facility capacity. Disposal waits within the host-operation deadline and
|
|
408
|
+
fails if acquisition or release is still unresolved. Failed releases remain owned
|
|
409
|
+
for an explicit disposal retry; a successful disposal never hides pending cleanup.
|
|
410
|
+
File reads receive an explicit `maxBytes` bound so the host can reject oversized
|
|
411
|
+
content before allocating it; the provider never silently truncates a file response.
|
|
412
|
+
Terminal handles belong to the session and may span turns. Interrupting a prompt
|
|
413
|
+
does not prove that every terminal exited; native release or session/connection
|
|
414
|
+
close ends that handle's ownership. The host retains control over its process policy.
|
|
415
|
+
|
|
416
|
+
## Form and media limits
|
|
417
|
+
|
|
418
|
+
Canonical forms preflight the whole schema before presenting a request. They
|
|
419
|
+
support at most 16 ordinary fields and 100 choices per selection. Free-text fields,
|
|
420
|
+
nested objects, numeric fields, defaults, patterns/formats, and constraints without
|
|
421
|
+
a V10 representation are rejected. Native free text permits blank/whitespace values
|
|
422
|
+
and measures length in Unicode code points; V10 text answers use nonblank/UTF-16
|
|
423
|
+
bounds. The provider does not narrow those native semantics silently. Enumerated
|
|
424
|
+
string values can map through opaque canonical selection IDs.
|
|
425
|
+
A required multi-select must require exactly one minimum selection; an optional
|
|
426
|
+
multi-select must allow zero. Unsupported shapes never produce a partial form.
|
|
427
|
+
|
|
428
|
+
The first stage offers “Provide answers” (or “Accept” for an empty form) and
|
|
429
|
+
“Decline”. Canceling either stage returns native cancel; decline returns native
|
|
430
|
+
decline. Submitting the answer stage returns native accept with validated content.
|
|
431
|
+
Both stages hold one native request, adding a user step without prompt replay.
|
|
432
|
+
Active session forms use canonical requests when they fit the supported subset.
|
|
433
|
+
An explicit `host.form` callback handles valid broader forms directly, including
|
|
434
|
+
blank text, Unicode code-point bounds, numeric bounds and defaults without
|
|
435
|
+
canonical conversion. Exactly correlated control/auth forms also use that host
|
|
436
|
+
facility. The provider validates the entire native schema and the host's returned
|
|
437
|
+
content; patterns/formats remain unsupported before any callback. Session forms
|
|
438
|
+
and URL interactions require an active prompt; historical replay or an idle
|
|
439
|
+
binding grants no interaction authority. Their host callbacks receive a turn
|
|
440
|
+
lifetime signal that ends on cancellation, settlement or close.
|
|
441
|
+
|
|
442
|
+
Image input allows at most 16 images, 375,000 decoded bytes per image and 750,000
|
|
443
|
+
decoded bytes total, subject to the stricter 1 MiB V10 turn-content bound. Declared
|
|
444
|
+
media type, dimensions, base64 encoding and byte counts are validated. The provider
|
|
445
|
+
does not decode pixels or publish generated bytes; hosts needing image-content
|
|
446
|
+
inspection must perform it before submitting input.
|
|
447
|
+
|
|
448
|
+
## Bounds and evidence
|
|
449
|
+
|
|
450
|
+
`limits` can override `maxQueuedMessages`, `maxQueuedBytes`,
|
|
451
|
+
`maxPendingRequests`, `maxHostTerminals`, `hostOperationTimeoutMs`,
|
|
452
|
+
`authenticationTimeoutMs`, `initializationTimeoutMs`, `promptTimeoutMs`, and
|
|
453
|
+
`cancellationTimeoutMs`. Defaults share a 128-entry, 8 MiB budget across queued
|
|
454
|
+
sources and retained current-turn item state, with output/control headroom
|
|
455
|
+
reserved inside that budget. Large bursts and turns with many retained items
|
|
456
|
+
can exhaust the same budget. Defaults allow 16 pending requests, 16 host terminals,
|
|
457
|
+
30 seconds for initialization or a host operation, 15 minutes for authentication,
|
|
458
|
+
30 minutes for a prompt, and 5 seconds for cancellation. Admission
|
|
459
|
+
reserves finite source capacity synchronously. Response and cancellation
|
|
460
|
+
processing remain independent of slow output consumers. Overflow, malformed
|
|
461
|
+
messages, process loss, or unconfirmed cancellation fail closed and require
|
|
462
|
+
closing the unusable session before rematerialization.
|
|
463
|
+
|
|
464
|
+
Readiness reports completed initialization and the reported agent version when
|
|
465
|
+
available. It does not prove authentication or inference. The Node launcher
|
|
466
|
+
does not install agents, load credentials, apply a sandbox, or grant production
|
|
467
|
+
execution authority. Those responsibilities belong to the application. Tests
|
|
468
|
+
use synthetic processes and streams; they do not qualify a native agent,
|
|
469
|
+
authenticated account, paid inference, or a production host.
|
|
470
|
+
|
|
471
|
+
The selected schema is stable `schema-v1.23.0` at upstream commit
|
|
472
|
+
`6d08f412a7a1370d3cc9a124e3be3d6acf92641e`, using ACP wire version 1.
|
|
473
|
+
The package version, schema release and native agent version are separate identities.
|
|
474
|
+
Qualify the exact native release, target, credentials, toolchain and confinement
|
|
475
|
+
policy before relying on native behavior; initialization alone is a narrower claim.
|
|
476
|
+
|
|
477
|
+
```sh
|
|
478
|
+
pnpm --filter @agen-ai/provider-acp build
|
|
479
|
+
pnpm --filter @agen-ai/provider-acp typecheck
|
|
480
|
+
pnpm --filter @agen-ai/provider-acp test
|
|
481
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AgentAuthenticationFlow, AgentInstanceId } from '@agen-ai/agent-protocol';
|
|
2
|
+
import { type AgentProviderAuthentication } from '@agen-ai/agent-runtime';
|
|
3
|
+
import type { AcpInitializedConnection } from '../connection/contracts.js';
|
|
4
|
+
import type { AcpHostFacilities } from '../host/contracts.js';
|
|
5
|
+
import type { AcpProviderLimits } from '../limits.js';
|
|
6
|
+
import type { AcpAuthenticationMethod } from './methods.js';
|
|
7
|
+
export declare function createAcpAuthentication(input: {
|
|
8
|
+
readonly instanceId: AgentInstanceId;
|
|
9
|
+
readonly methods: ReadonlyMap<AgentAuthenticationFlow, AcpAuthenticationMethod>;
|
|
10
|
+
readonly host: AcpHostFacilities;
|
|
11
|
+
readonly limits: AcpProviderLimits;
|
|
12
|
+
readonly lifetime: AbortSignal;
|
|
13
|
+
readonly now: () => string;
|
|
14
|
+
readonly acquire: (signal: AbortSignal) => Promise<AcpInitializedConnection>;
|
|
15
|
+
readonly retain: (connection: AcpInitializedConnection) => void;
|
|
16
|
+
readonly retire: (connection: AcpInitializedConnection) => Promise<void>;
|
|
17
|
+
}): {
|
|
18
|
+
port: AgentProviderAuthentication;
|
|
19
|
+
readonly active: boolean;
|
|
20
|
+
readonly cleanupPending: boolean;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=controller.d.ts.map
|