Add an ACP harness
Goal: make a command-line agent that supports the Agent Client Protocol (ACP) available as a SoduWork harness.
A program that already speaks standard ACP reuses SoduWork's discovery, dispatch, event handling, file delivery and session resume. You add one declaration; the core dispatch code doesn't change.
1. Add a declaration
Add an entry to the agents array in hub-backend/app/agent_catalog.json:
{
"id": "sample-acp",
"displayName": "Sample Agent",
"transport": "runner",
"modelMode": "managed",
"goalMode": "none",
"group": "more",
"order": 80,
"summary": "Runs tasks over ACP",
"accessControl": {
"schema": "soduwork.access-policy/v1",
"supported": false,
"modes": [],
"approval": "",
"sandbox": false
},
"runner": {
"adapter": "acp",
"bins": ["sample-agent"],
"args": ["--acp"],
"home": { "env": "SAMPLE_AGENT_HOME", "folder": ".sample-agent" },
"modelEnv": {
"OPENAI_BASE_URL": "base",
"OPENAI_API_KEY": "key",
"OPENAI_MODEL": "model"
}
},
"install": {
"installer": "manual",
"source": "Install by following the vendor's instructions",
"blurb": "Install the command-line version with ACP support",
"install_how": "Install sample-agent and make sure it runs from PATH."
}
}
This declaration doesn't install anything. Install the program yourself on each computer or runner that will use it.
Fields
| Field | Rule |
|---|---|
id | Starts with a lowercase letter; up to 40 lowercase letters, digits or hyphens; unique |
displayName, summary | Shown as plain text, never as HTML |
transport | runner. direct is reserved for Pi |
modelMode | managed uses SoduWork models; account uses the program's own sign-in and receives no organization model settings |
goalMode | native or none |
group, order | Where it appears in the harness picker: recommended or more |
accessControl.supported | true only if the program really supports the standard, read-only and full access modes. Then modes must be ["standard", "readonly", "full"]; otherwise [] and the UI shows compatible access. Changing the declaration alone doesn't give a program a sandbox or approvals |
runner.adapter | acp for this kind of program |
runner.bins | Executable names to look for, for example ["sample-agent", "sample-agent.cmd", "sample-agent.exe"] |
runner.args | Arguments that start ACP mode |
runner.launch | Optional. node starts the program with the bundled Node.js |
runner.home | An environment variable and a folder name (starting with .) for an isolated home directory |
runner.modelEnv | For managed harnesses: environment variable names mapped to base, key or model. Only names, never values |
install.installer | manual, npm, managed, bundled or native. npm needs a valid pkg name |
The connection is OpenAI-compatible. SoduWork doesn't convert other model protocols automatically.
2. Validate and rebuild
- Run the catalog tests:
python test_agent_catalog.pyinhub-backend/, andnode --test tests/agent-catalog-extension.test.cjsinclient/. They check the schema, the public fields the client receives, and model ownership. - Rebuild the runner and the client. The packaged runner embeds the catalog, so changing the JSON makes an old runner build out of date.
- On a test computer, check discovery, dispatch, a real tool call, file delivery, resume, cancel and access modes. Record real-model results separately from protocol-simulation results.
The client reads the source file during development and resources/agent_catalog.json in a packaged build. An invalid catalog fails with an error; SoduWork never silently switches to another list or harness.
Programs that don't speak ACP
A program with its own SDK or protocol needs an adapter that implements SoduWork's session and runner contract. This is a reviewed engineering change, not a configuration option.
harness harnesses runtime runtimes 底座