@automatalabs/acp-agents 1.3.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.
- package/README.md +66 -21
- package/dist/acp-client.d.ts +15 -9
- package/dist/acp-client.d.ts.map +1 -1
- package/dist/acp-client.js +12 -10
- package/dist/agent/acp-agent.d.ts +84 -26
- package/dist/agent/acp-agent.d.ts.map +1 -1
- package/dist/agent/acp-agent.js +461 -168
- package/dist/agent/errors.d.ts +12 -2
- package/dist/agent/errors.d.ts.map +1 -1
- package/dist/agent/errors.js +38 -9
- package/dist/agent/fork.d.ts +7 -5
- package/dist/agent/fork.d.ts.map +1 -1
- package/dist/agent/fork.js +7 -5
- package/dist/agent/messages.d.ts +42 -0
- package/dist/agent/messages.d.ts.map +1 -0
- package/dist/agent/messages.js +225 -0
- package/dist/agent/probe.d.ts +1 -1
- package/dist/agent/probe.d.ts.map +1 -1
- package/dist/agent/probe.js +5 -1
- package/dist/agent/queue.js +2 -2
- package/dist/agent/routing.d.ts +19 -1
- package/dist/agent/routing.d.ts.map +1 -1
- package/dist/agent/routing.js +41 -4
- package/dist/agent/stream.d.ts +21 -0
- package/dist/agent/stream.d.ts.map +1 -0
- package/dist/agent/stream.js +93 -0
- package/dist/agent/structured.d.ts +7 -3
- package/dist/agent/structured.d.ts.map +1 -1
- package/dist/agent/structured.js +24 -14
- package/dist/agent/tool-host.d.ts +34 -0
- package/dist/agent/tool-host.d.ts.map +1 -0
- package/dist/agent/tool-host.js +138 -0
- package/dist/agent/tools.d.ts +26 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +62 -0
- package/dist/agent/turn.d.ts +6 -3
- package/dist/agent/turn.d.ts.map +1 -1
- package/dist/agent/turn.js +15 -67
- package/dist/agent/types.d.ts +183 -29
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/backend.d.ts +13 -5
- package/dist/backend.d.ts.map +1 -1
- package/dist/backends/claude.d.ts +4 -0
- package/dist/backends/claude.d.ts.map +1 -1
- package/dist/backends/claude.js +40 -17
- package/dist/backends/codex.d.ts +5 -0
- package/dist/backends/codex.d.ts.map +1 -1
- package/dist/backends/codex.js +15 -9
- package/dist/backends/custom.d.ts.map +1 -1
- package/dist/backends/custom.js +3 -2
- package/dist/backends/opencode.d.ts +4 -0
- package/dist/backends/opencode.d.ts.map +1 -1
- package/dist/backends/opencode.js +5 -1
- package/dist/backends/pi.d.ts +5 -2
- package/dist/backends/pi.d.ts.map +1 -1
- package/dist/backends/pi.js +15 -3
- package/dist/config-catalog.d.ts +4 -0
- package/dist/config-catalog.d.ts.map +1 -1
- package/dist/config-catalog.js +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/interactive.d.ts +4 -5
- package/dist/interactive.d.ts.map +1 -1
- package/dist/local-mcp-host.d.ts +30 -0
- package/dist/local-mcp-host.d.ts.map +1 -0
- package/dist/local-mcp-host.js +151 -0
- package/dist/protocol-coverage.d.ts +34 -6
- package/dist/protocol-coverage.d.ts.map +1 -1
- package/dist/protocol-coverage.js +26 -1
- package/dist/registry.d.ts +3 -3
- package/dist/registry.d.ts.map +1 -1
- package/dist/runner.d.ts +5 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +13 -8
- package/dist/structured-output.d.ts +18 -0
- package/dist/structured-output.d.ts.map +1 -1
- package/dist/structured-output.js +19 -1
- package/dist/structured-tool.d.ts +7 -9
- package/dist/structured-tool.d.ts.map +1 -1
- package/dist/structured-tool.js +14 -102
- package/dist/system-prompt.d.ts +13 -0
- package/dist/system-prompt.d.ts.map +1 -0
- package/dist/system-prompt.js +67 -0
- package/dist/traits.d.ts +51 -0
- package/dist/traits.d.ts.map +1 -0
- package/dist/traits.js +88 -0
- package/package.json +4 -4
package/dist/registry.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export interface CustomBackendConfig {
|
|
|
14
14
|
* Default true; set false for custom agents that should use only the generic prompt/_meta path. */
|
|
15
15
|
structuredOutputTool?: boolean;
|
|
16
16
|
/** How the custom agent answers `session/fork` (see `FORK_SESSION_TRAITS`). Omitted = `live` /
|
|
17
|
-
* `free`: the plain ACP contract. Entries wrapping claude-agent-acp or codex-acp
|
|
18
|
-
* `{ disposition: "id-only" }` — a registered name is a
|
|
19
|
-
* may shadow and never inherits the built-in's row. */
|
|
17
|
+
* `free`: the plain ACP contract. Entries wrapping claude-agent-acp (or upstream codex-acp, which
|
|
18
|
+
* unsubscribes its forks) MUST declare `{ disposition: "id-only" }` — a registered name is a
|
|
19
|
+
* different program from the built-in it may shadow and never inherits the built-in's row. */
|
|
20
20
|
fork?: CustomBackendForkConfig;
|
|
21
21
|
}
|
|
22
22
|
/** A custom backend's declared `session/fork` disposition — data, never probed. `id-only`: the fork
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAIlD,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;2FACuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC;wGACoG;IACpG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAIlD,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;2FACuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC;wGACoG;IACpG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;mGAG+F;IAC/F,IAAI,CAAC,EAAE,uBAAuB,CAAC;CAChC;AAED;;wGAEwG;AACxG,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,GAAG,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAwBjB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,eAAe,EACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GACxC,eAAe,CAQjB"}
|
package/dist/runner.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type AcpEventListener, type AcpEventName } from "./events.js";
|
|
|
6
6
|
import type { Backend } from "./backend.js";
|
|
7
7
|
import { InteractiveSession, type InteractiveSessionOptions } from "./interactive.js";
|
|
8
8
|
import { type BackendRegistry, type CustomBackendConfig } from "./registry.js";
|
|
9
|
+
import { type AcpAgentTraits } from "./traits.js";
|
|
9
10
|
import { type AuthMethodDescriptor, type AuthResolution, type AuthResolver } from "./auth/auth-types.js";
|
|
10
11
|
import { type AuthMethodType, type BackendAuthState } from "./auth/auth-store.js";
|
|
11
12
|
import type { ElicitationResolver, PermissionResolver } from "./permissions.js";
|
|
@@ -17,6 +18,10 @@ export interface ProbedConfigOptions {
|
|
|
17
18
|
options: SessionConfigOption[];
|
|
18
19
|
/** Effective ACP mode catalog after normalizing the mode config-option fallback; null means unsupported. AcpAgentRunner always returns this field. */
|
|
19
20
|
modes?: SessionModeState | null;
|
|
21
|
+
/** The backend's traits refined by the probe connection's initialize advertisements
|
|
22
|
+
* (`describeBackendTraits`): pi and the Codex fork report their system-prompt channel as
|
|
23
|
+
* `advertised`, Claude reports the table. AcpAgentRunner and the SDK probe always return it. */
|
|
24
|
+
traits?: AcpAgentTraits;
|
|
20
25
|
}
|
|
21
26
|
export interface ProbeConfigOptionsOptions {
|
|
22
27
|
cwd?: string;
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAkBA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,WAAW,EAEhB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.js
CHANGED
|
@@ -25,14 +25,15 @@ import { BUILTIN_BACKEND_IDS } from "./backends/builtins.js";
|
|
|
25
25
|
import { registryWithRunBackends, resolveBackendRegistry, } from "./registry.js";
|
|
26
26
|
import { mapThrownError } from "./errors-map.js";
|
|
27
27
|
import { assertNoModelConfigOption, resolveModelRoute } from "./routing.js";
|
|
28
|
+
import { assertSystemPromptSupported } from "./system-prompt.js";
|
|
28
29
|
import { sessionRefFor } from "./session-ref.js";
|
|
30
|
+
import { describeBackendTraits } from "./traits.js";
|
|
29
31
|
import { buildAuthDescriptor, } from "./auth/auth-types.js";
|
|
30
32
|
import { AuthStore, classifyCredential, } from "./auth/auth-store.js";
|
|
31
33
|
import { ProviderStore, providerVertexMeta } from "./provider-store.js";
|
|
32
|
-
import { resolveStructuredOutput } from "./structured-output.js";
|
|
34
|
+
import { repairPromptText, resolveStructuredOutput } from "./structured-output.js";
|
|
33
35
|
import { STRUCTURED_OUTPUT_SERVER_NAME, StructuredOutputToolHost, } from "./structured-tool.js";
|
|
34
36
|
import { buildRunPrompt, mergeTurnMeta, promptWithImages, validatePromptImages, } from "./prompt.js";
|
|
35
|
-
const STRUCTURED_TOOL_REPROMPT_TEXT = "You did not call the StructuredOutput tool. Call the StructuredOutput tool now, exactly once, with your final answer as its arguments conforming to its parameter schema. Do not reply with plain text.";
|
|
36
37
|
const CONTINUATION_INSTRUCTION = "Your previous turn was interrupted before it finished — the provider paused it for a usage " +
|
|
37
38
|
"limit or expired credentials, not because the task was complete. The full task and all prior " +
|
|
38
39
|
"context are already in this session's history; do not restart or repeat work you already did. " +
|
|
@@ -173,10 +174,11 @@ export class AcpAgentRunner {
|
|
|
173
174
|
throw new Error("ACP agent runner is disposed");
|
|
174
175
|
opts.signal?.throwIfAborted();
|
|
175
176
|
const cwd = opts.cwd ?? process.cwd();
|
|
177
|
+
const registry = registryWithRunBackends(this.backends, opts.backends);
|
|
176
178
|
const prepared = this.prepareSession({ model: spec }, {
|
|
177
179
|
cwd,
|
|
178
180
|
schema: undefined,
|
|
179
|
-
registry
|
|
181
|
+
registry,
|
|
180
182
|
signal: opts.signal,
|
|
181
183
|
});
|
|
182
184
|
let session;
|
|
@@ -191,6 +193,7 @@ export class AcpAgentRunner {
|
|
|
191
193
|
...(prepared.backend.defaultModeId === undefined ? {} : { defaultModeId: prepared.backend.defaultModeId }),
|
|
192
194
|
options: session.advertisedConfigOptions,
|
|
193
195
|
modes: session.modes ?? null,
|
|
196
|
+
traits: describeBackendTraits(prepared.backend, registry, session.capabilities),
|
|
194
197
|
};
|
|
195
198
|
}
|
|
196
199
|
finally {
|
|
@@ -685,7 +688,8 @@ export class AcpAgentRunner {
|
|
|
685
688
|
maxSchemaRetries: opts.maxSchemaRetries,
|
|
686
689
|
signal: opts.signal,
|
|
687
690
|
label: opts.label,
|
|
688
|
-
|
|
691
|
+
// The same selection AcpAgent's ladder makes (tool variant vs JSON variant), bare text.
|
|
692
|
+
repromptText: repairPromptText({ toolActive: structuredToolActive }),
|
|
689
693
|
});
|
|
690
694
|
return result;
|
|
691
695
|
}
|
|
@@ -1029,6 +1033,8 @@ export class AcpAgentRunner {
|
|
|
1029
1033
|
prepareSession(opts, config) {
|
|
1030
1034
|
const route = resolveModelRoute(opts.model ?? opts.tier, config.registry);
|
|
1031
1035
|
const backend = route.backend;
|
|
1036
|
+
// Refuse instructions the routed backend cannot carry BEFORE anything is acquired or sent.
|
|
1037
|
+
const systemPrompt = assertSystemPromptSupported(backend, opts.systemPrompt, opts.label);
|
|
1032
1038
|
const policy = {
|
|
1033
1039
|
allow: opts.toolNames,
|
|
1034
1040
|
deny: opts.disallowedToolNames,
|
|
@@ -1054,10 +1060,9 @@ export class AcpAgentRunner {
|
|
|
1054
1060
|
label: opts.label,
|
|
1055
1061
|
// Direct engine-call correlation on emitted events only; never sent on the ACP wire.
|
|
1056
1062
|
callIndex: opts.callIndex,
|
|
1057
|
-
//
|
|
1058
|
-
//
|
|
1059
|
-
|
|
1060
|
-
developerInstructions: opts.developerInstructions,
|
|
1063
|
+
// Backend-neutral system prompt instructions -> the backend's own session `_meta` keys
|
|
1064
|
+
// (validated above). Additive; never hashed.
|
|
1065
|
+
systemPrompt,
|
|
1061
1066
|
retainSessionLog: config.retainSessionLog,
|
|
1062
1067
|
},
|
|
1063
1068
|
};
|
|
@@ -39,6 +39,24 @@ export interface ResolveOptions {
|
|
|
39
39
|
label?: string;
|
|
40
40
|
repromptText?: string;
|
|
41
41
|
}
|
|
42
|
+
/** The repair prompt for a schema turn that produced no valid JSON (native channels, prose
|
|
43
|
+
* extraction). Sent bare — text only, no re-embedded contract; the schema is in the session's
|
|
44
|
+
* context from the first turn — by the runner's ladder and by `AcpAgent`'s opt-in one. */
|
|
45
|
+
export declare const REPROMPT_TEXT: string;
|
|
46
|
+
/** The repair prompt when the client-hosted StructuredOutput tool is active on the session and
|
|
47
|
+
* the turn did not call it. */
|
|
48
|
+
export declare const STRUCTURED_TOOL_REPROMPT_TEXT = "You did not call the StructuredOutput tool. Call the StructuredOutput tool now, exactly once, with your final answer as its arguments conforming to its parameter schema. Do not reply with plain text.";
|
|
49
|
+
/**
|
|
50
|
+
* The one repair prompt both ladders send (package-internal; the runner and `AcpAgent` are its
|
|
51
|
+
* only callers): `STRUCTURED_TOOL_REPROMPT_TEXT` when the injected StructuredOutput tool is active
|
|
52
|
+
* for the session, else `REPROMPT_TEXT`; with `reason` (the previous turn's validation failure —
|
|
53
|
+
* `AcpAgentTurn.structuredError`) appended on its own line so the agent corrects against the actual
|
|
54
|
+
* miss, not a guess. The runner passes no reason and sends the bare text.
|
|
55
|
+
*/
|
|
56
|
+
export declare function repairPromptText(options: {
|
|
57
|
+
toolActive: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
}): string;
|
|
42
60
|
/**
|
|
43
61
|
* Resolve a schema agent's result via the ladder above. Returns the validated value (typed
|
|
44
62
|
* unknown at this layer; the caller casts to the seam's AgentResult<S>). Throws
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAa9D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBpD;AAED,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAQtE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAUvE;AAED,sGAAsG;AACtG,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,+DAA+D;IAC/D,QAAQ,IAAI,MAAM,CAAC;IACnB,8FAA8F;IAC9F,SAAS,CAAC,IAAI,OAAO,CAAC;IACtB,4FAA4F;IAC5F,WAAW,CAAC,IAAI,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAa9D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBpD;AAED,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAQtE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAUvE;AAED,sGAAsG;AACtG,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,+DAA+D;IAC/D,QAAQ,IAAI,MAAM,CAAC;IACnB,8FAA8F;IAC9F,SAAS,CAAC,IAAI,OAAO,CAAC;IACtB,4FAA4F;IAC5F,WAAW,CAAC,IAAI,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;2FAE2F;AAC3F,eAAO,MAAM,aAAa,QAIf,CAAC;AAEZ;gCACgC;AAChC,eAAO,MAAM,6BAA6B,4MACiK,CAAC;AAE5M;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI1F;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAgClB"}
|
|
@@ -81,11 +81,29 @@ export function extractValidated(text, schema) {
|
|
|
81
81
|
}
|
|
82
82
|
return validateValue(parsed, schema);
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
/** The repair prompt for a schema turn that produced no valid JSON (native channels, prose
|
|
85
|
+
* extraction). Sent bare — text only, no re-embedded contract; the schema is in the session's
|
|
86
|
+
* context from the first turn — by the runner's ladder and by `AcpAgent`'s opt-in one. */
|
|
87
|
+
export const REPROMPT_TEXT = [
|
|
85
88
|
"Your previous reply did not return valid JSON matching the required output schema.",
|
|
86
89
|
"Reply now with ONLY a single JSON object that conforms to the schema —",
|
|
87
90
|
"no prose, no explanation, and no markdown code fences.",
|
|
88
91
|
].join(" ");
|
|
92
|
+
/** The repair prompt when the client-hosted StructuredOutput tool is active on the session and
|
|
93
|
+
* the turn did not call it. */
|
|
94
|
+
export const STRUCTURED_TOOL_REPROMPT_TEXT = "You did not call the StructuredOutput tool. Call the StructuredOutput tool now, exactly once, with your final answer as its arguments conforming to its parameter schema. Do not reply with plain text.";
|
|
95
|
+
/**
|
|
96
|
+
* The one repair prompt both ladders send (package-internal; the runner and `AcpAgent` are its
|
|
97
|
+
* only callers): `STRUCTURED_TOOL_REPROMPT_TEXT` when the injected StructuredOutput tool is active
|
|
98
|
+
* for the session, else `REPROMPT_TEXT`; with `reason` (the previous turn's validation failure —
|
|
99
|
+
* `AcpAgentTurn.structuredError`) appended on its own line so the agent corrects against the actual
|
|
100
|
+
* miss, not a guess. The runner passes no reason and sends the bare text.
|
|
101
|
+
*/
|
|
102
|
+
export function repairPromptText(options) {
|
|
103
|
+
const base = options.toolActive ? STRUCTURED_TOOL_REPROMPT_TEXT : REPROMPT_TEXT;
|
|
104
|
+
const reason = options.reason?.trim();
|
|
105
|
+
return reason ? `${base}\n\nValidation error: ${reason}` : base;
|
|
106
|
+
}
|
|
89
107
|
/**
|
|
90
108
|
* Resolve a schema agent's result via the ladder above. Returns the validated value (typed
|
|
91
109
|
* unknown at this layer; the caller casts to the seam's AgentResult<S>). Throws
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1
2
|
import { type Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
3
|
import type { TSchema } from "typebox";
|
|
4
|
+
import { LocalMcpHttpHost } from "./local-mcp-host.js";
|
|
3
5
|
export declare const STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
4
6
|
export declare const STRUCTURED_OUTPUT_SERVER_NAME = "structured_output";
|
|
5
7
|
export declare const STRUCTURED_OUTPUT_TOOL_DESCRIPTION: string;
|
|
@@ -13,18 +15,14 @@ export interface StructuredOutputToolRegistration {
|
|
|
13
15
|
release(): void;
|
|
14
16
|
}
|
|
15
17
|
/** Runner-scoped localhost MCP host. It binds only once a schema run actually needs injection. */
|
|
16
|
-
export declare class StructuredOutputToolHost {
|
|
18
|
+
export declare class StructuredOutputToolHost extends LocalMcpHttpHost {
|
|
19
|
+
protected readonly hostName = "StructuredOutput";
|
|
17
20
|
private readonly slots;
|
|
18
|
-
private server;
|
|
19
|
-
private listenPromise;
|
|
20
|
-
private port;
|
|
21
|
-
isListening(): boolean;
|
|
22
|
-
listeningPort(): number | undefined;
|
|
23
21
|
register(schema: TSchema): Promise<StructuredOutputToolRegistration>;
|
|
24
22
|
dispose(): Promise<void>;
|
|
25
|
-
|
|
26
|
-
private handleRequest;
|
|
27
|
-
private slotFor;
|
|
23
|
+
protected mcpServerFor(token: string): Server | undefined;
|
|
28
24
|
}
|
|
29
25
|
export declare function structuredToolInputSchema(schema: TSchema): Tool["inputSchema"];
|
|
26
|
+
/** The first three typebox validation errors of `value` against `schema`, one line. */
|
|
27
|
+
export declare function describeSchemaErrors(schema: TSchema, value: unknown): string;
|
|
30
28
|
//# sourceMappingURL=structured-tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-tool.d.ts","sourceRoot":"","sources":["../src/structured-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"structured-tool.d.ts","sourceRoot":"","sources":["../src/structured-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAOL,KAAK,IAAI,EACV,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIvD,eAAO,MAAM,2BAA2B,qBAAqB,CAAC;AAC9D,eAAO,MAAM,6BAA6B,sBAAsB,CAAC;AAEjE,eAAO,MAAM,kCAAkC,QAM2C,CAAC;AAS3F,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,2FAA2F;IAC3F,WAAW,IAAI,OAAO,GAAG,SAAS,CAAC;IACnC;2EACuE;IACvE,YAAY,IAAI,OAAO,GAAG,SAAS,CAAC;IACpC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,kGAAkG;AAClG,qBAAa,wBAAyB,SAAQ,gBAAgB;IAC5D,SAAS,CAAC,QAAQ,CAAC,QAAQ,sBAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IAE3C,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,gCAAgC,CAAC;IA6BpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAI1D;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,CAI9E;AAyCD,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAW5E"}
|
package/dist/structured-tool.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import http from "node:http";
|
|
3
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
3
|
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
6
4
|
import { Convert, Errors } from "typebox/value";
|
|
5
|
+
import { LocalMcpHttpHost } from "./local-mcp-host.js";
|
|
7
6
|
import { toJsonSchema } from "./schema-strict.js";
|
|
8
7
|
import { validateValue } from "./structured-output.js";
|
|
9
8
|
export const STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
@@ -14,19 +13,10 @@ export const STRUCTURED_OUTPUT_TOOL_DESCRIPTION = "Use this tool to return your
|
|
|
14
13
|
"- The input must be valid JSON matching the required schema\n" +
|
|
15
14
|
"- Complete all necessary research and tool calls BEFORE calling this tool\n" +
|
|
16
15
|
"- This tool provides your final answer - no further actions are taken after calling it";
|
|
17
|
-
const HOST = "127.0.0.1";
|
|
18
16
|
/** Runner-scoped localhost MCP host. It binds only once a schema run actually needs injection. */
|
|
19
|
-
export class StructuredOutputToolHost {
|
|
17
|
+
export class StructuredOutputToolHost extends LocalMcpHttpHost {
|
|
18
|
+
hostName = "StructuredOutput";
|
|
20
19
|
slots = new Map();
|
|
21
|
-
server;
|
|
22
|
-
listenPromise;
|
|
23
|
-
port;
|
|
24
|
-
isListening() {
|
|
25
|
-
return this.server?.listening === true;
|
|
26
|
-
}
|
|
27
|
-
listeningPort() {
|
|
28
|
-
return this.port;
|
|
29
|
-
}
|
|
30
20
|
async register(schema) {
|
|
31
21
|
const token = randomBytes(16).toString("hex");
|
|
32
22
|
const slot = {
|
|
@@ -39,7 +29,7 @@ export class StructuredOutputToolHost {
|
|
|
39
29
|
try {
|
|
40
30
|
const port = await this.ensureListening();
|
|
41
31
|
return {
|
|
42
|
-
url:
|
|
32
|
+
url: this.urlFor(token, port),
|
|
43
33
|
tryCaptured: () => slot.captured,
|
|
44
34
|
takeCaptured: () => {
|
|
45
35
|
const captured = slot.captured;
|
|
@@ -58,92 +48,11 @@ export class StructuredOutputToolHost {
|
|
|
58
48
|
}
|
|
59
49
|
async dispose() {
|
|
60
50
|
this.slots.clear();
|
|
61
|
-
|
|
62
|
-
this.server = undefined;
|
|
63
|
-
this.listenPromise = undefined;
|
|
64
|
-
this.port = undefined;
|
|
65
|
-
if (!server || !server.listening)
|
|
66
|
-
return;
|
|
67
|
-
await new Promise((resolve, reject) => {
|
|
68
|
-
server.close((error) => (error ? reject(error) : resolve()));
|
|
69
|
-
});
|
|
51
|
+
await this.closeServer();
|
|
70
52
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
void this.handleRequest(req, res);
|
|
75
|
-
});
|
|
76
|
-
this.server.unref();
|
|
77
|
-
}
|
|
78
|
-
if (!this.listenPromise) {
|
|
79
|
-
this.listenPromise = new Promise((resolve, reject) => {
|
|
80
|
-
const server = this.server;
|
|
81
|
-
const onError = (error) => {
|
|
82
|
-
server.off("listening", onListening);
|
|
83
|
-
reject(error);
|
|
84
|
-
};
|
|
85
|
-
const onListening = () => {
|
|
86
|
-
server.off("error", onError);
|
|
87
|
-
const address = server.address();
|
|
88
|
-
if (!address || typeof address === "string") {
|
|
89
|
-
reject(new Error("StructuredOutput MCP server did not bind to a TCP port"));
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
this.port = address.port;
|
|
93
|
-
resolve();
|
|
94
|
-
};
|
|
95
|
-
server.once("error", onError);
|
|
96
|
-
server.once("listening", onListening);
|
|
97
|
-
server.listen(0, HOST);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
await this.listenPromise;
|
|
101
|
-
if (this.port === undefined) {
|
|
102
|
-
throw new Error("StructuredOutput MCP server has no listening port");
|
|
103
|
-
}
|
|
104
|
-
return this.port;
|
|
105
|
-
}
|
|
106
|
-
async handleRequest(req, res) {
|
|
107
|
-
const slot = this.slotFor(req);
|
|
108
|
-
if (!slot) {
|
|
109
|
-
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
110
|
-
res.end("not found");
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
114
|
-
const server = createMcpServer(slot);
|
|
115
|
-
try {
|
|
116
|
-
await server.connect(transport);
|
|
117
|
-
await transport.handleRequest(req, res);
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
if (!res.headersSent) {
|
|
121
|
-
res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
|
|
122
|
-
res.end(error instanceof Error ? error.message : String(error));
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
res.destroy(error instanceof Error ? error : undefined);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
finally {
|
|
129
|
-
await Promise.allSettled([server.close(), transport.close()]);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
slotFor(req) {
|
|
133
|
-
const rawUrl = req.url ?? "/";
|
|
134
|
-
let pathname;
|
|
135
|
-
try {
|
|
136
|
-
pathname = new URL(rawUrl, `http://${HOST}`).pathname;
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
if (!pathname.startsWith("/") || pathname.slice(1).includes("/"))
|
|
142
|
-
return undefined;
|
|
143
|
-
const token = pathname.slice(1);
|
|
144
|
-
if (!token)
|
|
145
|
-
return undefined;
|
|
146
|
-
return this.slots.get(token);
|
|
53
|
+
mcpServerFor(token) {
|
|
54
|
+
const slot = this.slots.get(token);
|
|
55
|
+
return slot ? createMcpServer(slot) : undefined;
|
|
147
56
|
}
|
|
148
57
|
}
|
|
149
58
|
export function structuredToolInputSchema(schema) {
|
|
@@ -182,7 +91,8 @@ function textResult(text, isError) {
|
|
|
182
91
|
...(isError ? { isError: true } : {}),
|
|
183
92
|
};
|
|
184
93
|
}
|
|
185
|
-
|
|
94
|
+
/** The first three typebox validation errors of `value` against `schema`, one line. */
|
|
95
|
+
export function describeSchemaErrors(schema, value) {
|
|
186
96
|
let converted;
|
|
187
97
|
try {
|
|
188
98
|
converted = Convert(schema, value);
|
|
@@ -190,13 +100,15 @@ function rejectionText(value, schema) {
|
|
|
190
100
|
catch {
|
|
191
101
|
converted = value;
|
|
192
102
|
}
|
|
193
|
-
|
|
103
|
+
return Errors(schema, converted)
|
|
194
104
|
.slice(0, 3)
|
|
195
105
|
.map((error) => `${error.instancePath || "/"} ${error.message}`)
|
|
196
106
|
.join("; ");
|
|
107
|
+
}
|
|
108
|
+
function rejectionText(value, schema) {
|
|
197
109
|
return [
|
|
198
110
|
"Structured output rejected: arguments do not match the required schema.",
|
|
199
|
-
|
|
111
|
+
describeSchemaErrors(schema, value),
|
|
200
112
|
"Fix the arguments and call StructuredOutput again.",
|
|
201
113
|
]
|
|
202
114
|
.filter(Boolean)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type SystemPromptOptions } from "@automatalabs/shared-types";
|
|
2
|
+
import type { Backend } from "./backend.js";
|
|
3
|
+
import { type SystemPromptSupport } from "./protocol-coverage.js";
|
|
4
|
+
/** Human summary of a support row for error messages: `replace and append`, `append only`, `none`. */
|
|
5
|
+
export declare function describeSystemPromptSupport(support: SystemPromptSupport): string;
|
|
6
|
+
/**
|
|
7
|
+
* Validate `systemPrompt` for `backend` and return it normalized (only the defined fields, or
|
|
8
|
+
* undefined when nothing was requested). Throws SCRIPT_VALIDATION_ERROR when the value is not a
|
|
9
|
+
* plain object, a field is not a non-blank string, or the backend does not carry a requested
|
|
10
|
+
* field — an unsupported instruction is refused, never silently ignored.
|
|
11
|
+
*/
|
|
12
|
+
export declare function assertSystemPromptSupported(backend: Pick<Backend, "id" | "systemPrompt">, systemPrompt: SystemPromptOptions | undefined, label: string | undefined): SystemPromptOptions | undefined;
|
|
13
|
+
//# sourceMappingURL=system-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoC,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACxG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAe7F,sGAAsG;AACtG,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAKhF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,cAAc,CAAC,EAC7C,YAAY,EAAE,mBAAmB,GAAG,SAAS,EAC7C,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,mBAAmB,GAAG,SAAS,CAoCjC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Backend-neutral system prompt instructions (`SystemPromptOptions`): the one validator every
|
|
2
|
+
// front door runs BEFORE a session opens — `AcpAgentRunner.prepareSession` (run / interactive /
|
|
3
|
+
// reattach), the `AcpAgent` constructor, `agent.fork()`, and the cold statics. The backend maps a
|
|
4
|
+
// validated value onto its own `_meta` dialect in `Backend.sessionMeta`; a backend whose
|
|
5
|
+
// `Backend.systemPrompt` row does not carry a field never receives it, and the caller learns why
|
|
6
|
+
// from a SCRIPT_VALIDATION_ERROR naming the backend, the field, and the escape hatch (`meta`).
|
|
7
|
+
import { WorkflowError, WorkflowErrorCode } from "@automatalabs/shared-types";
|
|
8
|
+
import { SYSTEM_PROMPT_UNSUPPORTED } from "./protocol-coverage.js";
|
|
9
|
+
const SYSTEM_PROMPT_FIELDS = ["replace", "append"];
|
|
10
|
+
function validationError(message, label) {
|
|
11
|
+
return new WorkflowError(message, WorkflowErrorCode.SCRIPT_VALIDATION_ERROR, {
|
|
12
|
+
recoverable: false,
|
|
13
|
+
agentLabel: label,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
/** Human summary of a support row for error messages: `replace and append`, `append only`, `none`. */
|
|
20
|
+
export function describeSystemPromptSupport(support) {
|
|
21
|
+
const supported = SYSTEM_PROMPT_FIELDS.filter((field) => support[field]);
|
|
22
|
+
if (supported.length === 0)
|
|
23
|
+
return "none";
|
|
24
|
+
if (supported.length === SYSTEM_PROMPT_FIELDS.length)
|
|
25
|
+
return supported.join(" and ");
|
|
26
|
+
return `${supported.join(", ")} only`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate `systemPrompt` for `backend` and return it normalized (only the defined fields, or
|
|
30
|
+
* undefined when nothing was requested). Throws SCRIPT_VALIDATION_ERROR when the value is not a
|
|
31
|
+
* plain object, a field is not a non-blank string, or the backend does not carry a requested
|
|
32
|
+
* field — an unsupported instruction is refused, never silently ignored.
|
|
33
|
+
*/
|
|
34
|
+
export function assertSystemPromptSupported(backend, systemPrompt, label) {
|
|
35
|
+
if (systemPrompt === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
const prefix = `Agent call${label ? ` "${label}"` : ""}`;
|
|
38
|
+
if (!isRecord(systemPrompt)) {
|
|
39
|
+
throw validationError(`${prefix} systemPrompt must be an object with optional string fields replace / append`, label);
|
|
40
|
+
}
|
|
41
|
+
const unknown = Object.keys(systemPrompt).filter((key) => !SYSTEM_PROMPT_FIELDS.includes(key));
|
|
42
|
+
if (unknown.length > 0) {
|
|
43
|
+
throw validationError(`${prefix} systemPrompt has unknown field${unknown.length > 1 ? "s" : ""} ${unknown.map((key) => `"${key}"`).join(", ")}; only replace / append are accepted (a backend's own extras go through meta)`, label);
|
|
44
|
+
}
|
|
45
|
+
const normalized = {};
|
|
46
|
+
for (const field of SYSTEM_PROMPT_FIELDS) {
|
|
47
|
+
const value = systemPrompt[field];
|
|
48
|
+
if (value === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
51
|
+
throw validationError(`${prefix} systemPrompt.${field} must be a non-empty string`, label);
|
|
52
|
+
}
|
|
53
|
+
normalized[field] = value;
|
|
54
|
+
}
|
|
55
|
+
const requested = SYSTEM_PROMPT_FIELDS.filter((field) => normalized[field] !== undefined);
|
|
56
|
+
if (requested.length === 0)
|
|
57
|
+
return undefined;
|
|
58
|
+
const support = backend.systemPrompt ?? SYSTEM_PROMPT_UNSUPPORTED;
|
|
59
|
+
const refused = requested.filter((field) => !support[field]);
|
|
60
|
+
if (refused.length > 0) {
|
|
61
|
+
throw validationError(`${prefix} systemPrompt.${refused.join(" / ")} is not supported by backend "${backend.id}" (supported: ${describeSystemPromptSupport(support)}); ` +
|
|
62
|
+
(support.replace || support.append
|
|
63
|
+
? "use a supported field"
|
|
64
|
+
: "this backend exposes no ACP system-prompt channel — drive its own configuration, or send its vendor `_meta` keys through the meta passthrough"), label);
|
|
65
|
+
}
|
|
66
|
+
return normalized;
|
|
67
|
+
}
|
package/dist/traits.d.ts
ADDED
|
@@ -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"}
|