@automatalabs/acp-agents 0.9.1 → 0.11.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/dist/acp-client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ContentBlock, type PromptRequest, type PromptResponse, type RequestPermissionResponse, type SessionConfigOption, type SessionNotification, type SetSessionConfigOptionRequest, type SetSessionConfigOptionResponse } 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";
|
|
@@ -92,8 +92,9 @@ export interface PooledConnectionDeps {
|
|
|
92
92
|
*/
|
|
93
93
|
export declare class PooledConnection {
|
|
94
94
|
readonly backendId: BackendId;
|
|
95
|
-
/** The held ACP connection
|
|
96
|
-
|
|
95
|
+
/** The held ACP connection (fluent client() app); session/* calls go through its
|
|
96
|
+
* `agent` ClientContext via the typed wrappers below. */
|
|
97
|
+
private readonly connection;
|
|
97
98
|
private readonly backend;
|
|
98
99
|
private readonly child;
|
|
99
100
|
private readonly client;
|
|
@@ -138,6 +139,10 @@ export declare class PooledConnection {
|
|
|
138
139
|
* synchronously (before the first await) so the pool's load accounting is race-free.
|
|
139
140
|
*/
|
|
140
141
|
openSession(opts: AcpSessionOptions): Promise<SessionHandle>;
|
|
142
|
+
/** session/prompt on this connection, raced against process death. */
|
|
143
|
+
prompt(request: PromptRequest): Promise<PromptResponse>;
|
|
144
|
+
/** session/set_config_option on this connection, raced against process death. */
|
|
145
|
+
setSessionConfigOption(request: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse>;
|
|
141
146
|
/** Best-effort ACP cancel for one session (wired to opts.signal). The PROCESS stays pooled. */
|
|
142
147
|
cancelSession(sessionId: string): Promise<void>;
|
|
143
148
|
/**
|
|
@@ -201,7 +206,9 @@ export declare class SessionHandle implements StructuredSource {
|
|
|
201
206
|
* carried by the model select itself, so it is treated as satisfied (no fallback).
|
|
202
207
|
*/
|
|
203
208
|
private applyModelModifiers;
|
|
204
|
-
/** Set one session config option via the wire method and adopt the echoed catalog.
|
|
209
|
+
/** Set one session config option via the wire method and adopt the echoed catalog.
|
|
210
|
+
* A boolean value drives a `type: "boolean"` option (the request must carry the type
|
|
211
|
+
* discriminator on the wire); a string value drives a select option. */
|
|
205
212
|
private applyConfigOption;
|
|
206
213
|
/** Send a prompt turn and drain it; returns the final PromptResponse. */
|
|
207
214
|
prompt(content: string | ContentBlock[], promptMeta?: Record<string, unknown>): Promise<PromptResponse>;
|
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
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
// per-session accumulator (SessionState) by `sessionId`.
|
|
17
17
|
//
|
|
18
18
|
// Draining: ACP delivers a prompt turn as session/update notifications followed by the
|
|
19
|
-
// session/prompt response, in wire order on one stream. Our
|
|
20
|
-
// (they only push into the routed session's arrays), so by the time
|
|
21
|
-
// every update for THAT session's turn has already been folded into its accumulator —
|
|
22
|
-
// other sessions' updates interleave on the same wire.
|
|
19
|
+
// session/prompt response, in wire order on one stream. Our client handlers are synchronous
|
|
20
|
+
// (they only push into the routed session's arrays), so by the time the session/prompt request
|
|
21
|
+
// resolves, every update for THAT session's turn has already been folded into its accumulator —
|
|
22
|
+
// even while other sessions' updates interleave on the same wire.
|
|
23
23
|
import { spawn } from "node:child_process";
|
|
24
24
|
import { Readable, Writable } from "node:stream";
|
|
25
|
-
import {
|
|
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
27
|
import { adaptPromptContent, gateCustomMeta, isSupportedProtocolVersion, negotiateCapabilities, unsupportedMcpServer, } from "./capabilities.js";
|
|
28
28
|
import { emitSessionUpdate } from "./events.js";
|
|
@@ -132,9 +132,10 @@ class SessionState {
|
|
|
132
132
|
settle(cancelledPermissionResponse());
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
/** The single
|
|
136
|
-
* permission request to the per-session
|
|
137
|
-
* many concurrent sessions without their
|
|
135
|
+
/** The single client-side handler set for one pooled connection (registered on the SDK's fluent
|
|
136
|
+
* client() app). It ROUTES every notification and permission request to the per-session
|
|
137
|
+
* SessionState by `sessionId`, so one process can serve many concurrent sessions without their
|
|
138
|
+
* streams crossing. */
|
|
138
139
|
class MultiplexClient {
|
|
139
140
|
backendId;
|
|
140
141
|
onEvent;
|
|
@@ -354,8 +355,9 @@ function toolNameFromMeta(meta) {
|
|
|
354
355
|
*/
|
|
355
356
|
export class PooledConnection {
|
|
356
357
|
backendId;
|
|
357
|
-
/** The held ACP connection
|
|
358
|
-
|
|
358
|
+
/** The held ACP connection (fluent client() app); session/* calls go through its
|
|
359
|
+
* `agent` ClientContext via the typed wrappers below. */
|
|
360
|
+
connection;
|
|
359
361
|
backend;
|
|
360
362
|
child;
|
|
361
363
|
client;
|
|
@@ -402,14 +404,39 @@ export class PooledConnection {
|
|
|
402
404
|
this.resolveDead = resolve;
|
|
403
405
|
});
|
|
404
406
|
const stream = ndJsonStream(Writable.toWeb(child.stdin), Readable.toWeb(child.stdout));
|
|
405
|
-
|
|
407
|
+
// The fluent client() app: every inbound agent->client request/notification is registered
|
|
408
|
+
// here and dispatched to the MultiplexClient router. All request handlers are registered
|
|
409
|
+
// unconditionally — MultiplexClient.dispatch() answers a method the consumer provided no
|
|
410
|
+
// handler for with the same -32601 "not advertised" error as before, so behavior is
|
|
411
|
+
// identical to the previous Client-interface wiring.
|
|
412
|
+
//
|
|
413
|
+
// ORDER MATTERS: the two accumulation-feeding notifications MUST be registered FIRST.
|
|
414
|
+
// The SDK Connection runs only the first matching handler synchronously inside the
|
|
415
|
+
// read-loop turn; later handlers each cost a microtask hop, which lets an in-flight
|
|
416
|
+
// session/prompt RESPONSE continuation overtake a session/update notification that
|
|
417
|
+
// arrived before it on the wire. Registering session/update (and the Claude raw-message
|
|
418
|
+
// channel) first preserves the drain contract this file documents — every update for a
|
|
419
|
+
// turn is folded into its accumulator before that turn's prompt() resolves — exactly as
|
|
420
|
+
// the SDK's own (deprecated) ClientSideConnection wrapper registered them.
|
|
421
|
+
this.connection = client({ name: CLIENT_INFO.name })
|
|
422
|
+
.onNotification(CLIENT_METHODS.session_update, ({ params }) => this.client.sessionUpdate(params))
|
|
423
|
+
.onNotification(CLAUDE_RAW_MESSAGE_METHOD, (params) => (params ?? {}), ({ params }) => this.client.extNotification(CLAUDE_RAW_MESSAGE_METHOD, params))
|
|
424
|
+
.onRequest(CLIENT_METHODS.session_request_permission, ({ params }) => this.client.requestPermission(params))
|
|
425
|
+
.onRequest(CLIENT_METHODS.fs_read_text_file, ({ params }) => this.client.readTextFile(params))
|
|
426
|
+
.onRequest(CLIENT_METHODS.fs_write_text_file, ({ params }) => this.client.writeTextFile(params))
|
|
427
|
+
.onRequest(CLIENT_METHODS.terminal_create, ({ params }) => this.client.createTerminal(params))
|
|
428
|
+
.onRequest(CLIENT_METHODS.terminal_output, ({ params }) => this.client.terminalOutput(params))
|
|
429
|
+
.onRequest(CLIENT_METHODS.terminal_release, ({ params }) => this.client.releaseTerminal(params))
|
|
430
|
+
.onRequest(CLIENT_METHODS.terminal_wait_for_exit, ({ params }) => this.client.waitForTerminalExit(params))
|
|
431
|
+
.onRequest(CLIENT_METHODS.terminal_kill, ({ params }) => this.client.killTerminal(params))
|
|
432
|
+
.connect(stream);
|
|
406
433
|
// Death detection. The connection's `signal` aborts the INSTANT the underlying stream closes
|
|
407
434
|
// (process crash or our own dispose) — in the SAME close() that rejects pending requests — so
|
|
408
435
|
// it is the earliest, DETERMINISTIC death signal: a connection is marked dead and evicted
|
|
409
436
|
// before its in-flight prompt's rejection even propagates, so a concurrent acquire can never
|
|
410
437
|
// hand out a connection whose process has already died. The child 'exit'/'error' events are a
|
|
411
438
|
// belt-and-suspenders backstop (and carry the exit code for a clearer message).
|
|
412
|
-
this.
|
|
439
|
+
this.connection.signal.addEventListener("abort", () => this.die(new Error(`ACP agent (${this.backendId}) connection closed${this.stderrSuffix()}`)), { once: true });
|
|
413
440
|
child.once("error", (err) => this.die(err));
|
|
414
441
|
child.once("exit", (code, sig) => {
|
|
415
442
|
this.die(new Error(`ACP agent (${this.backendId}) process exited (code=${code}, signal=${sig})${this.stderrSuffix()}`));
|
|
@@ -486,7 +513,7 @@ export class PooledConnection {
|
|
|
486
513
|
});
|
|
487
514
|
try {
|
|
488
515
|
const response = await Promise.race([
|
|
489
|
-
this.race(this.
|
|
516
|
+
this.race(this.connection.agent.request(AGENT_METHODS.initialize, {
|
|
490
517
|
protocolVersion: PROTOCOL_VERSION,
|
|
491
518
|
// Truthful advertisement: computed from the consumer-provided handlers registered on
|
|
492
519
|
// this runner. Omitted flags are unsupported; false flags are never sent deliberately.
|
|
@@ -550,7 +577,7 @@ export class PooledConnection {
|
|
|
550
577
|
mcpServers: opts.mcpServers ?? [],
|
|
551
578
|
...(meta ? { _meta: meta } : {}),
|
|
552
579
|
};
|
|
553
|
-
const response = await this.race(this.
|
|
580
|
+
const response = await this.race(this.connection.agent.request(AGENT_METHODS.session_new, request));
|
|
554
581
|
this.client.register(response.sessionId, state);
|
|
555
582
|
return new SessionHandle(this, response.sessionId, state, response.configOptions ?? [], opts);
|
|
556
583
|
}
|
|
@@ -559,13 +586,21 @@ export class PooledConnection {
|
|
|
559
586
|
throw error;
|
|
560
587
|
}
|
|
561
588
|
}
|
|
589
|
+
/** session/prompt on this connection, raced against process death. */
|
|
590
|
+
prompt(request) {
|
|
591
|
+
return this.race(this.connection.agent.request(AGENT_METHODS.session_prompt, request));
|
|
592
|
+
}
|
|
593
|
+
/** session/set_config_option on this connection, raced against process death. */
|
|
594
|
+
setSessionConfigOption(request) {
|
|
595
|
+
return this.race(this.connection.agent.request(AGENT_METHODS.session_set_config_option, request));
|
|
596
|
+
}
|
|
562
597
|
/** Best-effort ACP cancel for one session (wired to opts.signal). The PROCESS stays pooled. */
|
|
563
598
|
async cancelSession(sessionId) {
|
|
564
599
|
this.client.settlePendingPermissions(sessionId);
|
|
565
600
|
if (!this._alive)
|
|
566
601
|
return;
|
|
567
602
|
try {
|
|
568
|
-
await this.
|
|
603
|
+
await this.connection.agent.notify(AGENT_METHODS.session_cancel, { sessionId });
|
|
569
604
|
}
|
|
570
605
|
catch {
|
|
571
606
|
// best-effort: the session settles as "cancelled" regardless.
|
|
@@ -583,7 +618,7 @@ export class PooledConnection {
|
|
|
583
618
|
if (!this.negotiated?.supportsClose || !this._alive)
|
|
584
619
|
return;
|
|
585
620
|
try {
|
|
586
|
-
await this.race(withTimeout(this.
|
|
621
|
+
await this.race(withTimeout(this.connection.agent.request(AGENT_METHODS.session_close, { sessionId }), CLOSE_SESSION_TIMEOUT_MS));
|
|
587
622
|
}
|
|
588
623
|
catch {
|
|
589
624
|
// best-effort: the session is already untracked; the process stays pooled.
|
|
@@ -740,25 +775,39 @@ export class SessionHandle {
|
|
|
740
775
|
fallbacks.push(`${spec}: reasoning_effort "${effortTokens.join(",")}" not advertised`);
|
|
741
776
|
}
|
|
742
777
|
}
|
|
743
|
-
// Fast mode: a `fast` token turns the advertised toggle on.
|
|
778
|
+
// Fast mode: a `fast` token turns the advertised toggle on. The agent may advertise
|
|
779
|
+
// it as a `type: "boolean"` option (agents gate that shape on our
|
|
780
|
+
// session.configOptions.boolean capability) or as the legacy on/off select.
|
|
744
781
|
if (fastRequested && !effortAbsorbedByModel) {
|
|
745
782
|
const fastOption = this.configOptions.find(isFastModeOption);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
await this.applyConfigOption(fastOption.id, onValue);
|
|
783
|
+
if (fastOption?.type === "boolean") {
|
|
784
|
+
if (fastOption.currentValue !== true) {
|
|
785
|
+
await this.applyConfigOption(fastOption.id, true);
|
|
750
786
|
}
|
|
751
787
|
}
|
|
752
788
|
else {
|
|
753
|
-
|
|
754
|
-
|
|
789
|
+
const onValue = fastOption ? fastModeOnValue(flattenSelectOptions(fastOption.options)) : undefined;
|
|
790
|
+
if (fastOption && onValue) {
|
|
791
|
+
if (fastOption.currentValue !== onValue) {
|
|
792
|
+
await this.applyConfigOption(fastOption.id, onValue);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
else {
|
|
796
|
+
// No Fast-mode option, or it advertises no "on" value.
|
|
797
|
+
fallbacks.push(`${spec}: Fast mode not advertised`);
|
|
798
|
+
}
|
|
755
799
|
}
|
|
756
800
|
}
|
|
757
801
|
return fallbacks;
|
|
758
802
|
}
|
|
759
|
-
/** Set one session config option via the wire method and adopt the echoed catalog.
|
|
803
|
+
/** Set one session config option via the wire method and adopt the echoed catalog.
|
|
804
|
+
* A boolean value drives a `type: "boolean"` option (the request must carry the type
|
|
805
|
+
* discriminator on the wire); a string value drives a select option. */
|
|
760
806
|
async applyConfigOption(configId, value) {
|
|
761
|
-
const
|
|
807
|
+
const request = typeof value === "boolean"
|
|
808
|
+
? { sessionId: this.sessionId, configId, value, type: "boolean" }
|
|
809
|
+
: { sessionId: this.sessionId, configId, value };
|
|
810
|
+
const response = await this.pooled.setSessionConfigOption(request);
|
|
762
811
|
this.configOptions = response.configOptions;
|
|
763
812
|
}
|
|
764
813
|
/** Send a prompt turn and drain it; returns the final PromptResponse. */
|
|
@@ -776,7 +825,7 @@ export class SessionHandle {
|
|
|
776
825
|
prompt: typeof prompt === "string" ? [{ type: "text", text: prompt }] : prompt,
|
|
777
826
|
...(gatedMeta ? { _meta: gatedMeta } : {}),
|
|
778
827
|
};
|
|
779
|
-
const response = await this.pooled.
|
|
828
|
+
const response = await this.pooled.prompt(request);
|
|
780
829
|
this.state.usage.recordPromptUsage(response.usage);
|
|
781
830
|
return response;
|
|
782
831
|
}
|
|
@@ -822,8 +871,12 @@ function isModelSelectOption(option) {
|
|
|
822
871
|
function isReasoningEffortOption(option) {
|
|
823
872
|
return option.type === "select" && (option.id === "reasoning_effort" || option.category === "thought_level");
|
|
824
873
|
}
|
|
874
|
+
/** Fast mode is matched by its stable id (upstream codex-acp moved the category to
|
|
875
|
+
* "model_config"; the legacy category match is kept for older agents). Both the
|
|
876
|
+
* `type: "boolean"` and the legacy on/off select shapes qualify — the caller branches
|
|
877
|
+
* on `type`. */
|
|
825
878
|
function isFastModeOption(option) {
|
|
826
|
-
return option.
|
|
879
|
+
return option.id === "fast-mode" || option.category === "fast-mode";
|
|
827
880
|
}
|
|
828
881
|
/** Split the trailing `[...]` of a `model[effort]` spec into its comma/space/plus-separated
|
|
829
882
|
* tokens (e.g. `gpt-5.1-codex[high]` -> ["high"], `gpt-5-codex[high fast]` -> ["high","fast"]). */
|
|
@@ -20,7 +20,10 @@ export interface ClientHandlers {
|
|
|
20
20
|
fs?: FsHandlers;
|
|
21
21
|
terminal?: TerminalHandlers;
|
|
22
22
|
}
|
|
23
|
-
/** The client capability advertisement derived solely from registered consumer
|
|
23
|
+
/** The client capability advertisement: fs/terminal derived solely from registered consumer
|
|
24
|
+
* handlers, plus the capabilities this client supports natively regardless of handlers —
|
|
25
|
+
* boolean session config options (SessionHandle drives the catalog programmatically and
|
|
26
|
+
* handles `type: "boolean"` entries, e.g. codex-acp's Fast-mode toggle). */
|
|
24
27
|
export declare function clientCapabilitiesFor(handlers: ClientHandlers | undefined): ClientCapabilities;
|
|
25
28
|
/** Fail-fast validation for JavaScript consumers bypassing the TerminalHandlers type. */
|
|
26
29
|
export declare function validateClientHandlers(handlers: ClientHandlers | undefined): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-handlers.d.ts","sourceRoot":"","sources":["../src/client-handlers.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,CACX,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,CAAC;IACxD,aAAa,CAAC,CACZ,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;CACzE;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;IAC5D,cAAc,CACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;IAC5D,mBAAmB,CACjB,MAAM,EAAE,0BAA0B,EAClC,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;IACtE,YAAY,CACV,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAAC;IACtE,eAAe,CACb,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAAG,uBAAuB,GAAG,IAAI,CAAC;CAC7E;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAUD
|
|
1
|
+
{"version":3,"file":"client-handlers.d.ts","sourceRoot":"","sources":["../src/client-handlers.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,CACX,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,CAAC;IACxD,aAAa,CAAC,CACZ,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;CACzE;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;IAC5D,cAAc,CACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;IAC5D,mBAAmB,CACjB,MAAM,EAAE,0BAA0B,EAClC,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;IACtE,YAAY,CACV,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAAC;IACtE,eAAe,CACb,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAAG,uBAAuB,GAAG,IAAI,CAAC;CAC7E;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAUD;;;6EAG6E;AAC7E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,GAAG,kBAAkB,CAY9F;AAED,yFAAyF;AACzF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAMjF"}
|
package/dist/client-handlers.js
CHANGED
|
@@ -5,11 +5,14 @@ const TERMINAL_HANDLER_METHODS = [
|
|
|
5
5
|
"killTerminal",
|
|
6
6
|
"releaseTerminal",
|
|
7
7
|
];
|
|
8
|
-
/** The client capability advertisement derived solely from registered consumer
|
|
8
|
+
/** The client capability advertisement: fs/terminal derived solely from registered consumer
|
|
9
|
+
* handlers, plus the capabilities this client supports natively regardless of handlers —
|
|
10
|
+
* boolean session config options (SessionHandle drives the catalog programmatically and
|
|
11
|
+
* handles `type: "boolean"` entries, e.g. codex-acp's Fast-mode toggle). */
|
|
9
12
|
export function clientCapabilitiesFor(handlers) {
|
|
13
|
+
const capabilities = { session: { configOptions: { boolean: {} } } };
|
|
10
14
|
if (!handlers)
|
|
11
|
-
return
|
|
12
|
-
const capabilities = {};
|
|
15
|
+
return capabilities;
|
|
13
16
|
const fs = handlers.fs;
|
|
14
17
|
const fsCapabilities = {};
|
|
15
18
|
if (typeof fs?.readTextFile === "function")
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automatalabs/acp-agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=22"
|
|
7
|
+
},
|
|
5
8
|
"repository": {
|
|
6
9
|
"type": "git",
|
|
7
10
|
"url": "git+https://github.com/VikashLoomba/agentprism-workflows.git",
|
|
@@ -24,11 +27,11 @@
|
|
|
24
27
|
"access": "public"
|
|
25
28
|
},
|
|
26
29
|
"dependencies": {
|
|
27
|
-
"@agentclientprotocol/sdk": "1.
|
|
28
|
-
"@agentclientprotocol/claude-agent-acp": "0.
|
|
29
|
-
"@automatalabs/codex-acp": "1.
|
|
30
|
+
"@agentclientprotocol/sdk": "^1.2.0",
|
|
31
|
+
"@agentclientprotocol/claude-agent-acp": "0.56.0",
|
|
32
|
+
"@automatalabs/codex-acp": "1.4.0",
|
|
30
33
|
"typebox": "1.3.2",
|
|
31
|
-
"@automatalabs/shared-types": "0.
|
|
34
|
+
"@automatalabs/shared-types": "0.8.0"
|
|
32
35
|
},
|
|
33
36
|
"scripts": {
|
|
34
37
|
"build": "tsc -b",
|