@sweny-ai/core 0.1.148 → 0.1.149
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/cli/config.js +6 -3
- package/dist/harness/acp-rpc.d.ts +75 -0
- package/dist/harness/acp-rpc.js +204 -0
- package/dist/harness/acp.d.ts +189 -0
- package/dist/harness/acp.js +942 -0
- package/dist/harness/agents.d.ts +5 -1
- package/dist/harness/agents.js +8 -1
- package/dist/harness/capabilities.d.ts +30 -0
- package/dist/harness/capabilities.js +41 -0
- package/dist/harness/index.d.ts +7 -3
- package/dist/harness/index.js +7 -2
- package/dist/harness/parse.d.ts +12 -0
- package/dist/harness/parse.js +1 -1
- package/package.json +1 -1
package/dist/harness/agents.d.ts
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare const SUPPORTED_AGENTS: readonly ["claude", "codex", "pi"];
|
|
8
8
|
export type SupportedAgent = (typeof SUPPORTED_AGENTS)[number];
|
|
9
|
-
|
|
9
|
+
/** `acp:<command>` (#416): any Agent Client Protocol agent, started with `<command>`. */
|
|
10
|
+
export type AcpAgentId = `acp:${string}`;
|
|
11
|
+
/** The command of an `acp:<command>` agent id (`"opencode acp"` for `acp:opencode acp`), or undefined when it is not one or the command is empty. */
|
|
12
|
+
export declare function parseAcpAgent(id: string): string | undefined;
|
|
13
|
+
export declare function isSupportedAgent(id: string): id is SupportedAgent | AcpAgentId;
|
|
10
14
|
/** The error for an agent id with no adapter. */
|
|
11
15
|
export declare function unsupportedAgentError(id: string): string;
|
package/dist/harness/agents.js
CHANGED
|
@@ -5,8 +5,15 @@
|
|
|
5
5
|
* the harness factory share it).
|
|
6
6
|
*/
|
|
7
7
|
export const SUPPORTED_AGENTS = ["claude", "codex", "pi"];
|
|
8
|
+
/** The command of an `acp:<command>` agent id (`"opencode acp"` for `acp:opencode acp`), or undefined when it is not one or the command is empty. */
|
|
9
|
+
export function parseAcpAgent(id) {
|
|
10
|
+
if (!id.startsWith("acp:"))
|
|
11
|
+
return undefined;
|
|
12
|
+
const command = id.slice("acp:".length).trim();
|
|
13
|
+
return command === "" ? undefined : command;
|
|
14
|
+
}
|
|
8
15
|
export function isSupportedAgent(id) {
|
|
9
|
-
return SUPPORTED_AGENTS.includes(id);
|
|
16
|
+
return SUPPORTED_AGENTS.includes(id) || parseAcpAgent(id) !== undefined;
|
|
10
17
|
}
|
|
11
18
|
/** The error for an agent id with no adapter. */
|
|
12
19
|
export function unsupportedAgentError(id) {
|
|
@@ -56,3 +56,33 @@ export declare const CODEX_CAPABILITIES: HarnessCapabilities;
|
|
|
56
56
|
* - cancel rpc: the `abort` command, then SIGTERM and SIGKILL.
|
|
57
57
|
*/
|
|
58
58
|
export declare const PI_CAPABILITIES: HarnessCapabilities;
|
|
59
|
+
/**
|
|
60
|
+
* Any ACP agent (`--agent acp:<command>`, #416), declared from the Agent
|
|
61
|
+
* Client Protocol schema v1.24.1 (agentclientprotocol/agent-client-protocol,
|
|
62
|
+
* `schema/v1/schema.json`, docs under `docs/protocol/v1/`) and probed by the
|
|
63
|
+
* contract suite against a scripted fake agent. ACP is the long-tail adapter:
|
|
64
|
+
* the protocol carries a prompt and a stream of updates, not sweny's opinions.
|
|
65
|
+
* - structuredOutput prompt: `PromptResponse` has only `stopReason`, so there
|
|
66
|
+
* is no schema channel. sweny asks for the JSON in the prompt, parses it,
|
|
67
|
+
* checks it and retries once.
|
|
68
|
+
* - toolTrace full: `tool_call` and `tool_call_update` session updates carry an
|
|
69
|
+
* id, a kind, a status and (optionally) raw input and content.
|
|
70
|
+
* - builtinDeny none: the protocol has no tool allow or deny list. The only
|
|
71
|
+
* hook is `session/request_permission`, which fires only when the agent
|
|
72
|
+
* chooses to ask. sweny answers it by policy (best effort), but cannot
|
|
73
|
+
* promise the agent asks, so nothing is declared.
|
|
74
|
+
* - mcp inject, exclusive none: `session/new` takes `mcpServers`, but whether
|
|
75
|
+
* the agent also loads its own MCP config is agent-defined.
|
|
76
|
+
* - sandbox none: nothing in the protocol. The process wrapper (srt) is the
|
|
77
|
+
* only containment, see sandbox-wrapper.ts.
|
|
78
|
+
* - readOnly none: modes are agent-defined. `policyGate` counts read-only as
|
|
79
|
+
* enforced only with the wrapper's read-only mount.
|
|
80
|
+
* - turnLimit watchdog: no turn limit in the protocol; sweny counts tool calls.
|
|
81
|
+
* - usage costUsd only: `usage_update {used, size, cost?}` is the stable
|
|
82
|
+
* usage. `used` and `size` are context window occupancy, not billed tokens,
|
|
83
|
+
* so they are not mapped; `cost` (cumulative, ISO 4217 currency) is, when it
|
|
84
|
+
* is USD. Per-turn token usage is behind an unstable flag.
|
|
85
|
+
* - cancel rpc: `session/cancel`, then kill.
|
|
86
|
+
* - resume false: sweny starts a fresh session per node.
|
|
87
|
+
*/
|
|
88
|
+
export declare const ACP_CAPABILITIES: HarnessCapabilities;
|
|
@@ -90,3 +90,44 @@ export const PI_CAPABILITIES = {
|
|
|
90
90
|
cancel: "rpc",
|
|
91
91
|
resume: false,
|
|
92
92
|
};
|
|
93
|
+
/**
|
|
94
|
+
* Any ACP agent (`--agent acp:<command>`, #416), declared from the Agent
|
|
95
|
+
* Client Protocol schema v1.24.1 (agentclientprotocol/agent-client-protocol,
|
|
96
|
+
* `schema/v1/schema.json`, docs under `docs/protocol/v1/`) and probed by the
|
|
97
|
+
* contract suite against a scripted fake agent. ACP is the long-tail adapter:
|
|
98
|
+
* the protocol carries a prompt and a stream of updates, not sweny's opinions.
|
|
99
|
+
* - structuredOutput prompt: `PromptResponse` has only `stopReason`, so there
|
|
100
|
+
* is no schema channel. sweny asks for the JSON in the prompt, parses it,
|
|
101
|
+
* checks it and retries once.
|
|
102
|
+
* - toolTrace full: `tool_call` and `tool_call_update` session updates carry an
|
|
103
|
+
* id, a kind, a status and (optionally) raw input and content.
|
|
104
|
+
* - builtinDeny none: the protocol has no tool allow or deny list. The only
|
|
105
|
+
* hook is `session/request_permission`, which fires only when the agent
|
|
106
|
+
* chooses to ask. sweny answers it by policy (best effort), but cannot
|
|
107
|
+
* promise the agent asks, so nothing is declared.
|
|
108
|
+
* - mcp inject, exclusive none: `session/new` takes `mcpServers`, but whether
|
|
109
|
+
* the agent also loads its own MCP config is agent-defined.
|
|
110
|
+
* - sandbox none: nothing in the protocol. The process wrapper (srt) is the
|
|
111
|
+
* only containment, see sandbox-wrapper.ts.
|
|
112
|
+
* - readOnly none: modes are agent-defined. `policyGate` counts read-only as
|
|
113
|
+
* enforced only with the wrapper's read-only mount.
|
|
114
|
+
* - turnLimit watchdog: no turn limit in the protocol; sweny counts tool calls.
|
|
115
|
+
* - usage costUsd only: `usage_update {used, size, cost?}` is the stable
|
|
116
|
+
* usage. `used` and `size` are context window occupancy, not billed tokens,
|
|
117
|
+
* so they are not mapped; `cost` (cumulative, ISO 4217 currency) is, when it
|
|
118
|
+
* is USD. Per-turn token usage is behind an unstable flag.
|
|
119
|
+
* - cancel rpc: `session/cancel`, then kill.
|
|
120
|
+
* - resume false: sweny starts a fresh session per node.
|
|
121
|
+
*/
|
|
122
|
+
export const ACP_CAPABILITIES = {
|
|
123
|
+
structuredOutput: "prompt",
|
|
124
|
+
toolTrace: "full",
|
|
125
|
+
builtinDeny: "none",
|
|
126
|
+
mcp: { inject: true, exclusive: "none" },
|
|
127
|
+
sandbox: { fs: false, network: false },
|
|
128
|
+
readOnly: "none",
|
|
129
|
+
turnLimit: "watchdog",
|
|
130
|
+
usage: { tokens: false, costUsd: true, live: false },
|
|
131
|
+
cancel: "rpc",
|
|
132
|
+
resume: false,
|
|
133
|
+
};
|
package/dist/harness/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { ClaudeCodeHarness, type ClaudeCodeHarnessOptions } from "./claude-code.js";
|
|
6
6
|
import { CodexHarness, type CodexHarnessOptions } from "./codex.js";
|
|
7
|
+
import { AcpHarness, type AcpHarnessOptions } from "./acp.js";
|
|
7
8
|
import { PiHarness, type PiHarnessOptions } from "./pi.js";
|
|
8
9
|
export { claudeCompat, asClaude } from "./compat.js";
|
|
9
10
|
export type { AgentHarness, HarnessCapabilities, HarnessCompleteRequest, HarnessId, HarnessInfo, HarnessRunRequest, HarnessRunResult, NodePolicy, PolicyGateResult, PolicyWrappers, ToolClass, } from "./types.js";
|
|
@@ -14,12 +15,14 @@ export { ClaudeCodeHarness, CLAUDE_CODE_CAPABILITIES } from "./claude-code.js";
|
|
|
14
15
|
export type { ClaudeCodeHarnessOptions } from "./claude-code.js";
|
|
15
16
|
export { CodexHarness, CODEX_CAPABILITIES, MIN_CODEX_VERSION } from "./codex.js";
|
|
16
17
|
export type { CodexHarnessOptions } from "./codex.js";
|
|
18
|
+
export { AcpHarness, ACP_CAPABILITIES, ACP_PROTOCOL_VERSION } from "./acp.js";
|
|
19
|
+
export type { AcpHarnessOptions } from "./acp.js";
|
|
17
20
|
export { PiHarness, PI_CAPABILITIES, MIN_PI_VERSION } from "./pi.js";
|
|
18
21
|
export type { PiHarnessOptions } from "./pi.js";
|
|
19
22
|
export { startToolBridge } from "./tool-bridge/server.js";
|
|
20
23
|
export type { ToolBridge, ToolBridgeOptions } from "./tool-bridge/server.js";
|
|
21
|
-
export { SUPPORTED_AGENTS, isSupportedAgent, unsupportedAgentError } from "./agents.js";
|
|
22
|
-
export type { SupportedAgent } from "./agents.js";
|
|
24
|
+
export { SUPPORTED_AGENTS, isSupportedAgent, parseAcpAgent, unsupportedAgentError } from "./agents.js";
|
|
25
|
+
export type { AcpAgentId, SupportedAgent } from "./agents.js";
|
|
23
26
|
/**
|
|
24
27
|
* Build the harness for an agent id. `claude` is the historical `--agent` /
|
|
25
28
|
* `coding-agent-provider` value and means the same as `claude-code`.
|
|
@@ -28,4 +31,5 @@ export type { SupportedAgent } from "./agents.js";
|
|
|
28
31
|
export declare function createHarness(id: "claude" | "claude-code", opts?: ClaudeCodeHarnessOptions): ClaudeCodeHarness;
|
|
29
32
|
export declare function createHarness(id: "codex", opts?: CodexHarnessOptions): CodexHarness;
|
|
30
33
|
export declare function createHarness(id: "pi", opts?: PiHarnessOptions): PiHarness;
|
|
31
|
-
export declare function createHarness(id: string
|
|
34
|
+
export declare function createHarness(id: `acp:${string}`, opts?: AcpHarnessOptions): AcpHarness;
|
|
35
|
+
export declare function createHarness(id: string, opts?: ClaudeCodeHarnessOptions & CodexHarnessOptions & PiHarnessOptions & AcpHarnessOptions): ClaudeCodeHarness | CodexHarness | PiHarness | AcpHarness;
|
package/dist/harness/index.js
CHANGED
|
@@ -4,17 +4,22 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { ClaudeCodeHarness } from "./claude-code.js";
|
|
6
6
|
import { CodexHarness } from "./codex.js";
|
|
7
|
+
import { AcpHarness } from "./acp.js";
|
|
7
8
|
import { PiHarness } from "./pi.js";
|
|
8
|
-
import { unsupportedAgentError } from "./agents.js";
|
|
9
|
+
import { parseAcpAgent, unsupportedAgentError } from "./agents.js";
|
|
9
10
|
export { claudeCompat, asClaude } from "./compat.js";
|
|
10
11
|
export { policyGate, nativeDenyClasses, resolveHarnessPolicy, isToolClass, TOOL_CLASSES } from "./policy.js";
|
|
11
12
|
export { ask, evaluate, buildAskPrompt, buildEvaluatePrompt } from "./prompts.js";
|
|
12
13
|
export { ClaudeCodeHarness, CLAUDE_CODE_CAPABILITIES } from "./claude-code.js";
|
|
13
14
|
export { CodexHarness, CODEX_CAPABILITIES, MIN_CODEX_VERSION } from "./codex.js";
|
|
15
|
+
export { AcpHarness, ACP_CAPABILITIES, ACP_PROTOCOL_VERSION } from "./acp.js";
|
|
14
16
|
export { PiHarness, PI_CAPABILITIES, MIN_PI_VERSION } from "./pi.js";
|
|
15
17
|
export { startToolBridge } from "./tool-bridge/server.js";
|
|
16
|
-
export { SUPPORTED_AGENTS, isSupportedAgent, unsupportedAgentError } from "./agents.js";
|
|
18
|
+
export { SUPPORTED_AGENTS, isSupportedAgent, parseAcpAgent, unsupportedAgentError } from "./agents.js";
|
|
17
19
|
export function createHarness(id, opts = {}) {
|
|
20
|
+
// `acp:<command>` (#416): any ACP agent. An empty command is an error, not a fallback.
|
|
21
|
+
if (id.startsWith("acp:"))
|
|
22
|
+
return new AcpHarness({ ...opts, acpCommand: parseAcpAgent(id) ?? "" });
|
|
18
23
|
switch (id) {
|
|
19
24
|
case "claude":
|
|
20
25
|
case "claude-code":
|
package/dist/harness/parse.d.ts
CHANGED
|
@@ -47,3 +47,15 @@ export declare function summarizeToolError(parsed: unknown): string;
|
|
|
47
47
|
* non-conforming model answer is at least attributable.
|
|
48
48
|
*/
|
|
49
49
|
export declare function tryParseJSON(text: string, outputSchema?: JSONSchema, logger?: Pick<Logger, "warn">, label?: string): Record<string, unknown>;
|
|
50
|
+
/**
|
|
51
|
+
* Lightweight structural check of a parsed object against a JSON Schema.
|
|
52
|
+
*
|
|
53
|
+
* Deliberately shallow: it verifies `required` keys are present and that the
|
|
54
|
+
* top-level `type` and each declared property `type` match. It does NOT do
|
|
55
|
+
* full JSON Schema validation (no `$ref`, `oneOf`, formats, nested arrays).
|
|
56
|
+
* The contract here is "flag an obviously non-conforming object" so a mismatch
|
|
57
|
+
* is logged rather than silently accepted; it is not a validation gate.
|
|
58
|
+
*
|
|
59
|
+
* Returns a list of human-readable problems; empty means no detected mismatch.
|
|
60
|
+
*/
|
|
61
|
+
export declare function schemaMismatches(value: unknown, schema: JSONSchema): string[];
|
package/dist/harness/parse.js
CHANGED
|
@@ -195,7 +195,7 @@ export function tryParseJSON(text, outputSchema, logger, label = "Claude") {
|
|
|
195
195
|
*
|
|
196
196
|
* Returns a list of human-readable problems; empty means no detected mismatch.
|
|
197
197
|
*/
|
|
198
|
-
function schemaMismatches(value, schema) {
|
|
198
|
+
export function schemaMismatches(value, schema) {
|
|
199
199
|
const problems = [];
|
|
200
200
|
const s = schema;
|
|
201
201
|
if (s.type === "object" || s.properties || s.required) {
|