@automatalabs/acp-agents 2.0.0 → 3.0.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.
Files changed (72) hide show
  1. package/README.md +53 -17
  2. package/dist/acp-client.d.ts +10 -4
  3. package/dist/acp-client.d.ts.map +1 -1
  4. package/dist/acp-client.js +11 -8
  5. package/dist/agent/acp-agent.d.ts +84 -26
  6. package/dist/agent/acp-agent.d.ts.map +1 -1
  7. package/dist/agent/acp-agent.js +458 -170
  8. package/dist/agent/errors.d.ts +12 -2
  9. package/dist/agent/errors.d.ts.map +1 -1
  10. package/dist/agent/errors.js +38 -9
  11. package/dist/agent/fork.d.ts +7 -5
  12. package/dist/agent/fork.d.ts.map +1 -1
  13. package/dist/agent/fork.js +7 -5
  14. package/dist/agent/messages.d.ts +42 -0
  15. package/dist/agent/messages.d.ts.map +1 -0
  16. package/dist/agent/messages.js +225 -0
  17. package/dist/agent/probe.d.ts +1 -1
  18. package/dist/agent/probe.d.ts.map +1 -1
  19. package/dist/agent/probe.js +5 -1
  20. package/dist/agent/queue.js +2 -2
  21. package/dist/agent/routing.d.ts +19 -1
  22. package/dist/agent/routing.d.ts.map +1 -1
  23. package/dist/agent/routing.js +41 -4
  24. package/dist/agent/stream.d.ts +21 -0
  25. package/dist/agent/stream.d.ts.map +1 -0
  26. package/dist/agent/stream.js +93 -0
  27. package/dist/agent/structured.d.ts +7 -3
  28. package/dist/agent/structured.d.ts.map +1 -1
  29. package/dist/agent/structured.js +24 -14
  30. package/dist/agent/tool-host.d.ts +34 -0
  31. package/dist/agent/tool-host.d.ts.map +1 -0
  32. package/dist/agent/tool-host.js +138 -0
  33. package/dist/agent/tools.d.ts +26 -0
  34. package/dist/agent/tools.d.ts.map +1 -0
  35. package/dist/agent/tools.js +62 -0
  36. package/dist/agent/turn.d.ts +6 -3
  37. package/dist/agent/turn.d.ts.map +1 -1
  38. package/dist/agent/turn.js +15 -67
  39. package/dist/agent/types.d.ts +174 -25
  40. package/dist/agent/types.d.ts.map +1 -1
  41. package/dist/backend.d.ts +4 -3
  42. package/dist/backend.d.ts.map +1 -1
  43. package/dist/backends/codex.d.ts +2 -1
  44. package/dist/backends/codex.d.ts.map +1 -1
  45. package/dist/backends/codex.js +3 -2
  46. package/dist/config-catalog.d.ts +4 -0
  47. package/dist/config-catalog.d.ts.map +1 -1
  48. package/dist/config-catalog.js +1 -0
  49. package/dist/index.d.ts +5 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +6 -0
  52. package/dist/local-mcp-host.d.ts +30 -0
  53. package/dist/local-mcp-host.d.ts.map +1 -0
  54. package/dist/local-mcp-host.js +151 -0
  55. package/dist/protocol-coverage.d.ts +8 -6
  56. package/dist/protocol-coverage.d.ts.map +1 -1
  57. package/dist/protocol-coverage.js +3 -2
  58. package/dist/registry.d.ts +3 -3
  59. package/dist/registry.d.ts.map +1 -1
  60. package/dist/runner.d.ts +5 -0
  61. package/dist/runner.d.ts.map +1 -1
  62. package/dist/runner.js +7 -4
  63. package/dist/structured-output.d.ts +18 -0
  64. package/dist/structured-output.d.ts.map +1 -1
  65. package/dist/structured-output.js +19 -1
  66. package/dist/structured-tool.d.ts +7 -9
  67. package/dist/structured-tool.d.ts.map +1 -1
  68. package/dist/structured-tool.js +14 -102
  69. package/dist/traits.d.ts +51 -0
  70. package/dist/traits.d.ts.map +1 -0
  71. package/dist/traits.js +88 -0
  72. package/package.json +4 -4
