@sweny-ai/core 0.1.148 → 0.1.150
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/builtin-workflows.d.ts +45 -0
- package/dist/cli/builtin-workflows.js +129 -0
- package/dist/cli/check.d.ts +2 -8
- package/dist/cli/check.js +2 -34
- package/dist/cli/config.js +8 -3
- package/dist/cli/main.js +46 -11
- package/dist/cli/packs.d.ts +9 -5
- package/dist/cli/packs.js +100 -50
- package/dist/executor.js +15 -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/auth.d.ts +38 -0
- package/dist/harness/auth.js +93 -0
- package/dist/harness/capabilities.d.ts +30 -0
- package/dist/harness/capabilities.js +41 -0
- package/dist/harness/claude-code.d.ts +8 -0
- package/dist/harness/claude-code.js +8 -1
- package/dist/harness/codex.d.ts +10 -1
- package/dist/harness/codex.js +17 -3
- 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/dist/harness/policy.js +6 -0
- package/dist/harness/types.d.ts +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/node-policy.js +1 -0
- package/dist/safe-outputs.d.ts +17 -5
- package/dist/safe-outputs.js +85 -11
- package/dist/schema.d.ts +80 -0
- package/dist/schema.js +23 -0
- package/dist/types.d.ts +13 -0
- package/dist/workflows/browser.js +2 -2
- package/dist/workflows/implement.yml +61 -19
- package/dist/workflows/triage.yml +171 -139
- package/package.json +1 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP harness (#416): runs a node on any Agent Client Protocol agent
|
|
3
|
+
* (`--agent acp:<command>`, for example `acp:opencode acp`,
|
|
4
|
+
* `acp:hermes acp`, `acp:goose acp`, `acp:gemini --experimental-acp`).
|
|
5
|
+
*
|
|
6
|
+
* ACP is the long-tail adapter. It is JSON-RPC 2.0 over the agent's stdio and
|
|
7
|
+
* carries a prompt and a stream of updates; it does not carry sweny's
|
|
8
|
+
* opinions. Read from agentclientprotocol/agent-client-protocol at tag
|
|
9
|
+
* schema-v1.24.1 (`schema/v1/schema.json`, `docs/protocol/v1/*.mdx`):
|
|
10
|
+
* - transports: newline-delimited JSON over stdio (`transports.mdx`).
|
|
11
|
+
* - `initialize` negotiates `protocolVersion` (1) and capabilities
|
|
12
|
+
* (`initialization.mdx`); `InitializeRequest` / `InitializeResponse`.
|
|
13
|
+
* - `session/new {cwd, mcpServers}` returns `{sessionId}`; every agent MUST
|
|
14
|
+
* support stdio MCP servers, http and sse are optional
|
|
15
|
+
* (`session-setup.mdx`, `McpServerStdio`, `McpServerHttp`).
|
|
16
|
+
* - `session/prompt {sessionId, prompt: ContentBlock[]}` streams
|
|
17
|
+
* `session/update` notifications (`agent_message_chunk`, `tool_call`,
|
|
18
|
+
* `tool_call_update`, `usage_update`, ...) and ends with
|
|
19
|
+
* `{stopReason}`; `PromptResponse` has no other field (`prompt-turn.mdx`).
|
|
20
|
+
* - `session/cancel` (notification) ends a turn with stopReason `cancelled`
|
|
21
|
+
* (`prompt-turn.mdx`, Cancellation); pending permission requests get the
|
|
22
|
+
* `cancelled` outcome.
|
|
23
|
+
* - `session/request_permission {toolCall, options}` is how an agent MAY ask
|
|
24
|
+
* before a tool runs; the client picks an option or answers `cancelled`
|
|
25
|
+
* (`tool-calls.mdx`, `RequestPermissionResponse`).
|
|
26
|
+
* - `fs/read_text_file` and `fs/write_text_file` are client methods an agent
|
|
27
|
+
* may use only when the client advertised them (`file-system.mdx`).
|
|
28
|
+
*
|
|
29
|
+
* Every sweny opinion is enforced by sweny here, refused or reported as
|
|
30
|
+
* `degraded` by `policyGate` (see ACP_CAPABILITIES for the honest list):
|
|
31
|
+
* - Structured output: the schema rides in the prompt; sweny parses the last
|
|
32
|
+
* JSON object, checks it and asks once more before giving up.
|
|
33
|
+
* - Tool deny and read-only: best effort through `session/request_permission`
|
|
34
|
+
* (denied classes and every non-read tool under `readOnly` are rejected),
|
|
35
|
+
* plus a refusal of every `fs/write_text_file`. The protocol has no deny list
|
|
36
|
+
* and an agent that does not ask is not stopped, so `policyGate` still
|
|
37
|
+
* reports deny and read-only as unenforced; strict refuses the node unless
|
|
38
|
+
* the process wrapper provides the read-only mount.
|
|
39
|
+
* - Sandbox and egress: none in the protocol. The whole agent process runs
|
|
40
|
+
* inside the sandbox wrapper (sandbox-wrapper.ts); strict refuses without it.
|
|
41
|
+
* - Env: sweny spawns the agent with the scoped env (agent-env.ts).
|
|
42
|
+
* - Skill tools: passed in `session/new` as the stdio MCP server of the tool
|
|
43
|
+
* bridge (#414), so the executor still observes every call.
|
|
44
|
+
* - Turn limit: a watchdog counts tool calls and cancels past the budget.
|
|
45
|
+
* - Timeout: `session/cancel`, a grace period, then the process is killed.
|
|
46
|
+
*/
|
|
47
|
+
import type { Logger, McpServerConfig, ToolContext } from "../types.js";
|
|
48
|
+
import { type SandboxMode } from "../agent-env.js";
|
|
49
|
+
import type { AgentHarness, HarnessCapabilities, HarnessCompleteRequest, HarnessId, HarnessInfo, HarnessRunRequest, HarnessRunResult, ToolClass } from "./types.js";
|
|
50
|
+
import { ACP_CAPABILITIES } from "./capabilities.js";
|
|
51
|
+
import { type HarnessPolicyMode } from "./policy.js";
|
|
52
|
+
import { type SandboxWrapper } from "./sandbox-wrapper.js";
|
|
53
|
+
export { ACP_CAPABILITIES };
|
|
54
|
+
/** The ACP major version sweny speaks (`InitializeRequest.protocolVersion`). */
|
|
55
|
+
export declare const ACP_PROTOCOL_VERSION = 1;
|
|
56
|
+
export interface AcpHarnessOptions {
|
|
57
|
+
/**
|
|
58
|
+
* The agent to run: a command line (`"opencode acp"`, the part after `acp:`)
|
|
59
|
+
* or an explicit `{command, args}`. Never run through a shell.
|
|
60
|
+
*/
|
|
61
|
+
acpCommand?: string | {
|
|
62
|
+
command: string;
|
|
63
|
+
args: string[];
|
|
64
|
+
};
|
|
65
|
+
/** Tool-call budget the watchdog enforces when a node sets no `max_turns` (default: 20). */
|
|
66
|
+
maxTurns?: number;
|
|
67
|
+
/** Working directory (default: process.cwd()). */
|
|
68
|
+
cwd?: string;
|
|
69
|
+
logger?: Logger;
|
|
70
|
+
/** Default tool context for standalone usage (not via the executor). */
|
|
71
|
+
defaultContext?: ToolContext;
|
|
72
|
+
/** Catalog defaults, overridden by per-run skill servers and explicit mcpServers. */
|
|
73
|
+
defaultMcpServers?: Record<string, McpServerConfig>;
|
|
74
|
+
/** Explicit external MCP servers, overriding defaults and per-run skill servers. */
|
|
75
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
76
|
+
/** Extra env var names passed through (see agent-env.ts). Default: `SWENY_ENV_PASSTHROUGH`. */
|
|
77
|
+
envPassthrough?: string[];
|
|
78
|
+
/** The agent's own auth env var names, always passed through when scoping (none are assumed). */
|
|
79
|
+
authVars?: string[];
|
|
80
|
+
/** Scope the agent env to the allowlist. Default: `SWENY_ENV_SCOPE`, else on in CI. */
|
|
81
|
+
envScope?: boolean;
|
|
82
|
+
/** Process sandbox mode. Default: `SWENY_SANDBOX`, else `auto` in CI and `off` locally. */
|
|
83
|
+
sandbox?: SandboxMode;
|
|
84
|
+
/** The host's process sandbox wrapper (#360 step 2). `undefined` = detect srt once per process; `null` = none (test seam). */
|
|
85
|
+
sandboxWrapper?: SandboxWrapper | null;
|
|
86
|
+
/** `strict` refuses a node with unenforceable opinions. Default: {@link resolveHarnessPolicy}. */
|
|
87
|
+
policy?: HarnessPolicyMode;
|
|
88
|
+
/** Hosts the agent itself needs (its model API), allowed through the sandbox wrapper. */
|
|
89
|
+
egress?: string[];
|
|
90
|
+
/** Shim command override for the tool bridge (test seam). */
|
|
91
|
+
toolBridgeShim?: {
|
|
92
|
+
command: string;
|
|
93
|
+
args: string[];
|
|
94
|
+
};
|
|
95
|
+
/** Grace period between SIGTERM and SIGKILL, and for the agent to exit on its own (default: 2000 ms). */
|
|
96
|
+
killGraceMs?: number;
|
|
97
|
+
/** How long the agent gets to answer `session/cancel` before it is killed (default: 5000 ms). */
|
|
98
|
+
cancelGraceMs?: number;
|
|
99
|
+
/** How long `initialize` and `session/new` may take (default: 60000 ms). */
|
|
100
|
+
startupTimeoutMs?: number;
|
|
101
|
+
}
|
|
102
|
+
/** Portable tool classes an ACP tool call can be, from its `kind` (schema `ToolKind`) and name. */
|
|
103
|
+
export declare function classifyAcpTool(kind: string | null | undefined, name: string | null | undefined): {
|
|
104
|
+
classes: ToolClass[];
|
|
105
|
+
readOnlySafe: boolean;
|
|
106
|
+
};
|
|
107
|
+
/** Does this tool call name one of sweny's skill tools (they reach the agent as MCP tools of the tool bridge)? */
|
|
108
|
+
export declare function isSkillToolCall(names: readonly (string | null | undefined)[], skillTools: readonly string[]): boolean;
|
|
109
|
+
interface PermissionOption {
|
|
110
|
+
optionId: string;
|
|
111
|
+
kind: string;
|
|
112
|
+
}
|
|
113
|
+
/** The permission outcome for an option list: the first option of a wanted kind, else `cancelled`. */
|
|
114
|
+
export declare function pickPermissionOutcome(options: readonly PermissionOption[], allow: boolean): {
|
|
115
|
+
outcome: "selected";
|
|
116
|
+
optionId: string;
|
|
117
|
+
} | {
|
|
118
|
+
outcome: "cancelled";
|
|
119
|
+
};
|
|
120
|
+
/** A loosely typed JSON object, for reading what the agent sends. */
|
|
121
|
+
type Obj = Record<string, any>;
|
|
122
|
+
/** `McpServerConfig` map to the ACP `mcpServers` array (schema `McpServer`). Returns what the agent cannot load too. */
|
|
123
|
+
export declare function toAcpMcpServers(servers: Record<string, McpServerConfig>, agentHttp: boolean): {
|
|
124
|
+
list: Obj[];
|
|
125
|
+
unsupported: string[];
|
|
126
|
+
};
|
|
127
|
+
export declare class AcpHarness implements AgentHarness {
|
|
128
|
+
readonly id: HarnessId;
|
|
129
|
+
readonly capabilities: HarnessCapabilities;
|
|
130
|
+
/** Empty on purpose: judges use the agent's own default model. */
|
|
131
|
+
readonly defaultJudgeModel = "";
|
|
132
|
+
readonly logger: Logger;
|
|
133
|
+
private agent;
|
|
134
|
+
private maxTurns;
|
|
135
|
+
private cwd;
|
|
136
|
+
private defaultContext;
|
|
137
|
+
private mcpServers;
|
|
138
|
+
private defaultMcpServers;
|
|
139
|
+
private envPassthrough;
|
|
140
|
+
private authVars;
|
|
141
|
+
private envScope;
|
|
142
|
+
private sandboxMode;
|
|
143
|
+
private sandboxWrapper;
|
|
144
|
+
private policyMode;
|
|
145
|
+
private egress;
|
|
146
|
+
private toolBridgeShim;
|
|
147
|
+
private killGraceMs;
|
|
148
|
+
private cancelGraceMs;
|
|
149
|
+
private startupTimeoutMs;
|
|
150
|
+
private agentVersion;
|
|
151
|
+
constructor(opts?: AcpHarnessOptions);
|
|
152
|
+
info(): HarnessInfo;
|
|
153
|
+
/**
|
|
154
|
+
* Is the agent command there? Deliberately does not start it: it would run
|
|
155
|
+
* outside the sandbox wrapper. The version comes from `initialize` on the
|
|
156
|
+
* first run (`agentInfo.version`).
|
|
157
|
+
*/
|
|
158
|
+
preflight(): Promise<{
|
|
159
|
+
ok: true;
|
|
160
|
+
version: string;
|
|
161
|
+
} | {
|
|
162
|
+
ok: false;
|
|
163
|
+
reason: string;
|
|
164
|
+
}>;
|
|
165
|
+
/** Env for the agent process: scoped like Claude Code's, with only the auth vars the operator named. */
|
|
166
|
+
private buildEnv;
|
|
167
|
+
/** The node policy, with the harness policy mode and the watchdog budget applied. */
|
|
168
|
+
private compilePolicy;
|
|
169
|
+
/**
|
|
170
|
+
* Talk to one agent process from `initialize` to the last `session/prompt`
|
|
171
|
+
* response, then stop it. Never throws: every failure is on the result.
|
|
172
|
+
*/
|
|
173
|
+
private converse;
|
|
174
|
+
/**
|
|
175
|
+
* Run a node. The gate runs first: in strict mode a node whose opinions an
|
|
176
|
+
* ACP agent cannot honor is refused before the agent starts. The agent
|
|
177
|
+
* process runs inside the host's sandbox wrapper (#360 step 2) when the
|
|
178
|
+
* sandbox mode asks for one and the host has one.
|
|
179
|
+
*/
|
|
180
|
+
run(req: HarnessRunRequest): Promise<HarnessRunResult>;
|
|
181
|
+
/** Map one conversation onto a NodeResult with Claude Code's semantics. */
|
|
182
|
+
private toResult;
|
|
183
|
+
/**
|
|
184
|
+
* One completion: a fresh session with no MCP servers, every permission
|
|
185
|
+
* request rejected, and any tool call over budget. null when it failed
|
|
186
|
+
* (callers fail closed).
|
|
187
|
+
*/
|
|
188
|
+
complete(req: HarnessCompleteRequest): Promise<string | null>;
|
|
189
|
+
}
|