@automatalabs/acp-agents 0.12.0 → 0.14.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.
@@ -1,4 +1,4 @@
1
- import { type ContentBlock, type AgentNotificationMethod, type AgentNotificationParamsByMethod, type AgentRequestMethod, type AgentRequestParamsByMethod, type AgentRequestResponsesByMethod, type PromptRequest, type PromptResponse, type RequestPermissionResponse, type SendRequestOptions, type SessionConfigOption, type SessionNotification, type SetSessionConfigOptionRequest, type SetSessionConfigOptionResponse } from "@agentclientprotocol/sdk";
1
+ import { 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";
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";
@@ -26,10 +26,11 @@ declare class SessionState {
26
26
  readonly usage: UsageAccumulator;
27
27
  readonly pendingPermissions: Set<(outcome: RequestPermissionResponse) => void>;
28
28
  rawResultSuccess: RawResultSuccess | undefined;
29
+ modes: SessionModeState | null | undefined;
29
30
  private turnStartIndex;
30
31
  /** `label`/`runId` are carried here ONLY so the MultiplexClient can stamp them onto emitted
31
32
  * events as context — they never affect routing or the wire request. */
32
- constructor(cwd: string, policy: ToolPolicy, permissionResolver?: PermissionResolver | undefined, label?: string | undefined, runId?: string | undefined, retainSessionLog?: boolean);
33
+ constructor(cwd: string, policy: ToolPolicy, permissionResolver?: PermissionResolver | undefined, label?: string | undefined, runId?: string | undefined, modes?: SessionModeState | null, retainSessionLog?: boolean);
33
34
  /** Mark the start of a new turn so currentTurnText()/structured_output read only this turn.
34
35
  * Long-lived interactive sessions can opt out of retaining old text/history because hosts
35
36
  * stream live events and keep their own transcript; clearing here prevents dead logs from
@@ -126,6 +127,9 @@ export declare class PooledConnection {
126
127
  /** Drop the backend-declared bare `_meta` keys the connected agent did not advertise support
127
128
  * for (see gateCustomMeta). Applied to BOTH session/new and session/prompt `_meta`. */
128
129
  gateCustomMeta(meta: Record<string, unknown> | undefined): Record<string, unknown> | undefined;
130
+ private assertSupportedMcpServers;
131
+ private sessionRequestMeta;
132
+ private assertLifecycleSupported;
129
133
  /** Mark this connection dead exactly once, then ask the pool to evict it. Idempotent. */
130
134
  private die;
131
135
  private stderrSuffix;
@@ -139,10 +143,22 @@ export declare class PooledConnection {
139
143
  * synchronously (before the first await) so the pool's load accounting is race-free.
140
144
  */
141
145
  openSession(opts: AcpSessionOptions): Promise<SessionHandle>;
146
+ /** Reopen an existing session and replay its transcript through the router before resolving. */
147
+ loadSession(sessionId: string, opts: AcpSessionOptions): Promise<SessionHandle>;
148
+ /** Reopen an existing session without transcript replay. */
149
+ resumeSession(sessionId: string, opts: AcpSessionOptions): Promise<SessionHandle>;
150
+ private rawAgentRequest;
151
+ private reattachSession;
152
+ /** session/list on a dedicated connection, gated on the initialize advertisement. */
153
+ listSessions(request: ListSessionsRequest, label?: string): Promise<ListSessionsResponse>;
154
+ /** session/delete on a dedicated connection, gated on the initialize advertisement. */
155
+ deleteSession(request: DeleteSessionRequest, label?: string): Promise<void>;
142
156
  /** session/prompt on this connection, raced against process death. */
143
157
  prompt(request: PromptRequest): Promise<PromptResponse>;
144
158
  /** session/set_config_option on this connection, raced against process death. */
145
159
  setSessionConfigOption(request: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse>;
160
+ /** session/set_mode on this connection, raced against process death. */
161
+ setSessionMode(request: SetSessionModeRequest): Promise<SetSessionModeResponse>;
146
162
  /** RAW protocol escape hatch: this makes the full ACP spec reachable (for example
147
163
  * session/set_mode, session/fork, authenticate). Prefer the named wrappers when they exist
148
164
  * because they preserve engine semantics such as accumulation/drain and usage recording;
@@ -184,6 +200,10 @@ export declare class SessionHandle implements StructuredSource {
184
200
  get usage(): UsageAccumulator;
185
201
  /** Diagnostic message/tool history accumulated across this session's run. */
186
202
  get history(): AgentHistoryEntry[];
203
+ /** Assistant text accumulated across the retained session log. */
204
+ get text(): string;
205
+ /** Agent-advertised session mode catalog plus the currently active mode, if supported. */
206
+ get modes(): SessionModeState | null | undefined;
187
207
  /**
188
208
  * Select the model for this session from the agent-advertised config options (§5.4).
189
209
  * Returns `matched:false` (the caller fires onModelFallback) when the catalog has no value
@@ -220,6 +240,8 @@ export declare class SessionHandle implements StructuredSource {
220
240
  * A boolean value drives a `type: "boolean"` option (the request must carry the type
221
241
  * discriminator on the wire); a string value drives a select option. */
222
242
  private applyConfigOption;
243
+ /** Switch the session's operating mode through ACP's strict confinement channel. */
244
+ setMode(modeId: string): Promise<void>;
223
245
  /** Send a prompt turn and drain it; returns the final PromptResponse. */
224
246
  prompt(content: string | ContentBlock[], promptMeta?: Record<string, unknown>): Promise<PromptResponse>;
225
247
  /** StructuredSource — the latest turn's assistant text. */
@@ -1 +1 @@
1
- {"version":3,"file":"acp-client.d.ts","sourceRoot":"","sources":["../src/acp-client.ts"],"names":[],"mappings":"AAwBA,OAAO,EAUL,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,+BAA+B,EACpC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAIlC,KAAK,aAAa,EAClB,KAAK,cAAc,EAMnB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAGxB,KAAK,mBAAmB,EACxB,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EAOpC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAML,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGL,KAAK,cAAc,EAEpB,MAAM,sBAAsB,CAAC;AAiB9B,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAQD;8FAC8F;AAC9F,cAAM,YAAY;IAWd,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,MAAM,EAAE,UAAU;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAfnC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAM;IACnC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,EAAE,CAAM;IAC3C,QAAQ,CAAC,KAAK,mBAA0B;IACxC,QAAQ,CAAC,kBAAkB,gBAAqB,yBAAyB,KAAK,IAAI,EAAI;IACtF,gBAAgB,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC/C,OAAO,CAAC,cAAc,CAAK;IAE3B;6EACyE;gBAE9D,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,UAAU,EAClB,kBAAkB,CAAC,EAAE,kBAAkB,YAAA,EACvC,KAAK,CAAC,EAAE,MAAM,YAAA,EACd,KAAK,CAAC,EAAE,MAAM,YAAA,EACN,gBAAgB,UAAO;IAG1C;;;2DAGuD;IACvD,SAAS,IAAI,IAAI;IAWjB,eAAe,IAAI,MAAM;IAIzB,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,GAAG,IAAI;IAoCxD,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI;IAM5D;mFAC+E;IAC/E,wBAAwB,IAAI,IAAI;CAGjC;AA6PD,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB;mFAC+E;IAC/E,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B;;4FAEwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;oGACgG;IAChG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;oGACgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;sDAGkD;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qFAAqF;AACrF,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C;;iFAE6E;IAC7E,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,6FAA6F;IAC7F,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,oFAAoF;IACpF,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B;8DAC0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAE9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,oGAAoG;IACpG,OAAO,CAAC,SAAS,CAAS;IAC1B,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,UAAU,CAAoB;IAEtC,kGAAkG;IAClG,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,UAAU,CAAM;IAExB,OAAO;IAwFP;kDAC8C;IAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,oBAAoB,GAAG,gBAAgB;IAI7E,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;6FACyF;IACzF,IAAI,YAAY,IAAI,sBAAsB,GAAG,SAAS,CAErD;IAED;4FACwF;IACxF,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAI9F,yFAAyF;IACzF,OAAO,CAAC,GAAG;IAcX,OAAO,CAAC,YAAY;IAKpB;uDACmD;IAC7C,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;YAS3B,UAAU;IAsDxB;;;;OAIG;IACG,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IA6DlE,sEAAsE;IACtE,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAIvD,iFAAiF;IACjF,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAIvG;;;4DAGwD;IACxD,OAAO,CAAC,MAAM,SAAS,kBAAkB,EACvC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,0BAA0B,CAAC,MAAM,CAAC,EAC1C,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACjD,OAAO,CAAC,QAAQ,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,EAC1C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,QAAQ,CAAC;IAKpB;kGAC8F;IAC9F,MAAM,CAAC,MAAM,SAAS,uBAAuB,EAC3C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,+BAA+B,CAAC,MAAM,CAAC,GAC9C,OAAO,CAAC,IAAI,CAAC;IAChB,MAAM,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE,+FAA+F;IACzF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD;;;;OAIG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBtD,gGAAgG;IAChG,OAAO,IAAI,IAAI;IASf,8FAA8F;IACxF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B/B;AAID;;;;GAIG;AACH,qBAAa,aAAc,YAAW,gBAAgB;IAMlD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IATvB,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAS;gBAGN,MAAM,EAAE,gBAAgB,EAChC,SAAS,EAAE,MAAM,EACT,KAAK,EAAE,YAAY,EACpC,aAAa,EAAE,mBAAmB,EAAE,EACnB,IAAI,EAAE,iBAAiB;IAa1C,0FAA0F;IAC1F,IAAI,KAAK,IAAI,gBAAgB,CAE5B;IAED,6EAA6E;IAC7E,IAAI,OAAO,IAAI,iBAAiB,EAAE,CAEjC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACG,WAAW,CACf,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAgBjF;;;;;;;OAOG;YACW,mBAAmB;IAoDjC;;6EAEyE;YAC3D,iBAAiB;IAS/B,yEAAyE;IACnE,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;IAoB7G,2DAA2D;IAC3D,eAAe,IAAI,MAAM;IAIzB,qFAAqF;IACrF,mBAAmB,IAAI,OAAO;IAI9B,gGAAgG;IAC1F,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,6EAA6E;IACvE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAO/B"}
1
+ {"version":3,"file":"acp-client.d.ts","sourceRoot":"","sources":["../src/acp-client.ts"],"names":[],"mappings":"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"}
@@ -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, gateCustomMeta, isSupportedProtocolVersion, negotiateCapabilities, unsupportedMcpServer, } from "./capabilities.js";
27
+ import { adaptPromptContent, 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";
@@ -42,6 +42,15 @@ const CLOSE_SESSION_TIMEOUT_MS = 5_000;
42
42
  /** Bound the graceful SIGTERM shutdown before escalating to SIGKILL. */
43
43
  const DISPOSE_SIGKILL_GRACE_MS = 2_000;
44
44
  const TOMBSTONE_SESSION_CAP = 64;
45
+ const GUARDED_STATEFUL_REQUESTS = new Map([
46
+ [AGENT_METHODS.session_new, "use openSession()"],
47
+ [AGENT_METHODS.session_load, "use loadSession()"],
48
+ [AGENT_METHODS.session_resume, "use resumeSession()"],
49
+ [
50
+ AGENT_METHODS.session_fork,
51
+ "no driven wrapper yet; raw forked sessions cannot be routed (permissions auto-cancel)",
52
+ ],
53
+ ]);
45
54
  /** Per-session accumulator: assistant text, tool history, usage, the Claude raw structured_output,
46
55
  * and the permission policy/resolver used to answer permission requests for THIS session. */
47
56
  class SessionState {
@@ -56,16 +65,18 @@ class SessionState {
56
65
  usage = new UsageAccumulator();
57
66
  pendingPermissions = new Set();
58
67
  rawResultSuccess;
68
+ modes;
59
69
  turnStartIndex = 0;
60
70
  /** `label`/`runId` are carried here ONLY so the MultiplexClient can stamp them onto emitted
61
71
  * events as context — they never affect routing or the wire request. */
62
- constructor(cwd, policy, permissionResolver, label, runId, retainSessionLog = true) {
72
+ constructor(cwd, policy, permissionResolver, label, runId, modes, retainSessionLog = true) {
63
73
  this.cwd = cwd;
64
74
  this.policy = policy;
65
75
  this.permissionResolver = permissionResolver;
66
76
  this.label = label;
67
77
  this.runId = runId;
68
78
  this.retainSessionLog = retainSessionLog;
79
+ this.modes = modes;
69
80
  }
70
81
  /** Mark the start of a new turn so currentTurnText()/structured_output read only this turn.
71
82
  * Long-lived interactive sessions can opt out of retaining old text/history because hosts
@@ -116,6 +127,13 @@ class SessionState {
116
127
  this.usage.recordContextTokens(update.used, update.size);
117
128
  break;
118
129
  }
130
+ case "current_mode_update": {
131
+ this.modes = {
132
+ ...(this.modes ?? { availableModes: [] }),
133
+ currentModeId: update.currentModeId,
134
+ };
135
+ break;
136
+ }
119
137
  default:
120
138
  break;
121
139
  }
@@ -309,6 +327,35 @@ function cancelledPermissionResponse() {
309
327
  function methodNotAdvertised(method) {
310
328
  return new RequestError(-32601, `${method} was not advertised by this client`, { method });
311
329
  }
330
+ function assertSafeRawRequest(method) {
331
+ const guidance = GUARDED_STATEFUL_REQUESTS.get(method);
332
+ if (!guidance)
333
+ return;
334
+ throw new Error(`Raw ACP request "${method}" is guarded: ${guidance}. Sessions created, reopened, or forked ` +
335
+ "outside the router are unregistered: session/update notifications do not fold into an " +
336
+ "accumulator, permission requests auto-cancel, and fs/terminal dispatch fails for unknown sessions.");
337
+ }
338
+ function modeIds(modes) {
339
+ return modes?.availableModes.map((mode) => mode.id) ?? [];
340
+ }
341
+ function modeSelectionError(backendId, requested, advertisedIds, label, cause) {
342
+ const advertised = advertisedIds.length > 0 ? advertisedIds.join(", ") : "none";
343
+ const suffix = cause ? `: ${thrownMessage(cause)}` : "";
344
+ return new WorkflowError(`ACP agent (${backendId}) cannot apply session mode "${requested}" (advertised modes: ${advertised})${suffix}`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label, details: cause });
345
+ }
346
+ function lifecycleCapabilityError(backendId, method, capabilities, label) {
347
+ const advertised = capabilities
348
+ ? describeLifecycleAdvertisement(capabilities.agent)
349
+ : "initialize did not complete";
350
+ return new WorkflowError(`ACP agent (${backendId}) does not advertise ${method}; advertised lifecycle capabilities: ${advertised}`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
351
+ }
352
+ function thrownMessage(error) {
353
+ if (error instanceof Error)
354
+ return error.message;
355
+ if (typeof error === "string")
356
+ return error;
357
+ return String(error);
358
+ }
312
359
  const DEFAULT_INIT_TIMEOUT_MS = 60_000;
313
360
  /** Deadline for the one-time ACP `initialize` handshake per pooled process. Overridable via
314
361
  * AGENTPRISM_ACP_INIT_TIMEOUT_MS (e.g. for slow cold-start backends). Clamped to >= 1s. */
@@ -466,6 +513,35 @@ export class PooledConnection {
466
513
  gateCustomMeta(meta) {
467
514
  return gateCustomMeta(meta, this.negotiated?.customMetaSupport, this.negotiated?.gatedKeys);
468
515
  }
516
+ assertSupportedMcpServers(opts) {
517
+ const unsupported = this.negotiated
518
+ ? unsupportedMcpServer(opts.mcpServers, this.negotiated.agent)
519
+ : undefined;
520
+ if (!unsupported)
521
+ return;
522
+ throw new WorkflowError(`MCP server "${unsupported.name}" uses the "${unsupported.transport}" transport, which the ` +
523
+ `${this.backendId} agent does not support`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: opts.label });
524
+ }
525
+ sessionRequestMeta(opts) {
526
+ return this.gateCustomMeta(stampRunId(layerMeta(this.backend.sessionMetaDefaults?.(), opts.meta, this.backend.sessionMeta(opts.schema, {
527
+ baseInstructions: opts.baseInstructions,
528
+ developerInstructions: opts.developerInstructions,
529
+ })), opts.runId));
530
+ }
531
+ assertLifecycleSupported(method, label) {
532
+ const supported = method === AGENT_METHODS.session_load
533
+ ? this.negotiated?.supportsLoadSession
534
+ : method === AGENT_METHODS.session_list
535
+ ? this.negotiated?.supportsListSessions
536
+ : method === AGENT_METHODS.session_delete
537
+ ? this.negotiated?.supportsDeleteSession
538
+ : method === AGENT_METHODS.session_resume
539
+ ? this.negotiated?.supportsResumeSession
540
+ : false;
541
+ if (supported)
542
+ return;
543
+ throw lifecycleCapabilityError(this.backendId, method, this.negotiated, label);
544
+ }
469
545
  /** Mark this connection dead exactly once, then ask the pool to evict it. Idempotent. */
470
546
  die(error) {
471
547
  if (!this._alive)
@@ -553,24 +629,14 @@ export class PooledConnection {
553
629
  // does not advertise (http/sse gated on mcpCapabilities; stdio is always serviceable).
554
630
  // Fail-fast and non-recoverable — re-running the same incompatible transport can never
555
631
  // succeed. Lenient for agents that advertise no mcpCapabilities (the legacy passthrough).
556
- const unsupported = this.negotiated
557
- ? unsupportedMcpServer(opts.mcpServers, this.negotiated.agent)
558
- : undefined;
559
- if (unsupported) {
560
- throw new WorkflowError(`MCP server "${unsupported.name}" uses the "${unsupported.transport}" transport, which the ` +
561
- `${this.backendId} agent does not support`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: opts.label });
562
- }
563
- const state = new SessionState(opts.cwd, opts.policy, opts.permissionResolver, opts.label, opts.runId, opts.retainSessionLog ?? true);
632
+ this.assertSupportedMcpServers(opts);
564
633
  // session/new `_meta`, layered lowest-to-highest precedence: the backend's static
565
634
  // defaults (a custom registry entry's `sessionMeta`), then the generic user passthrough
566
635
  // (opts.meta), then the backend's protocol-critical `_meta` (Claude schema channel;
567
636
  // Codex base/developer instructions), then the engine runId correlation stamp. The result
568
637
  // is gated against the agent's advertised custom capabilities (a declared key the agent
569
638
  // said it does not honor is dropped). When no layer survives, no `_meta` is sent.
570
- const meta = this.gateCustomMeta(stampRunId(layerMeta(this.backend.sessionMetaDefaults?.(), opts.meta, this.backend.sessionMeta(opts.schema, {
571
- baseInstructions: opts.baseInstructions,
572
- developerInstructions: opts.developerInstructions,
573
- })), opts.runId));
639
+ const meta = this.sessionRequestMeta(opts);
574
640
  const request = {
575
641
  cwd: opts.cwd,
576
642
  // Client-provided MCP servers (additive run input), else the default empty list.
@@ -578,6 +644,7 @@ export class PooledConnection {
578
644
  ...(meta ? { _meta: meta } : {}),
579
645
  };
580
646
  const response = await this.race(this.connection.agent.request(AGENT_METHODS.session_new, request));
647
+ const state = new SessionState(opts.cwd, opts.policy, opts.permissionResolver, opts.label, opts.runId, response.modes, opts.retainSessionLog ?? true);
581
648
  this.client.register(response.sessionId, state);
582
649
  return new SessionHandle(this, response.sessionId, state, response.configOptions ?? [], opts);
583
650
  }
@@ -586,6 +653,71 @@ export class PooledConnection {
586
653
  throw error;
587
654
  }
588
655
  }
656
+ /** Reopen an existing session and replay its transcript through the router before resolving. */
657
+ loadSession(sessionId, opts) {
658
+ return this.reattachSession(AGENT_METHODS.session_load, sessionId, opts);
659
+ }
660
+ /** Reopen an existing session without transcript replay. */
661
+ resumeSession(sessionId, opts) {
662
+ return this.reattachSession(AGENT_METHODS.session_resume, sessionId, opts);
663
+ }
664
+ rawAgentRequest(method, params) {
665
+ // SDK 1.2.0 still maps session/load through emptyObjectResponse in ClientContext.request(),
666
+ // but both supported adapters return configOptions/modes there and the driven wrapper must
667
+ // adopt them. This bypasses only the SDK response mapper, not JSON-RPC validation/racing.
668
+ const agent = this.connection.agent;
669
+ return this.race(agent.sendRequest(method, params));
670
+ }
671
+ async reattachSession(method, sessionId, opts) {
672
+ this._activeSessions += 1;
673
+ let registered = false;
674
+ const state = new SessionState(opts.cwd, opts.policy, opts.permissionResolver, opts.label, opts.runId, undefined, opts.retainSessionLog ?? true);
675
+ try {
676
+ await this.ready;
677
+ this.assertLifecycleSupported(method, opts.label);
678
+ this.assertSupportedMcpServers(opts);
679
+ const meta = this.sessionRequestMeta(opts);
680
+ const request = {
681
+ sessionId,
682
+ cwd: opts.cwd,
683
+ mcpServers: opts.mcpServers ?? [],
684
+ ...(meta ? { _meta: meta } : {}),
685
+ };
686
+ // Replayed updates and permission requests can arrive before the response, so the
687
+ // caller-provided id must be routable before the wire call leaves this process.
688
+ this.client.register(sessionId, state);
689
+ registered = true;
690
+ let response;
691
+ if (method === AGENT_METHODS.session_load) {
692
+ const loadRequest = request;
693
+ response = await this.rawAgentRequest(AGENT_METHODS.session_load, loadRequest);
694
+ }
695
+ else {
696
+ const resumeRequest = request;
697
+ response = await this.rawAgentRequest(AGENT_METHODS.session_resume, resumeRequest);
698
+ }
699
+ state.modes = response.modes;
700
+ return new SessionHandle(this, sessionId, state, response.configOptions ?? [], opts);
701
+ }
702
+ catch (error) {
703
+ if (registered)
704
+ this.client.unregister(sessionId);
705
+ this._activeSessions -= 1;
706
+ throw error;
707
+ }
708
+ }
709
+ /** session/list on a dedicated connection, gated on the initialize advertisement. */
710
+ async listSessions(request, label) {
711
+ await this.ready;
712
+ this.assertLifecycleSupported(AGENT_METHODS.session_list, label);
713
+ return this.race(this.connection.agent.request(AGENT_METHODS.session_list, request));
714
+ }
715
+ /** session/delete on a dedicated connection, gated on the initialize advertisement. */
716
+ async deleteSession(request, label) {
717
+ await this.ready;
718
+ this.assertLifecycleSupported(AGENT_METHODS.session_delete, label);
719
+ await this.race(this.connection.agent.request(AGENT_METHODS.session_delete, request));
720
+ }
589
721
  /** session/prompt on this connection, raced against process death. */
590
722
  prompt(request) {
591
723
  return this.race(this.connection.agent.request(AGENT_METHODS.session_prompt, request));
@@ -594,7 +726,12 @@ export class PooledConnection {
594
726
  setSessionConfigOption(request) {
595
727
  return this.race(this.connection.agent.request(AGENT_METHODS.session_set_config_option, request));
596
728
  }
729
+ /** session/set_mode on this connection, raced against process death. */
730
+ setSessionMode(request) {
731
+ return this.race(this.connection.agent.request(AGENT_METHODS.session_set_mode, request));
732
+ }
597
733
  request(method, params, options) {
734
+ assertSafeRawRequest(method);
598
735
  return this.race(this.connection.agent.request(method, params, options));
599
736
  }
600
737
  notify(method, params) {
@@ -715,6 +852,14 @@ export class SessionHandle {
715
852
  get history() {
716
853
  return this.state.history;
717
854
  }
855
+ /** Assistant text accumulated across the retained session log. */
856
+ get text() {
857
+ return this.state.textChunks.join("");
858
+ }
859
+ /** Agent-advertised session mode catalog plus the currently active mode, if supported. */
860
+ get modes() {
861
+ return this.state.modes;
862
+ }
718
863
  /**
719
864
  * Select the model for this session from the agent-advertised config options (§5.4).
720
865
  * Returns `matched:false` (the caller fires onModelFallback) when the catalog has no value
@@ -816,6 +961,21 @@ export class SessionHandle {
816
961
  const response = await this.pooled.setSessionConfigOption(request);
817
962
  this.configOptions = response.configOptions;
818
963
  }
964
+ /** Switch the session's operating mode through ACP's strict confinement channel. */
965
+ async setMode(modeId) {
966
+ const modes = this.state.modes;
967
+ const ids = modeIds(modes);
968
+ if (!modes || !ids.includes(modeId)) {
969
+ throw modeSelectionError(this.pooled.backendId, modeId, ids, this.opts.label);
970
+ }
971
+ try {
972
+ await this.pooled.setSessionMode({ sessionId: this.sessionId, modeId });
973
+ }
974
+ catch (error) {
975
+ throw modeSelectionError(this.pooled.backendId, modeId, ids, this.opts.label, error);
976
+ }
977
+ this.state.modes = { ...modes, currentModeId: modeId };
978
+ }
819
979
  /** Send a prompt turn and drain it; returns the final PromptResponse. */
820
980
  async prompt(content, promptMeta) {
821
981
  this.opts.signal?.throwIfAborted();
@@ -18,6 +18,15 @@ export interface NegotiatedCapabilities {
18
18
  agentInfo: Implementation | undefined;
19
19
  /** Whether session/close is advertised (gates the best-effort release-time close). */
20
20
  supportsClose: boolean;
21
+ /** Whether session/load is advertised. The current SDK keeps this as the legacy top-level
22
+ * `loadSession` flag; tolerate a future sessionCapabilities.load shape for forward compat. */
23
+ supportsLoadSession: boolean;
24
+ /** Whether session/list is advertised. */
25
+ supportsListSessions: boolean;
26
+ /** Whether session/delete is advertised. */
27
+ supportsDeleteSession: boolean;
28
+ /** Whether session/resume is advertised. */
29
+ supportsResumeSession: boolean;
21
30
  /** The parsed backend-declared custom-capability block (the namespaced `_meta` object), or
22
31
  * undefined when the backend declared none or the agent did not advertise it — passthrough. */
23
32
  customMetaSupport: Record<string, unknown> | undefined;
@@ -27,6 +36,8 @@ export interface NegotiatedCapabilities {
27
36
  }
28
37
  /** Parse an initialize response into the connection's derived capability state. */
29
38
  export declare function negotiateCapabilities(response: InitializeResponse, customCapabilities?: Backend["customCapabilities"]): NegotiatedCapabilities;
39
+ /** Human-readable lifecycle advertisement summary for strict wrapper gate errors. */
40
+ export declare function describeLifecycleAdvertisement(agent: AgentCapabilities): string;
30
41
  /** True only when the agent selected EXACTLY PROTOCOL_VERSION. This client implements that one wire
31
42
  * version and adapts its behavior to no other, so any other selected version — older or newer —
32
43
  * 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;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,CAYxB;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;;;;0EAI0E;AAC1E,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,eAAe,EAAE,GAAG,SAAS,EACtC,KAAK,EAAE,iBAAiB,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,GAAG,SAAS,CAYzD"}
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,CAkBxB;AAMD,qFAAqF;AACrF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAiB/E;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;;;;0EAI0E;AAC1E,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,eAAe,EAAE,GAAG,SAAS,EACtC,KAAK,EAAE,iBAAiB,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,GAAG,SAAS,CAYzD"}
@@ -35,17 +35,44 @@ export const GATED_CUSTOM_META_KEYS = [
35
35
  /** Parse an initialize response into the connection's derived capability state. */
36
36
  export function negotiateCapabilities(response, customCapabilities) {
37
37
  const agent = response.agentCapabilities ?? {};
38
+ const sessionCapabilities = agent.sessionCapabilities;
38
39
  return {
39
40
  protocolVersion: response.protocolVersion,
40
41
  agent,
41
42
  agentInfo: response.agentInfo ?? undefined,
42
- supportsClose: Boolean(agent.sessionCapabilities?.close),
43
+ supportsClose: advertised(sessionCapabilities?.close),
44
+ supportsLoadSession: agent.loadSession === true || advertised(sessionCapabilities?.load),
45
+ supportsListSessions: advertised(sessionCapabilities?.list),
46
+ supportsDeleteSession: advertised(sessionCapabilities?.delete),
47
+ supportsResumeSession: advertised(sessionCapabilities?.resume),
43
48
  customMetaSupport: customCapabilities
44
49
  ? readCustomNamespace(agent._meta, customCapabilities.namespace)
45
50
  : undefined,
46
51
  gatedKeys: customCapabilities ? [...customCapabilities.gatedKeys] : undefined,
47
52
  };
48
53
  }
54
+ function advertised(capability) {
55
+ return capability !== undefined && capability !== null && capability !== false;
56
+ }
57
+ /** Human-readable lifecycle advertisement summary for strict wrapper gate errors. */
58
+ export function describeLifecycleAdvertisement(agent) {
59
+ const sessionCapabilities = agent.sessionCapabilities;
60
+ const session = [
61
+ ["close", sessionCapabilities?.close],
62
+ ["list", sessionCapabilities?.list],
63
+ ["delete", sessionCapabilities?.delete],
64
+ ["resume", sessionCapabilities?.resume],
65
+ ["fork", sessionCapabilities?.fork],
66
+ ["additionalDirectories", sessionCapabilities?.additionalDirectories],
67
+ ["load", sessionCapabilities?.load],
68
+ ]
69
+ .filter(([, value]) => advertised(value))
70
+ .map(([name]) => name);
71
+ return [
72
+ `loadSession=${agent.loadSession === true ? "true" : "false"}`,
73
+ `sessionCapabilities=${session.length > 0 ? session.join(", ") : "none"}`,
74
+ ].join("; ");
75
+ }
49
76
  function readCustomNamespace(meta, namespace) {
50
77
  if (!meta || typeof meta !== "object")
51
78
  return undefined;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export { AcpAgentRunner, createAcpRunner, selectBackend } from "./runner.js";
2
- export type { AcpRunnerOptions } from "./runner.js";
2
+ export type { AcpRunnerOptions, DeleteSessionOptions, ListSessionsOptions, ReattachSessionOptions, } 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, SendRequestOptions, } from "@agentclientprotocol/sdk";
6
+ export type { AgentNotificationMethod, AgentNotificationParamsByMethod, AgentRequestMethod, AgentRequestParamsByMethod, AgentRequestResponsesByMethod, DeleteSessionRequest, DeleteSessionResponse, ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, LoadSessionResponse, ResumeSessionRequest, ResumeSessionResponse, SessionMode, SessionModeState, SessionInfo, SendRequestOptions, } 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";
@@ -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,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACV,uBAAuB,EACvB,+BAA+B,EAC/B,kBAAkB,EAClB,0BAA0B,EAC1B,6BAA6B,EAC7B,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7F,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACvF,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAIxF,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5G,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAClG,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import type { AgentNotificationMethod, AgentNotificationParamsByMethod, AgentRequestMethod, AgentRequestParamsByMethod, AgentRequestResponsesByMethod, ContentBlock, SendRequestOptions, StopReason } from "@agentclientprotocol/sdk";
2
- import type { McpServerConfig, PromptImage } from "@automatalabs/shared-types";
1
+ import type { AgentNotificationMethod, AgentNotificationParamsByMethod, AgentRequestMethod, AgentRequestParamsByMethod, AgentRequestResponsesByMethod, ContentBlock, SendRequestOptions, SessionModeState, StopReason } from "@agentclientprotocol/sdk";
2
+ import type { AgentHistoryEntry, McpServerConfig, PromptImage } from "@automatalabs/shared-types";
3
3
  import type { RunOptions } from "@automatalabs/shared-types";
4
4
  import type { Backend, BackendId } from "./backend.js";
5
5
  import type { NegotiatedCapabilities } from "./capabilities.js";
@@ -14,6 +14,8 @@ import type { PermissionResolver } from "./permissions.js";
14
14
  export interface InteractiveSessionOptions {
15
15
  /** Model spec (`provider/modelId`, bare model id, or registered custom backend route). */
16
16
  model?: string;
17
+ /** Agent-advertised session mode id. Strict: openSession fails rather than running unconfined. */
18
+ mode?: string;
17
19
  /** Coarse tier consulted only when `model` is unset. */
18
20
  tier?: string;
19
21
  /** Absolute working directory for ACP session/new. Required for held-open sessions. */
@@ -40,6 +42,8 @@ export interface InteractiveSessionOptions {
40
42
  developerInstructions?: string;
41
43
  /** Client-provided MCP servers to attach at session/new. */
42
44
  mcpServers?: McpServerConfig[];
45
+ /** Keep accumulated text/history after each prompt turn; default false for held-open sessions. */
46
+ retainSessionLog?: boolean;
43
47
  /** Host-owned cancellation. Aborting releases this interactive session. */
44
48
  signal?: AbortSignal;
45
49
  }
@@ -89,6 +93,12 @@ export declare class InteractiveSession {
89
93
  constructor(deps: InteractiveSessionDeps);
90
94
  /** Negotiated initialize capabilities for this session's dedicated connection. */
91
95
  get capabilities(): NegotiatedCapabilities | undefined;
96
+ /** Agent-advertised session mode catalog plus the currently active mode, if supported. */
97
+ get modes(): SessionModeState | null | undefined;
98
+ /** Assistant text accumulated in this session's retained log. */
99
+ get text(): string;
100
+ /** Message/tool history accumulated in this session's retained log. */
101
+ get history(): readonly AgentHistoryEntry[];
92
102
  /** Send one prompt turn. A concurrent prompt on the same InteractiveSession is rejected with a
93
103
  * clear host-side error; queueing is deliberately left to the host so turn boundaries remain
94
104
  * explicit. Per-turn images are appended only to this prompt, and SessionHandle.prompt()
@@ -103,6 +113,8 @@ export declare class InteractiveSession {
103
113
  * recording; calling session/prompt here bypasses those paths. */
104
114
  request<Method extends AgentRequestMethod>(method: Method, params: AgentRequestParamsByMethod[Method], options?: SendRequestOptions): Promise<AgentRequestResponsesByMethod[Method]>;
105
115
  request<Response = unknown, Params = unknown>(method: string, params?: Params, options?: SendRequestOptions): Promise<Response>;
116
+ /** Switch this session's ACP operating mode. Fails strictly when the agent did not advertise it. */
117
+ setMode(modeId: string): Promise<void>;
106
118
  /** RAW protocol notification escape hatch for held-open sessions. Params carry `sessionId`
107
119
  * explicitly; use `session.sessionId` so the wire call targets this session. */
108
120
  notify<Method extends AgentNotificationMethod>(method: Method, params: AgentNotificationParamsByMethod[Method]): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,18 @@ export class InteractiveSession {
49
49
  get capabilities() {
50
50
  return this.connection.capabilities;
51
51
  }
52
+ /** Agent-advertised session mode catalog plus the currently active mode, if supported. */
53
+ get modes() {
54
+ return this.session.modes;
55
+ }
56
+ /** Assistant text accumulated in this session's retained log. */
57
+ get text() {
58
+ return this.session.text;
59
+ }
60
+ /** Message/tool history accumulated in this session's retained log. */
61
+ get history() {
62
+ return this.session.history;
63
+ }
52
64
  /** Send one prompt turn. A concurrent prompt on the same InteractiveSession is rejected with a
53
65
  * clear host-side error; queueing is deliberately left to the host so turn boundaries remain
54
66
  * explicit. Per-turn images are appended only to this prompt, and SessionHandle.prompt()
@@ -80,6 +92,13 @@ export class InteractiveSession {
80
92
  throw new Error("InteractiveSession has been released");
81
93
  return this.connection.request(method, params, options);
82
94
  }
95
+ /** Switch this session's ACP operating mode. Fails strictly when the agent did not advertise it. */
96
+ async setMode(modeId) {
97
+ if (this.releasePromise)
98
+ throw new Error("InteractiveSession has been released");
99
+ this.signal?.throwIfAborted();
100
+ await this.session.setMode(modeId);
101
+ }
83
102
  async notify(method, params) {
84
103
  if (this.releasePromise)
85
104
  throw new Error("InteractiveSession has been released");
@@ -13,6 +13,10 @@ export interface ToolPolicy {
13
13
  allow?: string[];
14
14
  /** Deny-list (agentType `disallowedTools`), applied after the allow-list. */
15
15
  deny?: string[];
16
+ /** No-match fallback for the headless auto-responder. Default "allow" preserves historical
17
+ * behavior. Explicit ACP session modes set this to "deny" unless a permission resolver is
18
+ * present, otherwise read-only/plan confinement can be bypassed by auto-approved escalations. */
19
+ defaultOutcome?: "allow" | "deny";
16
20
  }
17
21
  /** Decide the auto-response for one permission request given the tool policy. */
18
22
  export declare function decidePermission(request: RequestPermissionRequest, policy: ToolPolicy): RequestPermissionResponse;
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAGV,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;wDAMwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,MAAM,EAAE,wBAAwB,EAChC,GAAG,EAAE,eAAe,KACjB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE,UAAU,GACjB,yBAAyB,CAqC3B"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAGV,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;wDAMwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,MAAM,EAAE,wBAAwB,EAChC,GAAG,EAAE,eAAe,KACjB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;sGAEkG;IAClG,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACnC;AAKD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE,UAAU,GACjB,yBAAyB,CAsC3B"}
@@ -9,6 +9,7 @@ export function decidePermission(request, policy) {
9
9
  const allPool = [...toolNames, ...decoration];
10
10
  const denyList = policy.deny ?? [];
11
11
  const allowList = policy.allow ?? [];
12
+ const defaultOutcome = policy.defaultOutcome ?? "allow";
12
13
  const hasDeny = denyList.length > 0;
13
14
  const hasAllowList = allowList.length > 0;
14
15
  const denyExact = hasDeny && exactMatchesAny(exactPool, denyList);
@@ -20,12 +21,12 @@ export function decidePermission(request, policy) {
20
21
  // (Suppresses loose substring matches: a deny `read` no longer catches an exactly
21
22
  // allow-listed `thread-reader`.)
22
23
  denied = denyExact;
23
- allowedByList = !hasAllowList || allowExact;
24
+ allowedByList = hasAllowList ? allowExact : defaultOutcome === "allow";
24
25
  }
25
26
  else {
26
27
  // (b) No exact match in either list -> best-effort bidirectional substring fallback.
27
28
  denied = hasDeny && substringMatchesAny(allPool, denyList);
28
- allowedByList = !hasAllowList || substringMatchesAny(allPool, allowList);
29
+ allowedByList = hasAllowList ? substringMatchesAny(allPool, allowList) : defaultOutcome === "allow";
29
30
  }
30
31
  const wantAllow = !denied && allowedByList;
31
32
  const option = pickOption(request.options, wantAllow);
@@ -3,7 +3,9 @@ type ValueOf<T> = T[keyof T];
3
3
  type ClientMethod = ValueOf<typeof CLIENT_METHODS>;
4
4
  type AgentMethod = ValueOf<typeof AGENT_METHODS>;
5
5
  export type ClientMethodCoverage = "served" | "pending";
6
- export type AgentMethodCoverage = "driven" | "passthrough";
6
+ /** `guarded` means the raw passthrough would create/reopen session state outside the router, so
7
+ * the client rejects it until a driven wrapper can route updates, permissions, and terminals. */
8
+ export type AgentMethodCoverage = "driven" | "passthrough" | "guarded";
7
9
  /** Enforceable definition of "full ACP spec support": every SDK method constant is classified
8
10
  * here, and the tripwire test fails when an SDK bump silently widens or shrinks the protocol. */
9
11
  export declare const CLIENT_METHOD_COVERAGE: Record<ClientMethod, ClientMethodCoverage>;
@@ -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,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,CAAC;AAE3D;kGACkG;AAClG,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAe7E,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,mBAAmB,CA6B1E,CAAC"}
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;kGACkG;AAClG,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAe7E,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,mBAAmB,CA6B1E,CAAC"}
@@ -24,16 +24,16 @@ export const AGENT_METHOD_COVERAGE = {
24
24
  [AGENT_METHODS.providers_set]: "passthrough",
25
25
  [AGENT_METHODS.providers_disable]: "passthrough",
26
26
  [AGENT_METHODS.session_new]: "driven",
27
- [AGENT_METHODS.session_load]: "passthrough",
28
- [AGENT_METHODS.session_set_mode]: "passthrough",
27
+ [AGENT_METHODS.session_load]: "driven",
28
+ [AGENT_METHODS.session_set_mode]: "driven",
29
29
  [AGENT_METHODS.session_set_config_option]: "driven",
30
30
  [AGENT_METHODS.session_prompt]: "driven",
31
31
  [AGENT_METHODS.session_cancel]: "driven",
32
32
  [AGENT_METHODS.mcp_message]: "passthrough",
33
- [AGENT_METHODS.session_list]: "passthrough",
34
- [AGENT_METHODS.session_delete]: "passthrough",
35
- [AGENT_METHODS.session_fork]: "passthrough",
36
- [AGENT_METHODS.session_resume]: "passthrough",
33
+ [AGENT_METHODS.session_list]: "driven",
34
+ [AGENT_METHODS.session_delete]: "driven",
35
+ [AGENT_METHODS.session_fork]: "guarded",
36
+ [AGENT_METHODS.session_resume]: "driven",
37
37
  [AGENT_METHODS.session_close]: "driven",
38
38
  [AGENT_METHODS.logout]: "passthrough",
39
39
  [AGENT_METHODS.nes_start]: "passthrough",
package/dist/runner.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type AgentResult, type AgentRunner, type RunOptions } from "@automatalabs/shared-types";
2
+ import type { ListSessionsResponse } from "@agentclientprotocol/sdk";
2
3
  import type { TSchema } from "typebox";
3
4
  import { type AcpPoolOptions } from "./pool.js";
4
5
  import { type AcpEventListener, type AcpEventName } from "./events.js";
@@ -6,6 +7,39 @@ import type { Backend } from "./backend.js";
6
7
  import { InteractiveSession, type InteractiveSessionOptions } from "./interactive.js";
7
8
  import { type BackendRegistry, type CustomBackendConfig } from "./registry.js";
8
9
  import type { PermissionResolver } from "./permissions.js";
10
+ interface LifecycleRoutingOptions {
11
+ /** Model spec used only to select the backend process. */
12
+ model?: string;
13
+ /** Coarse tier consulted only when `model` is unset. */
14
+ tier?: string;
15
+ /** Event/telemetry label used in strict capability errors. */
16
+ label?: string;
17
+ /** Host-owned cancellation while the lifecycle request is in flight. */
18
+ signal?: AbortSignal;
19
+ }
20
+ /** Options for AcpAgentRunner.listSessions(). */
21
+ export interface ListSessionsOptions extends LifecycleRoutingOptions {
22
+ /** Optional absolute working-directory filter. */
23
+ cwd?: string;
24
+ /** Opaque pagination cursor from the previous response. */
25
+ cursor?: string;
26
+ /** Generic ACP `_meta` passthrough for session/list. */
27
+ meta?: Record<string, unknown>;
28
+ }
29
+ /** Options for AcpAgentRunner.deleteSession(). */
30
+ export interface DeleteSessionOptions extends LifecycleRoutingOptions {
31
+ /** Session id returned by session/list or previously persisted by the backend. */
32
+ sessionId: string;
33
+ /** Generic ACP `_meta` passthrough for session/delete. */
34
+ meta?: Record<string, unknown>;
35
+ }
36
+ /** Options for AcpAgentRunner.loadSession() and resumeSession(). */
37
+ export interface ReattachSessionOptions extends InteractiveSessionOptions {
38
+ /** Existing backend session id to route before the lifecycle request is sent. */
39
+ sessionId: string;
40
+ /** Alias for onPermissionRequest for hosts that name the resolver by role. */
41
+ permissionResolver?: PermissionResolver;
42
+ }
9
43
  /** Constructor options for the runner: pool sizing, client-side handlers, and the custom-backend
10
44
  * registry. `backends` merges over (and wins against) env-declared AGENTPRISM_BACKENDS entries. */
11
45
  export interface AcpRunnerOptions extends AcpPoolOptions {
@@ -60,10 +94,20 @@ export declare class AcpAgentRunner implements AgentRunner {
60
94
  * is one).
61
95
  */
62
96
  openSession(opts: InteractiveSessionOptions): Promise<InteractiveSession>;
97
+ /** List persisted ACP sessions from the selected backend. */
98
+ listSessions(opts?: ListSessionsOptions): Promise<ListSessionsResponse>;
99
+ /** Delete a persisted ACP session from the selected backend. */
100
+ deleteSession(opts: DeleteSessionOptions): Promise<void>;
101
+ /** Load an existing ACP session and return a live, routed InteractiveSession. */
102
+ loadSession(opts: ReattachSessionOptions): Promise<InteractiveSession>;
103
+ /** Resume an existing ACP session without replay and return a live, routed InteractiveSession. */
104
+ resumeSession(opts: ReattachSessionOptions): Promise<InteractiveSession>;
63
105
  run<S extends TSchema | undefined = undefined>(prompt: string, options?: RunOptions<S>): Promise<AgentResult<S>>;
64
106
  /** Tear down the whole pool (close every long-lived process). Call when the run ends / the
65
107
  * runner is disposed. Beyond the AgentRunner seam (additive) — never enters the resume hash. */
66
108
  dispose(): Promise<void>;
109
+ private createInteractiveSession;
110
+ private createDedicatedConnection;
67
111
  /** Build the backend choice, model-selection spec, tool policy, and session/new options in one
68
112
  * place for run() and openSession() so new AcpSessionOptions fields cannot drift by path. */
69
113
  private prepareSession;
@@ -86,4 +130,5 @@ export declare function selectBackend(opts: {
86
130
  model?: string;
87
131
  tier?: string;
88
132
  }, registry?: BackendRegistry): Backend;
133
+ export {};
89
134
  //# sourceMappingURL=runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
package/dist/runner.js CHANGED
@@ -91,67 +91,66 @@ export class AcpAgentRunner {
91
91
  * is one).
92
92
  */
93
93
  async openSession(opts) {
94
+ return this.createInteractiveSession(opts, "openSession", (connection, prepared) => connection.openSession(prepared.sessionOptions));
95
+ }
96
+ /** List persisted ACP sessions from the selected backend. */
97
+ async listSessions(opts = {}) {
94
98
  if (this.disposed)
95
99
  throw new Error("ACP agent runner is disposed");
96
- validateInteractiveCwd(opts.cwd, opts.label);
100
+ validateOptionalLifecycleCwd(opts.cwd, opts.label, "listSessions");
97
101
  opts.signal?.throwIfAborted();
98
- const prepared = this.prepareSession(opts, {
99
- cwd: opts.cwd,
100
- schema: undefined,
101
- registry: this.backends,
102
- permissionResolver: opts.onPermissionRequest,
103
- retainSessionLog: false,
104
- });
105
- this.installExitHook();
106
- let interactive;
107
- const connection = PooledConnection.create(prepared.backend, {
108
- onDead: () => {
109
- // Dedicated connections are not stored in pool arrays, so there is nothing to evict.
110
- // Once the public wrapper exists, process death releases it through the normal path:
111
- // subscriptions are removed, session_close is emitted, and future prompt() calls fail
112
- // with the clean released-session error. Before then, openSession's catch tears down.
113
- void interactive?.release();
114
- },
115
- onEvent: this.emitEvent,
116
- permissionResolver: this.permissionResolver,
117
- clientHandlers: this.clientHandlers,
118
- });
119
- let session;
102
+ const backend = selectBackend(opts, this.backends);
103
+ const connection = this.createDedicatedConnection(backend, () => undefined);
120
104
  try {
121
- session = await connection.openSession(prepared.sessionOptions);
105
+ const request = {
106
+ ...(opts.cwd ? { cwd: opts.cwd } : {}),
107
+ ...(opts.cursor ? { cursor: opts.cursor } : {}),
108
+ ...(opts.meta ? { _meta: opts.meta } : {}),
109
+ };
110
+ const response = await connection.listSessions(request, opts.label);
122
111
  opts.signal?.throwIfAborted();
123
- await applyModelSelection(session, prepared.modelSpec, opts);
112
+ if (this.disposed)
113
+ throw new Error("ACP agent runner is disposed");
114
+ return response;
115
+ }
116
+ finally {
117
+ await disposeBestEffort(connection);
118
+ }
119
+ }
120
+ /** Delete a persisted ACP session from the selected backend. */
121
+ async deleteSession(opts) {
122
+ if (this.disposed)
123
+ throw new Error("ACP agent runner is disposed");
124
+ if (typeof opts.sessionId !== "string" || opts.sessionId.trim() === "") {
125
+ throw new WorkflowError("deleteSession requires sessionId to be a non-empty string", WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: opts.label });
126
+ }
127
+ opts.signal?.throwIfAborted();
128
+ const backend = selectBackend(opts, this.backends);
129
+ const connection = this.createDedicatedConnection(backend, () => undefined);
130
+ try {
131
+ const request = {
132
+ sessionId: opts.sessionId,
133
+ ...(opts.meta ? { _meta: opts.meta } : {}),
134
+ };
135
+ await connection.deleteSession(request, opts.label);
124
136
  opts.signal?.throwIfAborted();
125
137
  if (this.disposed)
126
138
  throw new Error("ACP agent runner is disposed");
127
- interactive = new InteractiveSession({
128
- session,
129
- connection,
130
- backend: prepared.backend,
131
- subscribe: (name, listener) => this.events.on(name, listener),
132
- onRelease: (self) => this.interactiveSessions.delete(self),
133
- signal: opts.signal,
134
- label: opts.label,
135
- });
136
- this.interactiveSessions.set(interactive, connection);
137
- return interactive;
138
139
  }
139
- catch (error) {
140
- try {
141
- await session?.release();
142
- }
143
- catch {
144
- // best-effort: openSession failed, so teardown must never mask the real error.
145
- }
146
- try {
147
- await connection.dispose();
148
- }
149
- catch {
150
- // best-effort: same as pool teardown.
151
- }
152
- throw error;
140
+ finally {
141
+ await disposeBestEffort(connection);
153
142
  }
154
143
  }
144
+ /** Load an existing ACP session and return a live, routed InteractiveSession. */
145
+ async loadSession(opts) {
146
+ validateLifecycleSessionId(opts.sessionId, opts.label, "loadSession");
147
+ return this.createInteractiveSession(opts, "loadSession", (connection, prepared) => connection.loadSession(opts.sessionId, prepared.sessionOptions));
148
+ }
149
+ /** Resume an existing ACP session without replay and return a live, routed InteractiveSession. */
150
+ async resumeSession(opts) {
151
+ validateLifecycleSessionId(opts.sessionId, opts.label, "resumeSession");
152
+ return this.createInteractiveSession(opts, "resumeSession", (connection, prepared) => connection.resumeSession(opts.sessionId, prepared.sessionOptions));
153
+ }
155
154
  async run(prompt, options = {}) {
156
155
  const opts = options;
157
156
  const schema = opts.schema;
@@ -183,6 +182,9 @@ export class AcpAgentRunner {
183
182
  // model id: "browser" selects nothing; "browser/foo" selects "foo". Built-ins get the
184
183
  // full spec unchanged (their catalogs match provider-prefixed and bare ids).
185
184
  await applyModelSelection(session, prepared.modelSpec, opts);
185
+ opts.signal?.throwIfAborted();
186
+ if (opts.mode)
187
+ await session.setMode(opts.mode);
186
188
  const text = buildRunPrompt(prompt, opts, schema, prepared.backend);
187
189
  const initialPrompt = opts.images && opts.images.length > 0 ? promptWithImages(text, opts.images) : text;
188
190
  // Generic turn-scoped _meta passthrough merged UNDER the backend-computed keys (e.g. the
@@ -260,11 +262,79 @@ export class AcpAgentRunner {
260
262
  await this.pool.dispose();
261
263
  this.events.removeAllListeners();
262
264
  }
265
+ async createInteractiveSession(opts, methodName, open) {
266
+ if (this.disposed)
267
+ throw new Error("ACP agent runner is disposed");
268
+ validateInteractiveCwd(opts.cwd, opts.label, methodName);
269
+ opts.signal?.throwIfAborted();
270
+ const prepared = this.prepareSession(opts, {
271
+ cwd: opts.cwd,
272
+ schema: undefined,
273
+ registry: this.backends,
274
+ permissionResolver: opts.permissionResolver ?? opts.onPermissionRequest,
275
+ retainSessionLog: opts.retainSessionLog ?? false,
276
+ });
277
+ this.installExitHook();
278
+ let interactive;
279
+ const connection = this.createDedicatedConnection(prepared.backend, () => {
280
+ // Dedicated connections are not stored in pool arrays, so there is nothing to evict.
281
+ // Once the public wrapper exists, process death releases it through the normal path:
282
+ // subscriptions are removed, session_close is emitted, and future prompt() calls fail
283
+ // with the clean released-session error. Before then, this method's catch tears down.
284
+ void interactive?.release();
285
+ });
286
+ let session;
287
+ try {
288
+ session = await open(connection, prepared);
289
+ opts.signal?.throwIfAborted();
290
+ await applyModelSelection(session, prepared.modelSpec, opts);
291
+ opts.signal?.throwIfAborted();
292
+ if (opts.mode)
293
+ await session.setMode(opts.mode);
294
+ opts.signal?.throwIfAborted();
295
+ if (this.disposed)
296
+ throw new Error("ACP agent runner is disposed");
297
+ interactive = new InteractiveSession({
298
+ session,
299
+ connection,
300
+ backend: prepared.backend,
301
+ subscribe: (name, listener) => this.events.on(name, listener),
302
+ onRelease: (self) => this.interactiveSessions.delete(self),
303
+ signal: opts.signal,
304
+ label: opts.label,
305
+ });
306
+ this.interactiveSessions.set(interactive, connection);
307
+ return interactive;
308
+ }
309
+ catch (error) {
310
+ try {
311
+ await session?.release();
312
+ }
313
+ catch {
314
+ // best-effort: lifecycle setup failed, so teardown must never mask the real error.
315
+ }
316
+ await disposeBestEffort(connection);
317
+ throw error;
318
+ }
319
+ }
320
+ createDedicatedConnection(backend, onDead) {
321
+ return PooledConnection.create(backend, {
322
+ onDead,
323
+ onEvent: this.emitEvent,
324
+ permissionResolver: this.permissionResolver,
325
+ clientHandlers: this.clientHandlers,
326
+ });
327
+ }
263
328
  /** Build the backend choice, model-selection spec, tool policy, and session/new options in one
264
329
  * place for run() and openSession() so new AcpSessionOptions fields cannot drift by path. */
265
330
  prepareSession(opts, config) {
266
331
  const backend = selectBackend(opts, config.registry);
267
- const policy = { allow: opts.toolNames, deny: opts.disallowedToolNames };
332
+ const hasPermissionResolver = Boolean(config.permissionResolver ?? this.permissionResolver);
333
+ const policy = {
334
+ allow: opts.toolNames,
335
+ deny: opts.disallowedToolNames,
336
+ defaultOutcome: opts.mode && !hasPermissionResolver ? "deny" : undefined,
337
+ };
268
338
  return {
269
339
  backend,
270
340
  modelSpec: innerModelSpec(opts.model ?? opts.tier, backend),
@@ -401,9 +471,27 @@ function innerModelSpec(spec, backend) {
401
471
  }
402
472
  /** Interactive sessions are public and long-lived, so fail before spawning a dedicated process
403
473
  * when the required worktree root is absent or not absolute. */
404
- function validateInteractiveCwd(cwd, label) {
474
+ function validateInteractiveCwd(cwd, label, methodName) {
405
475
  if (typeof cwd !== "string" || cwd.trim() === "" || !isAbsolute(cwd)) {
406
- throw new WorkflowError("openSession requires cwd to be a non-empty absolute path", WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
476
+ throw new WorkflowError(`${methodName} requires cwd to be a non-empty absolute path`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
477
+ }
478
+ }
479
+ function validateOptionalLifecycleCwd(cwd, label, methodName) {
480
+ if (cwd === undefined || cwd === null)
481
+ return;
482
+ validateInteractiveCwd(cwd, label, methodName);
483
+ }
484
+ function validateLifecycleSessionId(sessionId, label, methodName) {
485
+ if (typeof sessionId !== "string" || sessionId.trim() === "") {
486
+ throw new WorkflowError(`${methodName} requires sessionId to be a non-empty string`, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, { recoverable: false, agentLabel: label });
487
+ }
488
+ }
489
+ async function disposeBestEffort(connection) {
490
+ try {
491
+ await connection.dispose();
492
+ }
493
+ catch {
494
+ // Dedicated lifecycle processes are already no longer useful; never mask the request result.
407
495
  }
408
496
  }
409
497
  function backendIdForSpec(spec) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automatalabs/acp-agents",
3
- "version": "0.12.0",
3
+ "version": "0.14.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.8.0"
34
+ "@automatalabs/shared-types": "0.9.0"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsc -b",