@@ -0,0 +1,51 @@
1
+ import type { Backend } from "./backend.js";
2
+ import type { NegotiatedCapabilities } from "./capabilities.js";
3
+ import { type ForkSessionTraitRow, type SystemPromptSupport } from "./protocol-coverage.js";
4
+ import type { BackendRegistry } from "./registry.js";
5
+ /** The traits of one agent's backend: routing identity, the `session/fork` row the SDK follows,
6
+ * the system-prompt channel and where that answer came from, the two vendor extensions, the
7
+ * structured-output channel, and the `PromptResponse.usage` scope. Frozen; `AcpAgent#traits` and
8
+ * `AcpAgent.traits()` hand out a fresh object per read. */
9
+ export interface AcpAgentTraits {
10
+ /** The resolved backend id (a built-in id or a registered custom name). */
11
+ readonly backendId: string;
12
+ /** `true` for a registry (custom) backend, `false` for one of the built-in adapters — a registry
13
+ * lookup, like the fork trait, so a custom entry that shadows a built-in name is `custom`. */
14
+ readonly custom: boolean;
15
+ /** The mode the SDK selects when the caller omits `mode` and the catalog advertises it. */
16
+ readonly defaultModeId?: string;
17
+ /** The `session/fork` row the SDK's fork choreography follows (`forkTraitFor`): a built-in's
18
+ * `FORK_SESSION_TRAITS` row, or a custom entry's declaration. */
19
+ readonly fork: ForkSessionTraitRow;
20
+ /** Which halves of `systemPrompt` the backend carries and where the answer came from: `table`
21
+ * (a built-in's `SYSTEM_PROMPT_SUPPORT` row), `advertised` (the live agent's initialize
22
+ * advertisement — pi under `_meta.systemPrompt`, the Codex fork under
23
+ * `agentCapabilities._meta["@automatalabs/codex-acp"]` — which wins over the table once the
24
+ * connection is open), or `none` (no channel — every custom backend before open, since
25
+ * `CustomAcpBackend` never carries the neutral instructions; a built-in that supports neither
26
+ * half, OpenCode, still reports its all-false row as `table`). */
27
+ readonly systemPrompt: SystemPromptSupport & {
28
+ readonly source: "table" | "advertised" | "none";
29
+ };
30
+ /** `_session/steering`: the built-in `ACP_EXTENSION_SUPPORT_MATRIX` row before open (`unknown`
31
+ * for a custom backend); after open, whether `initializeMeta.steering.supported === true`. */
32
+ readonly steering: "supported" | "not-advertised" | "unknown";
33
+ /** `_session/loaded_turn/query`, derived exactly like `steering` (`initializeMeta.loadedTurn`). */
34
+ readonly loadedTurn: "supported" | "not-advertised" | "unknown";
35
+ /** How a `schema` reaches this backend, from the Backend object's behavior: `client-tool` (the
36
+ * injected StructuredOutput MCP tool plus the in-prompt contract — pi, OpenCode, custom),
37
+ * `turn-meta` (the schema rides every turn's `_meta` — Codex), or `session-meta` (bound at
38
+ * session open — Claude). */
39
+ readonly structuredOutput: "session-meta" | "turn-meta" | "client-tool";
40
+ /** What `PromptResponse.usage` covers (`PROMPT_USAGE_SCOPES`): every agent reports the turn. */
41
+ readonly promptUsage: "turn";
42
+ }
43
+ /**
44
+ * Describe `backend`'s traits. Without `live`, every answer comes from the tables and the Backend
45
+ * object; with `live` (the negotiated capabilities of an open connection) the initialize
46
+ * advertisements refine `systemPrompt`, `steering`, and `loadedTurn`. `registry` is the registry
47
+ * the backend was routed through — a registered name is a custom backend and follows its own
48
+ * declarations, never a built-in's rows.
49
+ */
50
+ export declare function describeBackendTraits(backend: Backend, registry: BackendRegistry, live?: NegotiatedCapabilities): AcpAgentTraits;
51
+ //# sourceMappingURL=traits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traits.d.ts","sourceRoot":"","sources":["../src/traits.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;4DAG4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;mGAC+F;IAC/F,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,2FAA2F;IAC3F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;sEACkE;IAClE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC;;;;;;uEAMmE;IACnE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,GAAG;QAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,CAAA;KAAE,CAAC;IAClG;mGAC+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAC9D,mGAAmG;IACnG,QAAQ,CAAC,UAAU,EAAE,WAAW,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAChE;;;kCAG8B;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,cAAc,GAAG,WAAW,GAAG,aAAa,CAAC;IACxE,gGAAgG;IAChG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AASD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,EACzB,IAAI,CAAC,EAAE,sBAAsB,GAC5B,cAAc,CAchB"}
package/dist/traits.js ADDED
@@ -0,0 +1,88 @@
1
+ // Per-agent traits — what the AcpAgent SDK knows about a backend BEFORE it spawns (the executable
2
+ // protocol-coverage tables plus the Backend object's own behavior) and what the live agent
3
+ // ADVERTISED at initialize once a connection is open. Read-only data for callers: it never gates
4
+ // a call by itself. The pre-open validators (`assertSystemPromptSupported`, the fork cwd rule)
5
+ // keep reading the tables, so a refused option is refused before a process exists; the traits
6
+ // tell the caller what the table says and, after open, what the agent actually advertised.
7
+ import { Type } from "typebox";
8
+ import { CODEX_CUSTOM_CAPABILITY_NAMESPACE, CODEX_META_KEYS, META_KEYS } from "@automatalabs/shared-types";
9
+ import { LOADED_TURN_QUERY_METHOD, SESSION_STEERING_METHOD } from "./acp-client.js";
10
+ import { forkTraitFor } from "./agent/fork.js";
11
+ import { ACP_EXTENSION_SUPPORT_MATRIX, SYSTEM_PROMPT_UNSUPPORTED, promptUsageScope, } from "./protocol-coverage.js";
12
+ /** A trivial schema for probing which channel `Backend.promptMeta` carries the schema on. */
13
+ const PROBE_SCHEMA = Type.Object({ ok: Type.Boolean() });
14
+ function isRecord(value) {
15
+ return value !== null && typeof value === "object" && !Array.isArray(value);
16
+ }
17
+ /**
18
+ * Describe `backend`'s traits. Without `live`, every answer comes from the tables and the Backend
19
+ * object; with `live` (the negotiated capabilities of an open connection) the initialize
20
+ * advertisements refine `systemPrompt`, `steering`, and `loadedTurn`. `registry` is the registry
21
+ * the backend was routed through — a registered name is a custom backend and follows its own
22
+ * declarations, never a built-in's rows.
23
+ */
24
+ export function describeBackendTraits(backend, registry, live) {
25
+ const custom = registry.has(backend.id);
26
+ const initializeMeta = isRecord(live?.initializeMeta) ? live.initializeMeta : undefined;
27
+ return Object.freeze({
28
+ backendId: backend.id,
29
+ custom,
30
+ ...(backend.defaultModeId === undefined ? {} : { defaultModeId: backend.defaultModeId }),
31
+ fork: forkTraitFor(backend, registry),
32
+ systemPrompt: systemPromptTrait(backend, live),
33
+ steering: extensionTrait(backend.id, custom, SESSION_STEERING_METHOD, live, initializeMeta?.steering),
34
+ loadedTurn: extensionTrait(backend.id, custom, LOADED_TURN_QUERY_METHOD, live, initializeMeta?.loadedTurn),
35
+ structuredOutput: structuredOutputChannel(backend),
36
+ promptUsage: promptUsageScope(backend.id),
37
+ });
38
+ }
39
+ /** The live advertisement wins; else the Backend object's row — set only by the built-ins
40
+ * (`SYSTEM_PROMPT_SUPPORT`), never by `CustomAcpBackend`, so a defined row is always `table`. */
41
+ function systemPromptTrait(backend, live) {
42
+ const advertised = live ? advertisedSystemPrompt(live) : undefined;
43
+ if (advertised)
44
+ return Object.freeze({ ...advertised, source: "advertised" });
45
+ const table = backend.systemPrompt;
46
+ if (!table)
47
+ return Object.freeze({ ...SYSTEM_PROMPT_UNSUPPORTED, source: "none" });
48
+ return Object.freeze({ replace: table.replace, append: table.append, source: "table" });
49
+ }
50
+ /** The live system-prompt advertisement, when the agent made one: the bare `_meta.systemPrompt`
51
+ * block (`{ replace, append }` booleans — pi), else the Codex fork's namespaced capability block
52
+ * (`baseInstructions` => replace, `developerInstructions` => append). An agent that advertises
53
+ * neither (Claude) returns undefined and the table stands. */
54
+ function advertisedSystemPrompt(live) {
55
+ const initializeMeta = isRecord(live.initializeMeta) ? live.initializeMeta : undefined;
56
+ const bare = initializeMeta?.[META_KEYS.systemPrompt];
57
+ if (isRecord(bare))
58
+ return { replace: bare.replace === true, append: bare.append === true };
59
+ const agentMeta = isRecord(live.agent._meta) ? live.agent._meta : undefined;
60
+ const namespace = agentMeta?.[CODEX_CUSTOM_CAPABILITY_NAMESPACE];
61
+ if (isRecord(namespace) &&
62
+ (CODEX_META_KEYS.baseInstructions in namespace || CODEX_META_KEYS.developerInstructions in namespace)) {
63
+ return {
64
+ replace: namespace[CODEX_META_KEYS.baseInstructions] === true,
65
+ append: namespace[CODEX_META_KEYS.developerInstructions] === true,
66
+ };
67
+ }
68
+ return undefined;
69
+ }
70
+ function extensionTrait(backendId, custom, method, live, advertisement) {
71
+ if (live)
72
+ return isRecord(advertisement) && advertisement.supported === true ? "supported" : "not-advertised";
73
+ if (custom)
74
+ return "unknown";
75
+ const row = ACP_EXTENSION_SUPPORT_MATRIX.find((candidate) => candidate.agent === backendId && candidate.method === method);
76
+ return row?.disposition ?? "unknown";
77
+ }
78
+ /** Derived from the Backend object's behavior, never its id: a backend that opts into the injected
79
+ * tool is `client-tool`; else one whose `promptMeta` carries the schema is `turn-meta`; else the
80
+ * schema is bound at session open (`session-meta`). */
81
+ function structuredOutputChannel(backend) {
82
+ if (backend.injectStructuredOutputTool === true)
83
+ return "client-tool";
84
+ const turnMeta = backend.promptMeta(PROBE_SCHEMA);
85
+ if (turnMeta !== undefined && Object.keys(turnMeta).length > 0)
86
+ return "turn-meta";
87
+ return "session-meta";
88
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automatalabs/acp-agents",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "license": "Apache-2.0",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -31,9 +31,9 @@
31
31
  "@agentclientprotocol/sdk": "^1.4.0",
32
32
  "@modelcontextprotocol/sdk": "^1.30",
33
33
  "typebox": "1.3.2",
34
- "@automatalabs/codex-acp": "2.6.0",
35
- "@automatalabs/pi-acp": "0.9.0",
36
- "@automatalabs/shared-types": "3.0.0"
34
+ "@automatalabs/codex-acp": "2.7.0",
35
+ "@automatalabs/pi-acp": "0.9.1",
36
+ "@automatalabs/shared-types": "3.1.0"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "tsc -b",