@automatalabs/acp-agents 0.16.0 → 0.18.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/README.md +7 -3
- package/dist/acp-client.d.ts +16 -1
- package/dist/acp-client.d.ts.map +1 -1
- package/dist/acp-client.js +103 -4
- package/dist/backends/claude.d.ts.map +1 -1
- package/dist/backends/claude.js +3 -2
- package/dist/capabilities.d.ts +11 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +13 -0
- package/dist/errors-map.d.ts +8 -1
- package/dist/errors-map.d.ts.map +1 -1
- package/dist/errors-map.js +23 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +13 -1
- package/dist/protocol-coverage.d.ts +3 -1
- package/dist/protocol-coverage.d.ts.map +1 -1
- package/dist/protocol-coverage.js +8 -6
- package/dist/runner.d.ts +52 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +187 -31
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @automatalabs/acp-agents
|
|
|
14
14
|
|
|
15
15
|
## Standalone use: drive one agent
|
|
16
16
|
|
|
17
|
-
`createAcpRunner().run(prompt, options)` runs a single agent to completion. Pass a [typebox](https://github.com/sinclairzx81/typebox) `schema` to get a validated object back (typed as `Static<typeof schema>`); omit it to get the final assistant text as a `string`. The backend (Claude vs Codex) is selected from `model` / `tier`.
|
|
17
|
+
`createAcpRunner().run(prompt, options)` runs a single agent to completion. Pass a [typebox](https://github.com/sinclairzx81/typebox) `schema` to get a validated object back (typed as `Static<typeof schema>`); omit it to get the final assistant text as a `string`. The backend (Claude vs Codex) is selected from `model` / `tier`. Whoever constructs the runner owns it: call `dispose()` (or use `await using`) when you're done to tear down the pooled child processes.
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
import { createAcpRunner } from "@automatalabs/acp-agents";
|
|
@@ -133,7 +133,7 @@ try {
|
|
|
133
133
|
|
|
134
134
|
## Listening in: live ACP events
|
|
135
135
|
|
|
136
|
-
`AcpAgentRunner` is also a typed event bus — `runner.on(name, listener)` bubbles up the live ACP stream of every run (streaming text, tool calls, usage, permissions). Event names are the ACP `sessionUpdate` discriminants (`agent_message_chunk`, `tool_call`, `usage_update`, …) plus the cross-cutting `session_update` (catch-all), `permission_pending`, `permission_request`, `raw_message`, `session_open` / `session_close`, and `backend_error`. Each payload carries a `{ sessionId, backendId, label?, runId? }` context envelope (a pooled runner multiplexes many runs at once). `permission_pending`
|
|
136
|
+
`AcpAgentRunner` is also a typed event bus — `runner.on(name, listener)` bubbles up the live ACP stream of every run (streaming text, tool calls, usage, permissions, elicitations). Event names are the ACP `sessionUpdate` discriminants (`agent_message_chunk`, `tool_call`, `usage_update`, …) plus the cross-cutting `session_update` (catch-all), `permission_pending`, `permission_request`, `elicitation_pending`, `elicitation_request`, `elicitation_complete`, `raw_message`, `session_open` / `session_close`, and `backend_error`. Each payload carries a `{ sessionId, backendId, label?, runId? }` context envelope (a pooled runner multiplexes many runs at once). `permission_pending` / `elicitation_pending` are resolver-only and carry `{ request }` before the host resolver is invoked; `permission_request` / `elicitation_request` fire exactly once with the final `{ request, outcome }` returned to the agent; `elicitation_complete` carries `{ notification }` for URL completions. `on()` / `once()` return an unsubscribe thunk; `off()` and `removeAllListeners()` round it out. Listeners are best-effort observers — a throwing listener never affects the run.
|
|
137
137
|
|
|
138
138
|
```ts
|
|
139
139
|
const off = runner.on("agent_message_chunk", (e) => {
|
|
@@ -151,14 +151,18 @@ The full event map (`AcpRunnerEventMap`) and helpers (`TypedEventEmitter`) are e
|
|
|
151
151
|
From [`src/index.ts`](./src/index.ts):
|
|
152
152
|
|
|
153
153
|
- **`createAcpRunner(options?)`** — factory returning an `AcpAgentRunner` (this is what `@automatalabs/workflows` injects into the engine).
|
|
154
|
-
- **`AcpAgentRunner`** — the `AgentRunner` implementation; `run(prompt, options)`, `openSession(options)`, and `
|
|
154
|
+
- **`AcpAgentRunner`** — the `AgentRunner` implementation; `run(prompt, options)`, `openSession(options)`, `dispose()`, and `[Symbol.asyncDispose]()` for `await using`. The caller that constructs a runner owns its lifecycle.
|
|
155
|
+
- **Auth/provider lifecycle methods** — `authMethods()`, `authenticate()`, `listProviders()`, `setProvider()`, `disableProvider()`, and `logout()`; see [docs/api.md](../../docs/api.md) for capability gating and installed adapter support.
|
|
156
|
+
- **Session lifecycle methods** — `listSessions()`, `deleteSession()`, `loadSession()`, and `resumeSession()` for backends that advertise session persistence; see [docs/api.md](../../docs/api.md).
|
|
155
157
|
- **`InteractiveSession` / `InteractiveSessionOptions` / `InteractiveTurn`** — the held-open multi-turn session surface returned by `openSession()`.
|
|
158
|
+
- **`AcpRunnerOptions.onElicitation`** — runner-wide ACP elicitation responder; sessions can override with `InteractiveSessionOptions.onElicitation`.
|
|
156
159
|
- **`selectBackend({ model, tier }, registry?)`** — the cross-provider routing rule: which backend a spec maps to (registered custom names match first, exact or `name/<inner-model>`).
|
|
157
160
|
- **`ClaudeBackend` / `CodexBackend`** — the two built-in backend strategies (spawn config + per-backend schema wiring).
|
|
158
161
|
- **`CustomAcpBackend` / `resolveBackendRegistry` / `BACKENDS_ENV`** — the custom-backend registry: run **any** ACP agent as a named backend via `createAcpRunner({ backends: { name: { command, args?, env?, sessionMeta?, customCapabilities? } } })` or the `AGENTPRISM_BACKENDS` env var (JSON, same shape; the option wins per name; `claude`/`codex` reserved). Custom backends carry a `schema` as turn-level `_meta.outputSchema` and read the result off the final message as JSON. `customCapabilities: { namespace, gatedKeys }` declares the agent's `agentCapabilities._meta` negotiation contract: once the agent advertises that namespace, each declared bare `_meta` key is sent only when its same-named flag is `true` (no declaration = never gated).
|
|
159
162
|
- **`PermissionResolver`** — async human-in-the-loop permission resolution for runner-wide or interactive sessions.
|
|
160
163
|
- **`clientCapabilitiesFor` + the `ClientHandlers` / `FsHandlers` / `TerminalHandlers` / `AcpSessionContext` types** — the client-side fs/terminal interposition surface (see above).
|
|
161
164
|
- **`negotiateCapabilities` / `adaptPromptContent` / `gateCustomMeta` / `unsupportedMcpServer` + `NegotiatedCapabilities`** — the `initialize` capability-negotiation primitives; the negotiated record for a live connection is exposed on `PooledConnection.capabilities`.
|
|
165
|
+
- **`AGENT_METHOD_COVERAGE` / `CLIENT_METHOD_COVERAGE`** — manifests classifying the installed ACP SDK method surface; enforced by tests so SDK bumps cannot silently drift.
|
|
162
166
|
- **`toJsonSchema(schema)` / `toStrictJsonSchema(schema)`** — turn a typebox schema into the on-the-wire shapes: a plain JSON Schema for Claude `outputFormat`, and an OpenAI-strict-normalized schema for Codex `outputSchema`.
|
|
163
167
|
|
|
164
168
|
Also exported: `AcpAgentPool` / `resolvePoolSize`, `PooledConnection` / `SessionHandle`, `decidePermission`, `UsageAccumulator`, `resolveStructuredOutput` / `extractValidated` / `findJsonBlock` / `validateValue`, `errorText` / `mapThrownError`, and the event surface `TypedEventEmitter` / `AcpRunnerEventMap` / `AcpEventName` / `AcpEventListener` / `AcpEventContext` / `AcpSessionUpdate` (+ the per-event payload types, including `AcpPermissionPendingEvent`), plus their associated types.
|
package/dist/acp-client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CreateElicitationResponse, type ContentBlock, type AgentNotificationMethod, type AgentNotificationParamsByMethod, type AgentRequestMethod, type AgentRequestParamsByMethod, type AgentRequestResponsesByMethod, type DeleteSessionRequest, type ListSessionsRequest, type ListSessionsResponse, type PromptRequest, type PromptResponse, type RequestPermissionResponse, type SendRequestOptions, type SessionConfigOption, type SessionModeState, type SessionNotification, type SetSessionConfigOptionRequest, type SetSessionConfigOptionResponse, type SetSessionModeRequest, type SetSessionModeResponse } from "@agentclientprotocol/sdk";
|
|
1
|
+
import { type AuthenticateRequest, type AuthenticateResponse, type AuthMethod, type CreateElicitationResponse, type ContentBlock, type AgentNotificationMethod, type AgentNotificationParamsByMethod, type AgentRequestMethod, type AgentRequestParamsByMethod, type AgentRequestResponsesByMethod, type DeleteSessionRequest, type DisableProviderRequest, type DisableProviderResponse, type ListSessionsRequest, type ListSessionsResponse, type ListProvidersRequest, type ListProvidersResponse, type LogoutRequest, type LogoutResponse, type PromptRequest, type PromptResponse, type RequestPermissionResponse, type SendRequestOptions, type SessionConfigOption, type SessionModeState, type SessionNotification, type SetProviderRequest, type SetProviderResponse, type SetSessionConfigOptionRequest, type SetSessionConfigOptionResponse, type SetSessionModeRequest, type SetSessionModeResponse } from "@agentclientprotocol/sdk";
|
|
2
2
|
import type { TSchema } from "typebox";
|
|
3
3
|
import { type AgentHistoryEntry, type McpServerConfig } from "@automatalabs/shared-types";
|
|
4
4
|
import type { Backend, BackendId, StructuredSource } from "./backend.js";
|
|
@@ -147,6 +147,7 @@ export declare class PooledConnection {
|
|
|
147
147
|
private assertSupportedMcpServers;
|
|
148
148
|
private sessionRequestMeta;
|
|
149
149
|
private assertLifecycleSupported;
|
|
150
|
+
private assertAuthProviderSupported;
|
|
150
151
|
/** Mark this connection dead exactly once, then ask the pool to evict it. Idempotent. */
|
|
151
152
|
private die;
|
|
152
153
|
private stderrSuffix;
|
|
@@ -170,6 +171,18 @@ export declare class PooledConnection {
|
|
|
170
171
|
listSessions(request: ListSessionsRequest, label?: string): Promise<ListSessionsResponse>;
|
|
171
172
|
/** session/delete on a dedicated connection, gated on the initialize advertisement. */
|
|
172
173
|
deleteSession(request: DeleteSessionRequest, label?: string): Promise<void>;
|
|
174
|
+
/** Authentication methods advertised in initialize, available without opening a session. */
|
|
175
|
+
authMethods(): Promise<AuthMethod[]>;
|
|
176
|
+
/** authenticate has no AgentCapabilities gate; authMethods advertises choices, not method support. */
|
|
177
|
+
authenticate(request: AuthenticateRequest, label?: string): Promise<AuthenticateResponse | void>;
|
|
178
|
+
/** providers/list on a dedicated connection, gated on the unstable providers advertisement. */
|
|
179
|
+
listProviders(request: ListProvidersRequest, label?: string): Promise<ListProvidersResponse>;
|
|
180
|
+
/** providers/set on a dedicated connection, gated on the unstable providers advertisement. */
|
|
181
|
+
setProvider(request: SetProviderRequest, label?: string): Promise<SetProviderResponse | void>;
|
|
182
|
+
/** providers/disable on a dedicated connection, gated on the unstable providers advertisement. */
|
|
183
|
+
disableProvider(request: DisableProviderRequest, label?: string): Promise<DisableProviderResponse | void>;
|
|
184
|
+
/** logout on a dedicated connection, gated on agentCapabilities.auth.logout. */
|
|
185
|
+
logout(request: LogoutRequest, label?: string): Promise<LogoutResponse | void>;
|
|
173
186
|
/** session/prompt on this connection, raced against process death. */
|
|
174
187
|
prompt(request: PromptRequest): Promise<PromptResponse>;
|
|
175
188
|
/** session/set_config_option on this connection, raced against process death. */
|
|
@@ -221,6 +234,8 @@ export declare class SessionHandle implements StructuredSource {
|
|
|
221
234
|
get text(): string;
|
|
222
235
|
/** Agent-advertised session mode catalog plus the currently active mode, if supported. */
|
|
223
236
|
get modes(): SessionModeState | null | undefined;
|
|
237
|
+
/** The connection-level initialize response parsed before this session was opened. */
|
|
238
|
+
get capabilities(): NegotiatedCapabilities | undefined;
|
|
224
239
|
/**
|
|
225
240
|
* Select the model for this session from the agent-advertised config options (§5.4).
|
|
226
241
|
* Returns `matched:false` (the caller fires onModelFallback) when the catalog has no value
|
package/dist/acp-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp-client.d.ts","sourceRoot":"","sources":["../src/acp-client.ts"],"names":[],"mappings":"AAwBA,OAAO,
|
|
1
|
+
{"version":3,"file":"acp-client.d.ts","sourceRoot":"","sources":["../src/acp-client.ts"],"names":[],"mappings":"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"}
|
package/dist/acp-client.js
CHANGED
|
@@ -24,7 +24,7 @@ import { spawn } from "node:child_process";
|
|
|
24
24
|
import { Readable, Writable } from "node:stream";
|
|
25
25
|
import { AGENT_METHODS, client, CLIENT_METHODS, ndJsonStream, PROTOCOL_VERSION, RequestError, } from "@agentclientprotocol/sdk";
|
|
26
26
|
import { META_KEYS, WorkflowError, WorkflowErrorCode, } from "@automatalabs/shared-types";
|
|
27
|
-
import { adaptPromptContent, describeLifecycleAdvertisement, gateCustomMeta, isSupportedProtocolVersion, negotiateCapabilities, unsupportedMcpServer, } from "./capabilities.js";
|
|
27
|
+
import { adaptPromptContent, describeAuthProviderAdvertisement, describeLifecycleAdvertisement, gateCustomMeta, isSupportedProtocolVersion, negotiateCapabilities, unsupportedMcpServer, } from "./capabilities.js";
|
|
28
28
|
import { emitSessionUpdate } from "./events.js";
|
|
29
29
|
import { decidePermission, } from "./permissions.js";
|
|
30
30
|
import { UsageAccumulator } from "./usage.js";
|
|
@@ -552,6 +552,18 @@ function lifecycleCapabilityError(backendId, method, capabilities, label) {
|
|
|
552
552
|
: "initialize did not complete";
|
|
553
553
|
return new WorkflowError(`ACP agent (${backendId}) does not advertise ${method}; advertised lifecycle capabilities: ${advertised}`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
|
|
554
554
|
}
|
|
555
|
+
function authProviderCapabilityError(backendId, method, capabilities, label) {
|
|
556
|
+
const advertised = capabilities
|
|
557
|
+
? describeAuthProviderAdvertisement(capabilities.agent, capabilities.authMethods)
|
|
558
|
+
: "initialize did not complete";
|
|
559
|
+
return new WorkflowError(`ACP agent (${backendId}) does not advertise ${method}; advertised auth/provider capabilities: ${advertised}`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
|
|
560
|
+
}
|
|
561
|
+
function isMethodNotFound(error) {
|
|
562
|
+
return Boolean(error && typeof error === "object" && error.code === -32601);
|
|
563
|
+
}
|
|
564
|
+
function agentMethodNotFoundError(backendId, method, label, cause) {
|
|
565
|
+
return new WorkflowError(`ACP agent (${backendId}) does not implement ${method}: ${thrownMessage(cause)}`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label, details: cause });
|
|
566
|
+
}
|
|
555
567
|
function thrownMessage(error) {
|
|
556
568
|
if (error instanceof Error)
|
|
557
569
|
return error.message;
|
|
@@ -764,6 +776,18 @@ export class PooledConnection {
|
|
|
764
776
|
return;
|
|
765
777
|
throw lifecycleCapabilityError(this.backendId, method, this.negotiated, label);
|
|
766
778
|
}
|
|
779
|
+
assertAuthProviderSupported(method, label) {
|
|
780
|
+
const supported = method === AGENT_METHODS.logout
|
|
781
|
+
? this.negotiated?.supportsLogout
|
|
782
|
+
: method === AGENT_METHODS.providers_list ||
|
|
783
|
+
method === AGENT_METHODS.providers_set ||
|
|
784
|
+
method === AGENT_METHODS.providers_disable
|
|
785
|
+
? this.negotiated?.supportsProviders
|
|
786
|
+
: true;
|
|
787
|
+
if (supported)
|
|
788
|
+
return;
|
|
789
|
+
throw authProviderCapabilityError(this.backendId, method, this.negotiated, label);
|
|
790
|
+
}
|
|
767
791
|
/** Mark this connection dead exactly once, then ask the pool to evict it. Idempotent. */
|
|
768
792
|
die(error) {
|
|
769
793
|
if (!this._alive)
|
|
@@ -888,9 +912,10 @@ export class PooledConnection {
|
|
|
888
912
|
return this.reattachSession(AGENT_METHODS.session_resume, sessionId, opts);
|
|
889
913
|
}
|
|
890
914
|
rawAgentRequest(method, params) {
|
|
891
|
-
// SDK
|
|
892
|
-
//
|
|
893
|
-
//
|
|
915
|
+
// Some SDK ClientContext convenience methods collapse responses through emptyObjectResponse
|
|
916
|
+
// (session/load in 1.2.0, plus auth/provider methods with optional _meta). Driven wrappers
|
|
917
|
+
// need the wire response as-is. This bypasses only the SDK response mapper, not JSON-RPC
|
|
918
|
+
// validation/racing.
|
|
894
919
|
const agent = this.connection.agent;
|
|
895
920
|
return this.race(agent.sendRequest(method, params));
|
|
896
921
|
}
|
|
@@ -944,6 +969,76 @@ export class PooledConnection {
|
|
|
944
969
|
this.assertLifecycleSupported(AGENT_METHODS.session_delete, label);
|
|
945
970
|
await this.race(this.connection.agent.request(AGENT_METHODS.session_delete, request));
|
|
946
971
|
}
|
|
972
|
+
/** Authentication methods advertised in initialize, available without opening a session. */
|
|
973
|
+
async authMethods() {
|
|
974
|
+
await this.ready;
|
|
975
|
+
return [...(this.negotiated?.authMethods ?? [])];
|
|
976
|
+
}
|
|
977
|
+
/** authenticate has no AgentCapabilities gate; authMethods advertises choices, not method support. */
|
|
978
|
+
async authenticate(request, label) {
|
|
979
|
+
await this.ready;
|
|
980
|
+
try {
|
|
981
|
+
return await this.rawAgentRequest(AGENT_METHODS.authenticate, request);
|
|
982
|
+
}
|
|
983
|
+
catch (error) {
|
|
984
|
+
if (isMethodNotFound(error))
|
|
985
|
+
throw agentMethodNotFoundError(this.backendId, AGENT_METHODS.authenticate, label, error);
|
|
986
|
+
throw error;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
/** providers/list on a dedicated connection, gated on the unstable providers advertisement. */
|
|
990
|
+
async listProviders(request, label) {
|
|
991
|
+
await this.ready;
|
|
992
|
+
this.assertAuthProviderSupported(AGENT_METHODS.providers_list, label);
|
|
993
|
+
try {
|
|
994
|
+
return await this.rawAgentRequest(AGENT_METHODS.providers_list, request);
|
|
995
|
+
}
|
|
996
|
+
catch (error) {
|
|
997
|
+
if (isMethodNotFound(error))
|
|
998
|
+
throw agentMethodNotFoundError(this.backendId, AGENT_METHODS.providers_list, label, error);
|
|
999
|
+
throw error;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
/** providers/set on a dedicated connection, gated on the unstable providers advertisement. */
|
|
1003
|
+
async setProvider(request, label) {
|
|
1004
|
+
await this.ready;
|
|
1005
|
+
this.assertAuthProviderSupported(AGENT_METHODS.providers_set, label);
|
|
1006
|
+
try {
|
|
1007
|
+
return await this.rawAgentRequest(AGENT_METHODS.providers_set, request);
|
|
1008
|
+
}
|
|
1009
|
+
catch (error) {
|
|
1010
|
+
if (isMethodNotFound(error))
|
|
1011
|
+
throw agentMethodNotFoundError(this.backendId, AGENT_METHODS.providers_set, label, error);
|
|
1012
|
+
throw error;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
/** providers/disable on a dedicated connection, gated on the unstable providers advertisement. */
|
|
1016
|
+
async disableProvider(request, label) {
|
|
1017
|
+
await this.ready;
|
|
1018
|
+
this.assertAuthProviderSupported(AGENT_METHODS.providers_disable, label);
|
|
1019
|
+
try {
|
|
1020
|
+
return await this.rawAgentRequest(AGENT_METHODS.providers_disable, request);
|
|
1021
|
+
}
|
|
1022
|
+
catch (error) {
|
|
1023
|
+
if (isMethodNotFound(error)) {
|
|
1024
|
+
throw agentMethodNotFoundError(this.backendId, AGENT_METHODS.providers_disable, label, error);
|
|
1025
|
+
}
|
|
1026
|
+
throw error;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
/** logout on a dedicated connection, gated on agentCapabilities.auth.logout. */
|
|
1030
|
+
async logout(request, label) {
|
|
1031
|
+
await this.ready;
|
|
1032
|
+
this.assertAuthProviderSupported(AGENT_METHODS.logout, label);
|
|
1033
|
+
try {
|
|
1034
|
+
return await this.rawAgentRequest(AGENT_METHODS.logout, request);
|
|
1035
|
+
}
|
|
1036
|
+
catch (error) {
|
|
1037
|
+
if (isMethodNotFound(error))
|
|
1038
|
+
throw agentMethodNotFoundError(this.backendId, AGENT_METHODS.logout, label, error);
|
|
1039
|
+
throw error;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
947
1042
|
/** session/prompt on this connection, raced against process death. */
|
|
948
1043
|
prompt(request) {
|
|
949
1044
|
return this.race(this.connection.agent.request(AGENT_METHODS.session_prompt, request));
|
|
@@ -1087,6 +1182,10 @@ export class SessionHandle {
|
|
|
1087
1182
|
get modes() {
|
|
1088
1183
|
return this.state.modes;
|
|
1089
1184
|
}
|
|
1185
|
+
/** The connection-level initialize response parsed before this session was opened. */
|
|
1186
|
+
get capabilities() {
|
|
1187
|
+
return this.pooled.capabilities;
|
|
1188
|
+
}
|
|
1090
1189
|
/**
|
|
1091
1190
|
* Select the model for this session from the agent-advertised config options (§5.4).
|
|
1092
1191
|
* Returns `matched:false` (the caller fires onModelFallback) when the catalog has no value
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/backends/claude.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/backends/claude.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAM5E,qBAAa,aAAc,YAAW,OAAO;IAC3C,QAAQ,CAAC,EAAE,EAAG,QAAQ,CAAU;IAEhC,WAAW,IAAI,WAAW;IAgB1B,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAe7E,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAKjD,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO;CAGpD"}
|
package/dist/backends/claude.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ClaudeBackend — drives @agentclientprotocol/claude-agent-acp@0.
|
|
1
|
+
// ClaudeBackend — drives @agentclientprotocol/claude-agent-acp@0.56.0 (over the Claude
|
|
2
2
|
// Agent SDK). Structured output rides the vendor `_meta.claudeCode` channel at session/new:
|
|
3
3
|
// options.outputFormat = { type:"json_schema", schema } // the SDK's native constraint
|
|
4
4
|
// emitRawSDKMessages = true // MANDATORY to READ the result
|
|
@@ -31,7 +31,7 @@ export class ClaudeBackend {
|
|
|
31
31
|
// optional SessionMetaInputs (the seam still accepts them via the Backend interface).
|
|
32
32
|
if (!schema)
|
|
33
33
|
return undefined;
|
|
34
|
-
|
|
34
|
+
const meta = {
|
|
35
35
|
claudeCode: {
|
|
36
36
|
options: {
|
|
37
37
|
outputFormat: { type: "json_schema", schema: toJsonSchema(schema) },
|
|
@@ -39,6 +39,7 @@ export class ClaudeBackend {
|
|
|
39
39
|
emitRawSDKMessages: true,
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
|
+
return meta;
|
|
42
43
|
}
|
|
43
44
|
promptMeta() {
|
|
44
45
|
// Claude's schema is session-scoped (read at session/new); nothing on the turn.
|
package/dist/capabilities.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentCapabilities, type ContentBlock, type Implementation, type InitializeResponse } from "@agentclientprotocol/sdk";
|
|
1
|
+
import { type AgentCapabilities, type AuthMethod, type ContentBlock, type Implementation, type InitializeResponse } from "@agentclientprotocol/sdk";
|
|
2
2
|
import { type McpServerConfig } from "@automatalabs/shared-types";
|
|
3
3
|
import type { Backend } from "./backend.js";
|
|
4
4
|
/** The bare `_meta` keys whose emission is gated by Codex's custom-capability advertisement.
|
|
@@ -16,6 +16,10 @@ export interface NegotiatedCapabilities {
|
|
|
16
16
|
agent: AgentCapabilities;
|
|
17
17
|
/** The agent's self-identification, when it sent agentInfo. */
|
|
18
18
|
agentInfo: Implementation | undefined;
|
|
19
|
+
/** Authentication methods advertised by the agent in initialize, defaulting to [] when absent. */
|
|
20
|
+
authMethods: AuthMethod[];
|
|
21
|
+
/** Initialize-response `_meta`, when the agent sent it. */
|
|
22
|
+
initializeMeta: InitializeResponse["_meta"] | undefined;
|
|
19
23
|
/** Whether session/close is advertised (gates the best-effort release-time close). */
|
|
20
24
|
supportsClose: boolean;
|
|
21
25
|
/** Whether session/load is advertised. The current SDK keeps this as the legacy top-level
|
|
@@ -27,6 +31,10 @@ export interface NegotiatedCapabilities {
|
|
|
27
31
|
supportsDeleteSession: boolean;
|
|
28
32
|
/** Whether session/resume is advertised. */
|
|
29
33
|
supportsResumeSession: boolean;
|
|
34
|
+
/** Whether logout is advertised under agentCapabilities.auth.logout. */
|
|
35
|
+
supportsLogout: boolean;
|
|
36
|
+
/** Whether the unstable provider-configuration block is advertised. */
|
|
37
|
+
supportsProviders: boolean;
|
|
30
38
|
/** The parsed backend-declared custom-capability block (the namespaced `_meta` object), or
|
|
31
39
|
* undefined when the backend declared none or the agent did not advertise it — passthrough. */
|
|
32
40
|
customMetaSupport: Record<string, unknown> | undefined;
|
|
@@ -38,6 +46,8 @@ export interface NegotiatedCapabilities {
|
|
|
38
46
|
export declare function negotiateCapabilities(response: InitializeResponse, customCapabilities?: Backend["customCapabilities"]): NegotiatedCapabilities;
|
|
39
47
|
/** Human-readable lifecycle advertisement summary for strict wrapper gate errors. */
|
|
40
48
|
export declare function describeLifecycleAdvertisement(agent: AgentCapabilities): string;
|
|
49
|
+
/** Human-readable auth/provider advertisement summary for strict wrapper gate errors. */
|
|
50
|
+
export declare function describeAuthProviderAdvertisement(agent: AgentCapabilities, authMethods?: readonly AuthMethod[]): string;
|
|
41
51
|
/** True only when the agent selected EXACTLY PROTOCOL_VERSION. This client implements that one wire
|
|
42
52
|
* version and adapts its behavior to no other, so any other selected version — older or newer —
|
|
43
53
|
* means close the connection per the ACP spec's SHOULD-close rule. Per the spec the agent echoes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQ5C;;;iGAGiG;AACjG,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAInD,CAAC;AAEF,qFAAqF;AACrF,MAAM,WAAW,sBAAsB;IACrC;0FACsF;IACtF,eAAe,EAAE,MAAM,CAAC;IACxB;4DACwD;IACxD,KAAK,EAAE,iBAAiB,CAAC;IACzB,+DAA+D;IAC/D,SAAS,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC,sFAAsF;IACtF,aAAa,EAAE,OAAO,CAAC;IACvB;mGAC+F;IAC/F,mBAAmB,EAAE,OAAO,CAAC;IAC7B,0CAA0C;IAC1C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,4CAA4C;IAC5C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4CAA4C;IAC5C,qBAAqB,EAAE,OAAO,CAAC;IAC/B;oGACgG;IAChG,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACvD;+EAC2E;IAC3E,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC1C;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,kBAAkB,EAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACjD,sBAAsB,
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQ5C;;;iGAGiG;AACjG,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAInD,CAAC;AAEF,qFAAqF;AACrF,MAAM,WAAW,sBAAsB;IACrC;0FACsF;IACtF,eAAe,EAAE,MAAM,CAAC;IACxB;4DACwD;IACxD,KAAK,EAAE,iBAAiB,CAAC;IACzB,+DAA+D;IAC/D,SAAS,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC,kGAAkG;IAClG,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,2DAA2D;IAC3D,cAAc,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,sFAAsF;IACtF,aAAa,EAAE,OAAO,CAAC;IACvB;mGAC+F;IAC/F,mBAAmB,EAAE,OAAO,CAAC;IAC7B,0CAA0C;IAC1C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,4CAA4C;IAC5C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4CAA4C;IAC5C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wEAAwE;IACxE,cAAc,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,iBAAiB,EAAE,OAAO,CAAC;IAC3B;oGACgG;IAChG,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACvD;+EAC2E;IAC3E,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC1C;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,kBAAkB,EAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACjD,sBAAsB,CAsBxB;AAMD,qFAAqF;AACrF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAiB/E;AAED,yFAAyF;AACzF,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,iBAAiB,EACxB,WAAW,GAAE,SAAS,UAAU,EAAO,GACtC,MAAM,CAOR;AAaD;;;;+DAI+D;AAC/D,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;gEAGgE;AAChE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,SAAS,GAAE,SAAS,MAAM,EAA2B,GACpD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAWrC;AAED;;;;;2EAK2E;AAC3E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EAAE,EACtB,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,MAAM,GAChB,YAAY,EAAE,CAchB;AAkCD;;;;kEAIkE;AAClE,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,eAAe,EAAE,GAAG,SAAS,EACtC,KAAK,EAAE,iBAAiB,EACxB,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAA;CAAE,GAAG,SAAS,CAkBpF"}
|
package/dist/capabilities.js
CHANGED
|
@@ -40,11 +40,15 @@ export function negotiateCapabilities(response, customCapabilities) {
|
|
|
40
40
|
protocolVersion: response.protocolVersion,
|
|
41
41
|
agent,
|
|
42
42
|
agentInfo: response.agentInfo ?? undefined,
|
|
43
|
+
authMethods: response.authMethods ?? [],
|
|
44
|
+
initializeMeta: response._meta ?? undefined,
|
|
43
45
|
supportsClose: advertised(sessionCapabilities?.close),
|
|
44
46
|
supportsLoadSession: agent.loadSession === true || advertised(sessionCapabilities?.load),
|
|
45
47
|
supportsListSessions: advertised(sessionCapabilities?.list),
|
|
46
48
|
supportsDeleteSession: advertised(sessionCapabilities?.delete),
|
|
47
49
|
supportsResumeSession: advertised(sessionCapabilities?.resume),
|
|
50
|
+
supportsLogout: advertised(agent.auth?.logout),
|
|
51
|
+
supportsProviders: advertised(agent.providers),
|
|
48
52
|
customMetaSupport: customCapabilities
|
|
49
53
|
? readCustomNamespace(agent._meta, customCapabilities.namespace)
|
|
50
54
|
: undefined,
|
|
@@ -73,6 +77,15 @@ export function describeLifecycleAdvertisement(agent) {
|
|
|
73
77
|
`sessionCapabilities=${session.length > 0 ? session.join(", ") : "none"}`,
|
|
74
78
|
].join("; ");
|
|
75
79
|
}
|
|
80
|
+
/** Human-readable auth/provider advertisement summary for strict wrapper gate errors. */
|
|
81
|
+
export function describeAuthProviderAdvertisement(agent, authMethods = []) {
|
|
82
|
+
const methodIds = authMethods.map((method) => method.id).filter(Boolean);
|
|
83
|
+
return [
|
|
84
|
+
`authMethods=${methodIds.length > 0 ? methodIds.join(", ") : "none"}`,
|
|
85
|
+
`auth.logout=${advertised(agent.auth?.logout) ? "true" : "false"}`,
|
|
86
|
+
`providers=${advertised(agent.providers) ? "true" : "false"}`,
|
|
87
|
+
].join("; ");
|
|
88
|
+
}
|
|
76
89
|
function readCustomNamespace(meta, namespace) {
|
|
77
90
|
if (!meta || typeof meta !== "object")
|
|
78
91
|
return undefined;
|
package/dist/errors-map.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { WorkflowError } from "@automatalabs/shared-types";
|
|
2
|
+
import type { AuthMethod } from "@agentclientprotocol/sdk";
|
|
3
|
+
export declare const ACP_AUTH_REQUIRED_ERROR_CODE = -32000;
|
|
4
|
+
export interface ErrorMapContext {
|
|
5
|
+
label?: string;
|
|
6
|
+
backendId?: string;
|
|
7
|
+
authMethods?: readonly AuthMethod[];
|
|
8
|
+
}
|
|
2
9
|
export declare function errorText(error: unknown): string;
|
|
3
10
|
/** Map any thrown error from the run path onto a seam-level WorkflowError. */
|
|
4
|
-
export declare function mapThrownError(error: unknown,
|
|
11
|
+
export declare function mapThrownError(error: unknown, labelOrContext?: string | ErrorMapContext): WorkflowError;
|
|
5
12
|
//# sourceMappingURL=errors-map.d.ts.map
|
package/dist/errors-map.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-map.d.ts","sourceRoot":"","sources":["../src/errors-map.ts"],"names":[],"mappings":"AAYA,OAAO,EAA0C,aAAa,EAAqB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"errors-map.d.ts","sourceRoot":"","sources":["../src/errors-map.ts"],"names":[],"mappings":"AAYA,OAAO,EAA0C,aAAa,EAAqB,MAAM,4BAA4B,CAAC;AACtH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,eAAO,MAAM,4BAA4B,SAAS,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACrC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAahD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,aAAa,CA4BvG"}
|
package/dist/errors-map.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// the engine retries). WorkflowErrors raised inside the ladder (SCHEMA_NONCOMPLIANCE,
|
|
12
12
|
// AGENT_EMPTY_OUTPUT) pass through unchanged.
|
|
13
13
|
import { classifyProviderLimit, isWorkflowError, WorkflowError, WorkflowErrorCode } from "@automatalabs/shared-types";
|
|
14
|
+
export const ACP_AUTH_REQUIRED_ERROR_CODE = -32000;
|
|
14
15
|
export function errorText(error) {
|
|
15
16
|
if (error instanceof Error)
|
|
16
17
|
return error.message;
|
|
@@ -30,18 +31,37 @@ export function errorText(error) {
|
|
|
30
31
|
return String(error);
|
|
31
32
|
}
|
|
32
33
|
/** Map any thrown error from the run path onto a seam-level WorkflowError. */
|
|
33
|
-
export function mapThrownError(error,
|
|
34
|
+
export function mapThrownError(error, labelOrContext) {
|
|
34
35
|
// Already a seam error (e.g. SCHEMA_NONCOMPLIANCE / AGENT_EMPTY_OUTPUT raised in-band).
|
|
35
36
|
if (isWorkflowError(error))
|
|
36
37
|
return error;
|
|
38
|
+
const context = typeof labelOrContext === "string" ? { label: labelOrContext } : (labelOrContext ?? {});
|
|
37
39
|
const message = errorText(error);
|
|
40
|
+
if (isAcpAuthRequired(error, message)) {
|
|
41
|
+
return new WorkflowError(authRequiredMessage(message, context), WorkflowErrorCode.AUTH_REQUIRED, {
|
|
42
|
+
recoverable: false,
|
|
43
|
+
agentLabel: context.label,
|
|
44
|
+
details: error,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
38
47
|
const { matched, resetHint } = classifyProviderLimit(message);
|
|
39
48
|
if (matched) {
|
|
40
|
-
return new WorkflowError(message || "Provider usage/quota limit reached", WorkflowErrorCode.PROVIDER_USAGE_LIMIT, { recoverable: false, agentLabel: label, resetHint, details: error });
|
|
49
|
+
return new WorkflowError(message || "Provider usage/quota limit reached", WorkflowErrorCode.PROVIDER_USAGE_LIMIT, { recoverable: false, agentLabel: context.label, resetHint, details: error });
|
|
41
50
|
}
|
|
42
51
|
return new WorkflowError(message || "Subagent execution failed", WorkflowErrorCode.AGENT_EXECUTION_ERROR, {
|
|
43
52
|
recoverable: true,
|
|
44
|
-
agentLabel: label,
|
|
53
|
+
agentLabel: context.label,
|
|
45
54
|
details: error,
|
|
46
55
|
});
|
|
47
56
|
}
|
|
57
|
+
function isAcpAuthRequired(error, message) {
|
|
58
|
+
return (Boolean(error && typeof error === "object" && error.code === ACP_AUTH_REQUIRED_ERROR_CODE) &&
|
|
59
|
+
/^Authentication required\b/i.test(message));
|
|
60
|
+
}
|
|
61
|
+
function authRequiredMessage(message, context) {
|
|
62
|
+
const backend = context.backendId ? ` (${context.backendId})` : "";
|
|
63
|
+
const detail = message.replace(/^Authentication required:?\s*/i, "").trim();
|
|
64
|
+
const methodIds = (context.authMethods ?? []).map((method) => method.id).filter(Boolean);
|
|
65
|
+
const hint = methodIds.length > 0 ? `; run authenticate() with one of: ${methodIds.join(", ")}` : "";
|
|
66
|
+
return `ACP agent${backend} requires authentication${detail ? `: ${detail}` : ""}${hint}`;
|
|
67
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { AcpAgentRunner, createAcpRunner, selectBackend } from "./runner.js";
|
|
2
|
-
export type { AcpRunnerOptions, DeleteSessionOptions, ListSessionsOptions, ReattachSessionOptions, } from "./runner.js";
|
|
2
|
+
export type { AcpRunnerOptions, AuthenticateOptions, AuthMethodsOptions, DisableProviderOptions, DeleteSessionOptions, ListProvidersOptions, ListSessionsOptions, LogoutOptions, ReattachSessionOptions, SetProviderOptions, } from "./runner.js";
|
|
3
3
|
export { InteractiveSession } from "./interactive.js";
|
|
4
4
|
export type { InteractiveSessionOptions, InteractiveTurn } from "./interactive.js";
|
|
5
5
|
export { AGENT_METHODS, CLIENT_METHODS } from "@agentclientprotocol/sdk";
|
|
6
|
-
export type { AgentNotificationMethod, AgentNotificationParamsByMethod, AgentRequestMethod, AgentRequestParamsByMethod, AgentRequestResponsesByMethod, CompleteElicitationNotification, ConnectMcpRequest, ConnectMcpResponse, CreateElicitationRequest, CreateElicitationResponse, DeleteSessionRequest, DeleteSessionResponse, DisconnectMcpRequest, DisconnectMcpResponse, ElicitationAcceptAction, ElicitationCapabilities, ElicitationContentValue, ElicitationFormCapabilities, ElicitationFormMode, ElicitationId, ElicitationPropertySchema, ElicitationRequestScope, ElicitationSchema, ElicitationSchemaType, ElicitationSessionScope, ElicitationUrlCapabilities, ElicitationUrlMode, ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, LoadSessionResponse, McpConnectionId, McpServerAcp, McpServerAcpId, MessageMcpNotification, MessageMcpRequest, MessageMcpResponse, ResumeSessionRequest, ResumeSessionResponse, SessionMode, SessionModeState, SessionInfo, SendRequestOptions, } from "@agentclientprotocol/sdk";
|
|
6
|
+
export type { AgentNotificationMethod, AgentNotificationParamsByMethod, AgentAuthCapabilities, AgentRequestMethod, AgentRequestParamsByMethod, AgentRequestResponsesByMethod, AuthCapabilities, AuthEnvVar, AuthenticateRequest, AuthenticateResponse, AuthMethod, AuthMethodAgent, AuthMethodEnvVar, AuthMethodId, AuthMethodTerminal, DisableProviderRequest, DisableProviderResponse, CompleteElicitationNotification, ConnectMcpRequest, ConnectMcpResponse, CreateElicitationRequest, CreateElicitationResponse, DeleteSessionRequest, DeleteSessionResponse, DisconnectMcpRequest, DisconnectMcpResponse, ElicitationAcceptAction, ElicitationCapabilities, ElicitationContentValue, ElicitationFormCapabilities, ElicitationFormMode, ElicitationId, ElicitationPropertySchema, ElicitationRequestScope, ElicitationSchema, ElicitationSchemaType, ElicitationSessionScope, ElicitationUrlCapabilities, ElicitationUrlMode, ListProvidersRequest, ListProvidersResponse, ListSessionsRequest, ListSessionsResponse, LlmProtocol, LoadSessionRequest, LoadSessionResponse, LogoutCapabilities, LogoutRequest, LogoutResponse, McpConnectionId, McpServerAcp, McpServerAcpId, MessageMcpNotification, MessageMcpRequest, MessageMcpResponse, ResumeSessionRequest, ResumeSessionResponse, ProviderCurrentConfig, ProviderId, ProviderInfo, ProvidersCapabilities, SessionMode, SessionModeState, SessionInfo, SendRequestOptions, SetProviderRequest, SetProviderResponse, } from "@agentclientprotocol/sdk";
|
|
7
7
|
export { BACKENDS_ENV, registryWithRunBackends, resolveBackendRegistry } from "./registry.js";
|
|
8
8
|
export type { BackendRegistry, CustomBackendConfig, RegisteredBackend } from "./registry.js";
|
|
9
9
|
export { PooledConnection, SessionHandle } from "./acp-client.js";
|
|
@@ -29,5 +29,6 @@ export type { McpAcpServerConfig, McpServerConfig } from "@automatalabs/shared-t
|
|
|
29
29
|
export { toJsonSchema, toStrictJsonSchema } from "./schema-strict.js";
|
|
30
30
|
export { extractValidated, findJsonBlock, parseFinalJson, resolveStructuredOutput, validateValue, } from "./structured-output.js";
|
|
31
31
|
export type { ResolveOptions, StructuredSession } from "./structured-output.js";
|
|
32
|
-
export { errorText, mapThrownError } from "./errors-map.js";
|
|
32
|
+
export { ACP_AUTH_REQUIRED_ERROR_CODE, errorText, mapThrownError } from "./errors-map.js";
|
|
33
|
+
export type { ErrorMapContext } from "./errors-map.js";
|
|
33
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27,4 +27,4 @@ export { decidePermission } from "./permissions.js";
|
|
|
27
27
|
export { UsageAccumulator } from "./usage.js";
|
|
28
28
|
export { toJsonSchema, toStrictJsonSchema } from "./schema-strict.js";
|
|
29
29
|
export { extractValidated, findJsonBlock, parseFinalJson, resolveStructuredOutput, validateValue, } from "./structured-output.js";
|
|
30
|
-
export { errorText, mapThrownError } from "./errors-map.js";
|
|
30
|
+
export { ACP_AUTH_REQUIRED_ERROR_CODE, errorText, mapThrownError } from "./errors-map.js";
|
package/dist/pool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AACvD,OAAO,EAAoB,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AACvD,OAAO,EAAoB,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAKhF,MAAM,WAAW,cAAc;IAC7B,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;6FAC6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,qBAAa,YAAY;IAUrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IATvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAC1D,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAS;gBAGvB,OAAO,GAAE,cAAmB,EACX,IAAI,GAAE,WAAgB;IAOzC,8FAA8F;IACxF,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAehF;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,cAAc;IAStB,+DAA+D;IAC/D,OAAO,CAAC,IAAI;IAOZ,iEAAiE;IAC3D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IAMtB,gGAAgG;IAChG,OAAO,CAAC,WAAW;CAGpB"}
|
package/dist/pool.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PooledConnection } from "./acp-client.js";
|
|
2
2
|
import { validateClientHandlers } from "./client-handlers.js";
|
|
3
|
+
import { mapThrownError } from "./errors-map.js";
|
|
3
4
|
const DEFAULT_POOL_SIZE = 1;
|
|
4
5
|
const POOL_SIZE_ENV = "AGENTPRISM_ACP_POOL_SIZE";
|
|
5
6
|
/** Resolve the per-backend pool size: explicit option wins, else env, else 1. Clamped to >= 1. */
|
|
@@ -34,7 +35,18 @@ export class AcpAgentPool {
|
|
|
34
35
|
if (this.disposed)
|
|
35
36
|
throw new Error("ACP agent pool is disposed");
|
|
36
37
|
const connection = this.selectConnection(backend);
|
|
37
|
-
|
|
38
|
+
try {
|
|
39
|
+
return await connection.openSession(opts);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (opts.signal?.aborted)
|
|
43
|
+
throw error;
|
|
44
|
+
throw mapThrownError(error, {
|
|
45
|
+
label: opts.label,
|
|
46
|
+
backendId: connection.backendId,
|
|
47
|
+
authMethods: connection.capabilities?.authMethods,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
51
|
/**
|
|
40
52
|
* Pick the connection to host the next session. Runs SYNCHRONOUSLY (no await) through to the
|
|
@@ -7,7 +7,9 @@ export type ClientMethodCoverage = "served" | "pending";
|
|
|
7
7
|
* the client rejects it until a driven wrapper can route updates, permissions, and terminals. */
|
|
8
8
|
export type AgentMethodCoverage = "driven" | "passthrough" | "guarded";
|
|
9
9
|
/** Enforceable definition of "full ACP spec support": every SDK method constant is classified
|
|
10
|
-
* here, and the tripwire test fails when an SDK bump silently widens or shrinks the protocol.
|
|
10
|
+
* here, and the tripwire test fails when an SDK bump silently widens or shrinks the protocol.
|
|
11
|
+
* Agent side: 15 operational methods are driven (plus initialize), 1 is guarded (session/fork),
|
|
12
|
+
* and the passthrough remainder is nes/*, document/*, and mcp/message. */
|
|
11
13
|
export declare const CLIENT_METHOD_COVERAGE: Record<ClientMethod, ClientMethodCoverage>;
|
|
12
14
|
export declare const AGENT_METHOD_COVERAGE: Record<AgentMethod, AgentMethodCoverage>;
|
|
13
15
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-coverage.d.ts","sourceRoot":"","sources":["../src/protocol-coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEzE,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B,KAAK,YAAY,GAAG,OAAO,CAAC,OAAO,cAAc,CAAC,CAAC;AACnD,KAAK,WAAW,GAAG,OAAO,CAAC,OAAO,aAAa,CAAC,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC;AACxD;kGACkG;AAClG,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE;
|
|
1
|
+
{"version":3,"file":"protocol-coverage.d.ts","sourceRoot":"","sources":["../src/protocol-coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEzE,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B,KAAK,YAAY,GAAG,OAAO,CAAC,OAAO,cAAc,CAAC,CAAC;AACnD,KAAK,WAAW,GAAG,OAAO,CAAC,OAAO,aAAa,CAAC,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC;AACxD;kGACkG;AAClG,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE;;;2EAG2E;AAC3E,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAe7E,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,mBAAmB,CA6B1E,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { AGENT_METHODS, CLIENT_METHODS } from "@agentclientprotocol/sdk";
|
|
2
2
|
/** Enforceable definition of "full ACP spec support": every SDK method constant is classified
|
|
3
|
-
* here, and the tripwire test fails when an SDK bump silently widens or shrinks the protocol.
|
|
3
|
+
* here, and the tripwire test fails when an SDK bump silently widens or shrinks the protocol.
|
|
4
|
+
* Agent side: 15 operational methods are driven (plus initialize), 1 is guarded (session/fork),
|
|
5
|
+
* and the passthrough remainder is nes/*, document/*, and mcp/message. */
|
|
4
6
|
export const CLIENT_METHOD_COVERAGE = {
|
|
5
7
|
[CLIENT_METHODS.session_request_permission]: "served",
|
|
6
8
|
[CLIENT_METHODS.session_update]: "served",
|
|
@@ -19,10 +21,10 @@ export const CLIENT_METHOD_COVERAGE = {
|
|
|
19
21
|
};
|
|
20
22
|
export const AGENT_METHOD_COVERAGE = {
|
|
21
23
|
[AGENT_METHODS.initialize]: "driven",
|
|
22
|
-
[AGENT_METHODS.authenticate]: "
|
|
23
|
-
[AGENT_METHODS.providers_list]: "
|
|
24
|
-
[AGENT_METHODS.providers_set]: "
|
|
25
|
-
[AGENT_METHODS.providers_disable]: "
|
|
24
|
+
[AGENT_METHODS.authenticate]: "driven",
|
|
25
|
+
[AGENT_METHODS.providers_list]: "driven",
|
|
26
|
+
[AGENT_METHODS.providers_set]: "driven",
|
|
27
|
+
[AGENT_METHODS.providers_disable]: "driven",
|
|
26
28
|
[AGENT_METHODS.session_new]: "driven",
|
|
27
29
|
[AGENT_METHODS.session_load]: "driven",
|
|
28
30
|
[AGENT_METHODS.session_set_mode]: "driven",
|
|
@@ -35,7 +37,7 @@ export const AGENT_METHOD_COVERAGE = {
|
|
|
35
37
|
[AGENT_METHODS.session_fork]: "guarded",
|
|
36
38
|
[AGENT_METHODS.session_resume]: "driven",
|
|
37
39
|
[AGENT_METHODS.session_close]: "driven",
|
|
38
|
-
[AGENT_METHODS.logout]: "
|
|
40
|
+
[AGENT_METHODS.logout]: "driven",
|
|
39
41
|
[AGENT_METHODS.nes_start]: "passthrough",
|
|
40
42
|
[AGENT_METHODS.nes_suggest]: "passthrough",
|
|
41
43
|
[AGENT_METHODS.nes_accept]: "passthrough",
|
package/dist/runner.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AgentResult, type AgentRunner, type RunOptions } from "@automatalabs/shared-types";
|
|
2
|
-
import type { ListSessionsResponse } from "@agentclientprotocol/sdk";
|
|
2
|
+
import type { AuthenticateRequest, AuthenticateResponse, AuthMethod, DisableProviderRequest, DisableProviderResponse, ListProvidersResponse, ListSessionsResponse, LogoutResponse, SetProviderRequest, SetProviderResponse } from "@agentclientprotocol/sdk";
|
|
3
3
|
import type { TSchema } from "typebox";
|
|
4
4
|
import { type AcpPoolOptions } from "./pool.js";
|
|
5
5
|
import { type AcpEventListener, type AcpEventName } from "./events.js";
|
|
@@ -17,6 +17,13 @@ interface LifecycleRoutingOptions {
|
|
|
17
17
|
/** Host-owned cancellation while the lifecycle request is in flight. */
|
|
18
18
|
signal?: AbortSignal;
|
|
19
19
|
}
|
|
20
|
+
/** Options for AcpAgentRunner.authMethods(). */
|
|
21
|
+
export interface AuthMethodsOptions {
|
|
22
|
+
/** Model spec used only to select the backend process. */
|
|
23
|
+
model?: string;
|
|
24
|
+
/** Coarse tier consulted only when `model` is unset. */
|
|
25
|
+
tier?: string;
|
|
26
|
+
}
|
|
20
27
|
/** Options for AcpAgentRunner.listSessions(). */
|
|
21
28
|
export interface ListSessionsOptions extends LifecycleRoutingOptions {
|
|
22
29
|
/** Optional absolute working-directory filter. */
|
|
@@ -33,6 +40,32 @@ export interface DeleteSessionOptions extends LifecycleRoutingOptions {
|
|
|
33
40
|
/** Generic ACP `_meta` passthrough for session/delete. */
|
|
34
41
|
meta?: Record<string, unknown>;
|
|
35
42
|
}
|
|
43
|
+
interface AuthProviderRoutingOptions extends LifecycleRoutingOptions {
|
|
44
|
+
/** Generic ACP `_meta` passthrough for the request. */
|
|
45
|
+
meta?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
/** Options for AcpAgentRunner.authenticate(). */
|
|
48
|
+
export interface AuthenticateOptions extends AuthProviderRoutingOptions {
|
|
49
|
+
/** Authentication method id advertised by runner.authMethods(). */
|
|
50
|
+
methodId: AuthenticateRequest["methodId"];
|
|
51
|
+
}
|
|
52
|
+
/** Options for AcpAgentRunner.listProviders(). */
|
|
53
|
+
export interface ListProvidersOptions extends AuthProviderRoutingOptions {
|
|
54
|
+
}
|
|
55
|
+
/** Options for AcpAgentRunner.setProvider(). */
|
|
56
|
+
export interface SetProviderOptions extends AuthProviderRoutingOptions {
|
|
57
|
+
providerId: SetProviderRequest["providerId"];
|
|
58
|
+
apiType: SetProviderRequest["apiType"];
|
|
59
|
+
baseUrl: SetProviderRequest["baseUrl"];
|
|
60
|
+
headers?: SetProviderRequest["headers"];
|
|
61
|
+
}
|
|
62
|
+
/** Options for AcpAgentRunner.disableProvider(). */
|
|
63
|
+
export interface DisableProviderOptions extends AuthProviderRoutingOptions {
|
|
64
|
+
providerId: DisableProviderRequest["providerId"];
|
|
65
|
+
}
|
|
66
|
+
/** Options for AcpAgentRunner.logout(). */
|
|
67
|
+
export interface LogoutOptions extends AuthProviderRoutingOptions {
|
|
68
|
+
}
|
|
36
69
|
/** Options for AcpAgentRunner.loadSession() and resumeSession(). */
|
|
37
70
|
export interface ReattachSessionOptions extends InteractiveSessionOptions {
|
|
38
71
|
/** Existing backend session id to route before the lifecycle request is sent. */
|
|
@@ -53,6 +86,11 @@ export interface AcpRunnerOptions extends AcpPoolOptions {
|
|
|
53
86
|
* elicitation form/url support on every connection; sessions may override the resolver. */
|
|
54
87
|
onElicitation?: ElicitationResolver;
|
|
55
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* ACP-backed AgentRunner implementation. The caller that constructs an AcpAgentRunner owns it:
|
|
91
|
+
* pass it into managers/runs as needed, then call dispose() (or use `await using`) when that
|
|
92
|
+
* owner is done with the pooled and dedicated backend processes.
|
|
93
|
+
*/
|
|
56
94
|
export declare class AcpAgentRunner implements AgentRunner {
|
|
57
95
|
private readonly pool;
|
|
58
96
|
/** The resolved custom-backend registry (env + option, validated at construction). */
|
|
@@ -99,6 +137,18 @@ export declare class AcpAgentRunner implements AgentRunner {
|
|
|
99
137
|
* is one).
|
|
100
138
|
*/
|
|
101
139
|
openSession(opts: InteractiveSessionOptions): Promise<InteractiveSession>;
|
|
140
|
+
/** Return the selected backend's initialize-advertised authentication methods. */
|
|
141
|
+
authMethods(opts?: AuthMethodsOptions): Promise<AuthMethod[]>;
|
|
142
|
+
/** Drive ACP authenticate on the selected backend. */
|
|
143
|
+
authenticate(opts: AuthenticateOptions): Promise<AuthenticateResponse | void>;
|
|
144
|
+
/** List configurable providers from the selected backend. */
|
|
145
|
+
listProviders(opts?: ListProvidersOptions): Promise<ListProvidersResponse>;
|
|
146
|
+
/** Configure one provider on the selected backend. */
|
|
147
|
+
setProvider(opts: SetProviderOptions): Promise<SetProviderResponse | void>;
|
|
148
|
+
/** Disable one provider on the selected backend. */
|
|
149
|
+
disableProvider(opts: DisableProviderOptions): Promise<DisableProviderResponse | void>;
|
|
150
|
+
/** Logout through the selected backend. */
|
|
151
|
+
logout(opts?: LogoutOptions): Promise<LogoutResponse | void>;
|
|
102
152
|
/** List persisted ACP sessions from the selected backend. */
|
|
103
153
|
listSessions(opts?: ListSessionsOptions): Promise<ListSessionsResponse>;
|
|
104
154
|
/** Delete a persisted ACP session from the selected backend. */
|
|
@@ -111,6 +161,7 @@ export declare class AcpAgentRunner implements AgentRunner {
|
|
|
111
161
|
/** Tear down the whole pool (close every long-lived process). Call when the run ends / the
|
|
112
162
|
* runner is disposed. Beyond the AgentRunner seam (additive) — never enters the resume hash. */
|
|
113
163
|
dispose(): Promise<void>;
|
|
164
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
114
165
|
private createInteractiveSession;
|
|
115
166
|
private createDedicatedConnection;
|
|
116
167
|
/** Build the backend choice, model-selection spec, tool policy, and session/new options in one
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAmBA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.js
CHANGED
|
@@ -29,6 +29,11 @@ import { registryWithRunBackends, resolveBackendRegistry, } from "./registry.js"
|
|
|
29
29
|
import { mapThrownError } from "./errors-map.js";
|
|
30
30
|
import { resolveStructuredOutput } from "./structured-output.js";
|
|
31
31
|
import { buildRunPrompt, mergeTurnMeta, promptWithImages, validatePromptImages, } from "./prompt.js";
|
|
32
|
+
/**
|
|
33
|
+
* ACP-backed AgentRunner implementation. The caller that constructs an AcpAgentRunner owns it:
|
|
34
|
+
* pass it into managers/runs as needed, then call dispose() (or use `await using`) when that
|
|
35
|
+
* owner is done with the pooled and dedicated backend processes.
|
|
36
|
+
*/
|
|
32
37
|
export class AcpAgentRunner {
|
|
33
38
|
pool;
|
|
34
39
|
/** The resolved custom-backend registry (env + option, validated at construction). */
|
|
@@ -98,6 +103,137 @@ export class AcpAgentRunner {
|
|
|
98
103
|
async openSession(opts) {
|
|
99
104
|
return this.createInteractiveSession(opts, "openSession", (connection, prepared) => connection.openSession(prepared.sessionOptions));
|
|
100
105
|
}
|
|
106
|
+
/** Return the selected backend's initialize-advertised authentication methods. */
|
|
107
|
+
async authMethods(opts = {}) {
|
|
108
|
+
if (this.disposed)
|
|
109
|
+
throw new Error("ACP agent runner is disposed");
|
|
110
|
+
const backend = selectBackend(opts, this.backends);
|
|
111
|
+
const connection = this.createDedicatedConnection(backend, () => undefined);
|
|
112
|
+
try {
|
|
113
|
+
if (this.disposed)
|
|
114
|
+
throw new Error("ACP agent runner is disposed");
|
|
115
|
+
return await connection.authMethods();
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
await disposeBestEffort(connection);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Drive ACP authenticate on the selected backend. */
|
|
122
|
+
async authenticate(opts) {
|
|
123
|
+
if (this.disposed)
|
|
124
|
+
throw new Error("ACP agent runner is disposed");
|
|
125
|
+
validateRequiredString(opts.methodId, opts.label, "authenticate", "methodId");
|
|
126
|
+
opts.signal?.throwIfAborted();
|
|
127
|
+
const backend = selectBackend(opts, this.backends);
|
|
128
|
+
const connection = this.createDedicatedConnection(backend, () => undefined);
|
|
129
|
+
try {
|
|
130
|
+
const request = {
|
|
131
|
+
methodId: opts.methodId,
|
|
132
|
+
...(opts.meta ? { _meta: opts.meta } : {}),
|
|
133
|
+
};
|
|
134
|
+
const response = await connection.authenticate(request, opts.label);
|
|
135
|
+
opts.signal?.throwIfAborted();
|
|
136
|
+
if (this.disposed)
|
|
137
|
+
throw new Error("ACP agent runner is disposed");
|
|
138
|
+
return response;
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
await disposeBestEffort(connection);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** List configurable providers from the selected backend. */
|
|
145
|
+
async listProviders(opts = {}) {
|
|
146
|
+
if (this.disposed)
|
|
147
|
+
throw new Error("ACP agent runner is disposed");
|
|
148
|
+
opts.signal?.throwIfAborted();
|
|
149
|
+
const backend = selectBackend(opts, this.backends);
|
|
150
|
+
const connection = this.createDedicatedConnection(backend, () => undefined);
|
|
151
|
+
try {
|
|
152
|
+
const request = {
|
|
153
|
+
...(opts.meta ? { _meta: opts.meta } : {}),
|
|
154
|
+
};
|
|
155
|
+
const response = await connection.listProviders(request, opts.label);
|
|
156
|
+
opts.signal?.throwIfAborted();
|
|
157
|
+
if (this.disposed)
|
|
158
|
+
throw new Error("ACP agent runner is disposed");
|
|
159
|
+
return response;
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await disposeBestEffort(connection);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Configure one provider on the selected backend. */
|
|
166
|
+
async setProvider(opts) {
|
|
167
|
+
if (this.disposed)
|
|
168
|
+
throw new Error("ACP agent runner is disposed");
|
|
169
|
+
validateRequiredString(opts.providerId, opts.label, "setProvider", "providerId");
|
|
170
|
+
validateRequiredString(opts.apiType, opts.label, "setProvider", "apiType");
|
|
171
|
+
validateRequiredString(opts.baseUrl, opts.label, "setProvider", "baseUrl");
|
|
172
|
+
opts.signal?.throwIfAborted();
|
|
173
|
+
const backend = selectBackend(opts, this.backends);
|
|
174
|
+
const connection = this.createDedicatedConnection(backend, () => undefined);
|
|
175
|
+
try {
|
|
176
|
+
const request = {
|
|
177
|
+
providerId: opts.providerId,
|
|
178
|
+
apiType: opts.apiType,
|
|
179
|
+
baseUrl: opts.baseUrl,
|
|
180
|
+
...(opts.headers ? { headers: opts.headers } : {}),
|
|
181
|
+
...(opts.meta ? { _meta: opts.meta } : {}),
|
|
182
|
+
};
|
|
183
|
+
const response = await connection.setProvider(request, opts.label);
|
|
184
|
+
opts.signal?.throwIfAborted();
|
|
185
|
+
if (this.disposed)
|
|
186
|
+
throw new Error("ACP agent runner is disposed");
|
|
187
|
+
return response;
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
await disposeBestEffort(connection);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Disable one provider on the selected backend. */
|
|
194
|
+
async disableProvider(opts) {
|
|
195
|
+
if (this.disposed)
|
|
196
|
+
throw new Error("ACP agent runner is disposed");
|
|
197
|
+
validateRequiredString(opts.providerId, opts.label, "disableProvider", "providerId");
|
|
198
|
+
opts.signal?.throwIfAborted();
|
|
199
|
+
const backend = selectBackend(opts, this.backends);
|
|
200
|
+
const connection = this.createDedicatedConnection(backend, () => undefined);
|
|
201
|
+
try {
|
|
202
|
+
const request = {
|
|
203
|
+
providerId: opts.providerId,
|
|
204
|
+
...(opts.meta ? { _meta: opts.meta } : {}),
|
|
205
|
+
};
|
|
206
|
+
const response = await connection.disableProvider(request, opts.label);
|
|
207
|
+
opts.signal?.throwIfAborted();
|
|
208
|
+
if (this.disposed)
|
|
209
|
+
throw new Error("ACP agent runner is disposed");
|
|
210
|
+
return response;
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
await disposeBestEffort(connection);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** Logout through the selected backend. */
|
|
217
|
+
async logout(opts = {}) {
|
|
218
|
+
if (this.disposed)
|
|
219
|
+
throw new Error("ACP agent runner is disposed");
|
|
220
|
+
opts.signal?.throwIfAborted();
|
|
221
|
+
const backend = selectBackend(opts, this.backends);
|
|
222
|
+
const connection = this.createDedicatedConnection(backend, () => undefined);
|
|
223
|
+
try {
|
|
224
|
+
const request = {
|
|
225
|
+
...(opts.meta ? { _meta: opts.meta } : {}),
|
|
226
|
+
};
|
|
227
|
+
const response = await connection.logout(request, opts.label);
|
|
228
|
+
opts.signal?.throwIfAborted();
|
|
229
|
+
if (this.disposed)
|
|
230
|
+
throw new Error("ACP agent runner is disposed");
|
|
231
|
+
return response;
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
await disposeBestEffort(connection);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
101
237
|
/** List persisted ACP sessions from the selected backend. */
|
|
102
238
|
async listSessions(opts = {}) {
|
|
103
239
|
if (this.disposed)
|
|
@@ -180,22 +316,24 @@ export class AcpAgentRunner {
|
|
|
180
316
|
registry,
|
|
181
317
|
signal: opts.signal,
|
|
182
318
|
});
|
|
183
|
-
|
|
319
|
+
let session;
|
|
184
320
|
try {
|
|
321
|
+
session = await this.pool.acquire(prepared.backend, prepared.sessionOptions);
|
|
322
|
+
const activeSession = session;
|
|
185
323
|
opts.signal?.throwIfAborted();
|
|
186
324
|
// For a CUSTOM backend chosen by its registered name, the name itself is routing, not a
|
|
187
325
|
// model id: "browser" selects nothing; "browser/foo" selects "foo". Built-ins get the
|
|
188
326
|
// full spec unchanged (their catalogs match provider-prefixed and bare ids).
|
|
189
|
-
await applyModelSelection(
|
|
327
|
+
await applyModelSelection(activeSession, prepared.modelSpec, opts);
|
|
190
328
|
opts.signal?.throwIfAborted();
|
|
191
329
|
if (opts.mode)
|
|
192
|
-
await
|
|
330
|
+
await activeSession.setMode(opts.mode);
|
|
193
331
|
const text = buildRunPrompt(prompt, opts, schema, prepared.backend);
|
|
194
332
|
const initialPrompt = opts.images && opts.images.length > 0 ? promptWithImages(text, opts.images) : text;
|
|
195
333
|
// Generic turn-scoped _meta passthrough merged UNDER the backend-computed keys (e.g. the
|
|
196
334
|
// outputSchema forward when a schema is set) — user meta never clobbers the schema channel.
|
|
197
335
|
const promptMeta = mergeTurnMeta(opts.promptMeta, prepared.backend.promptMeta(schema));
|
|
198
|
-
const response = await
|
|
336
|
+
const response = await activeSession.prompt(initialPrompt, promptMeta);
|
|
199
337
|
opts.signal?.throwIfAborted();
|
|
200
338
|
// Inspect the turn's stop reason BEFORE the text/schema path: a refusal or truncation
|
|
201
339
|
// must surface distinctly here, never be misread as empty output or burned through the
|
|
@@ -204,13 +342,13 @@ export class AcpAgentRunner {
|
|
|
204
342
|
if (schema) {
|
|
205
343
|
const structuredSession = {
|
|
206
344
|
prompt: async (repromptText) => {
|
|
207
|
-
const repromptResponse = await
|
|
345
|
+
const repromptResponse = await activeSession.prompt(repromptText, promptMeta);
|
|
208
346
|
// A repair turn that refuses / truncates / cancels must also surface distinctly
|
|
209
347
|
// instead of silently continuing the ladder.
|
|
210
348
|
assertNormalStopReason(repromptResponse.stopReason, opts.label);
|
|
211
349
|
},
|
|
212
|
-
lastText: () =>
|
|
213
|
-
tryNative: () => prepared.backend.nativeStructured(
|
|
350
|
+
lastText: () => activeSession.currentTurnText(),
|
|
351
|
+
tryNative: () => prepared.backend.nativeStructured(activeSession),
|
|
214
352
|
};
|
|
215
353
|
const result = await resolveStructuredOutput(structuredSession, schema, {
|
|
216
354
|
maxSchemaRetries: opts.maxSchemaRetries,
|
|
@@ -219,7 +357,7 @@ export class AcpAgentRunner {
|
|
|
219
357
|
});
|
|
220
358
|
return result;
|
|
221
359
|
}
|
|
222
|
-
const finalText =
|
|
360
|
+
const finalText = activeSession.currentTurnText().trim();
|
|
223
361
|
if (!finalText) {
|
|
224
362
|
throw new WorkflowError("Subagent produced no assistant output", WorkflowErrorCode.AGENT_EMPTY_OUTPUT, {
|
|
225
363
|
recoverable: true,
|
|
@@ -232,28 +370,34 @@ export class AcpAgentRunner {
|
|
|
232
370
|
// Abort is the engine's concern (throwIfAborted before/after the call) — re-throw it raw.
|
|
233
371
|
if (opts.signal?.aborted)
|
|
234
372
|
throw error;
|
|
235
|
-
throw mapThrownError(error,
|
|
373
|
+
throw mapThrownError(error, {
|
|
374
|
+
label: opts.label,
|
|
375
|
+
backendId: prepared.backend.id,
|
|
376
|
+
authMethods: session?.capabilities?.authMethods,
|
|
377
|
+
});
|
|
236
378
|
}
|
|
237
379
|
finally {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
380
|
+
if (session) {
|
|
381
|
+
// Read real usage on BOTH success and error so partial usage is never lost.
|
|
382
|
+
try {
|
|
383
|
+
opts.onUsage?.(session.usage.toAgentUsage());
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
// usage is best-effort; never let it mask the real result/error.
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
opts.onHistory?.(session.history);
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
// history is diagnostic only.
|
|
393
|
+
}
|
|
394
|
+
// Release the SESSION (best-effort session/close) WITHOUT killing the pooled process.
|
|
395
|
+
try {
|
|
396
|
+
await session.release();
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
// release is best-effort (session already untracked); never mask the real result/error.
|
|
400
|
+
}
|
|
257
401
|
}
|
|
258
402
|
}
|
|
259
403
|
}
|
|
@@ -267,6 +411,9 @@ export class AcpAgentRunner {
|
|
|
267
411
|
await this.pool.dispose();
|
|
268
412
|
this.events.removeAllListeners();
|
|
269
413
|
}
|
|
414
|
+
async [Symbol.asyncDispose]() {
|
|
415
|
+
await this.dispose();
|
|
416
|
+
}
|
|
270
417
|
async createInteractiveSession(opts, methodName, open) {
|
|
271
418
|
if (this.disposed)
|
|
272
419
|
throw new Error("ACP agent runner is disposed");
|
|
@@ -320,7 +467,13 @@ export class AcpAgentRunner {
|
|
|
320
467
|
// best-effort: lifecycle setup failed, so teardown must never mask the real error.
|
|
321
468
|
}
|
|
322
469
|
await disposeBestEffort(connection);
|
|
323
|
-
|
|
470
|
+
if (opts.signal?.aborted)
|
|
471
|
+
throw error;
|
|
472
|
+
throw mapThrownError(error, {
|
|
473
|
+
label: opts.label,
|
|
474
|
+
backendId: prepared.backend.id,
|
|
475
|
+
authMethods: connection.capabilities?.authMethods,
|
|
476
|
+
});
|
|
324
477
|
}
|
|
325
478
|
}
|
|
326
479
|
createDedicatedConnection(backend, onDead) {
|
|
@@ -491,8 +644,11 @@ function validateOptionalLifecycleCwd(cwd, label, methodName) {
|
|
|
491
644
|
validateInteractiveCwd(cwd, label, methodName);
|
|
492
645
|
}
|
|
493
646
|
function validateLifecycleSessionId(sessionId, label, methodName) {
|
|
494
|
-
|
|
495
|
-
|
|
647
|
+
validateRequiredString(sessionId, label, methodName, "sessionId");
|
|
648
|
+
}
|
|
649
|
+
function validateRequiredString(value, label, methodName, fieldName) {
|
|
650
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
651
|
+
throw new WorkflowError(`${methodName} requires ${fieldName} to be a non-empty string`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
|
|
496
652
|
}
|
|
497
653
|
}
|
|
498
654
|
async function disposeBestEffort(connection) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automatalabs/acp-agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@agentclientprotocol/claude-agent-acp": "0.56.0",
|
|
32
32
|
"@automatalabs/codex-acp": "1.4.0",
|
|
33
33
|
"typebox": "1.3.2",
|
|
34
|
-
"@automatalabs/shared-types": "0.
|
|
34
|
+
"@automatalabs/shared-types": "0.12.0"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsc -b",
|