Calciforge can dispatch to agents in four broad ways:
Prefer the smallest stable interface the upstream agent exposes. A documented JSON or text CLI mode is usually enough for a Calciforge adapter. GUI-only tools should not become first-class adapters until they expose a scriptable protocol; otherwise Calciforge inherits the GUI’s state model, auth prompts, and failure modes.
Every adapter and recipe also needs an instruction path. The
agent runtime contract is the shared baseline:
default to CLI guidance via calciforge-secrets, opt into MCP only when the
operator configures it for that runtime, and document any advertised artifact,
proxy, model-gateway, or future Calciforge API surfaces.
Adapter lifecycle labels:
| Agent | Calciforge path | Notes |
|---|---|---|
| Codex CLI | kind = "codex-cli" or future ACP via codex-acp |
Good fit when the Unix account running Calciforge owns Codex credentials. Calciforge can pass selected sessions through the Codex resume path. Zed’s Apache-2.0 codex-acp adapter is the better reference path for richer Codex sessions because it exposes ACP features such as images, tool-call permission requests, edit review, TODO lists, slash commands, MCP server forwarding, and Codex auth methods. Keep chat-facing agents conservative unless the channel is trusted. |
| Claude Code | kind = "claude-cli" or acpx |
Use the first-class CLI adapter for simple subscription-backed prompt execution with --session-id. Use acpx when ACP sessions are needed. |
| OpenClaw | openclaw-channel |
Preferred path for richer OpenClaw runtime, skills, plugins, provider routing, and slash commands. It talks to the Calciforge bridge plugin inside OpenClaw, not to another Calciforge gateway. Calciforge no longer supports OpenClaw agent chat through /v1/chat/completions. |
| ZeroClaw | kind = "zeroclaw" legacy adapter or future managed path |
Treat the official release as compatibility/best-effort until its blocking policy hook and instruction surfaces are verified. If Calciforge needs ZeroClaw behavior with Calciforge/Clash as the policy authority, the roadmap tracks a possible fork or library-mode path rather than assuming upstream defaults are the right contract. |
| Hermes | kind = "hermes" |
HTTP adapter for a running Hermes API server. It preserves session continuity with X-Hermes-Session-Id and can forward Calciforge !model selections when allow_model_override = true. |
| IronClaw | kind = "ironclaw" |
HTTP webhook adapter for IronClaw. Model selection is configured in IronClaw today; do not enable allow_model_override until the upstream webhook contract accepts model selectors. |
| OpenAI-compatible endpoint | openai-compat |
Plain /v1/chat/completions target for Calciforge’s model gateway, local test gateways, or compatible model APIs. Set allow_model_override = true only when this endpoint should accept Calciforge !model selections. |
| Artifact-producing CLI | kind = "artifact-cli" |
Prototype path for tools such as npcsh media workflows. Calciforge sends the task on stdin, exposes {artifact_dir} and CALCIFORGE_ARTIFACT_DIR, validates produced files, and returns a text fallback that names attachments without exposing local paths. Telegram and Matrix already use the richer internal envelope; native media upload can be added channel by channel. |
| opencode | acpx or generic CLI |
Model-agnostic terminal agent with a mature CLI/TUI surface. Prefer ACP when available. |
| Dirac | kind = "dirac-cli" |
Good scriptable fit. The adapter defaults to --json, sends the user task on stdin, ignores internal JSON event spam, and returns the final completion_result. Approval-bypass flags such as --yolo require an explicit operator opt-in. |
| Kimi Code CLI | kind = "kimi-cli" or generic ACP |
Use kimi-cli for print-mode CLI dispatch with --session and explicit --thinking / --no-thinking args. Use generic ACP for kimi acp when Calciforge should talk to Kimi’s native agent protocol. |
| AgentSwift | Not supported directly | Interesting iOS-specific workflow, but current public shape is a SwiftUI app that drives Claude plus xcodebuildmcp/openspec, not a stable CLI adapter surface. Revisit if it exposes a noninteractive JSON/ACP/HTTP protocol. |
These candidates currently look better as recipes or orchestrators than as hard first-class adapters:
| Candidate | Current fit | Why |
|---|---|---|
| npcsh | artifact-cli recipe first |
Installs cleanly via pip install 'npcsh[lite]', exposes npcsh and npc, and has explicit image/video/team commands. The best early value is multimodal artifacts through Calciforge’s secured artifact directory. |
| OmO / oh-my-openagent | Orchestrator recipe | Installs through bunx oh-my-opencode; the run command has noninteractive flags, --json, --on-complete, --session-id, and agent/model overrides. It is primarily an OpenCode harness, so Calciforge should wrap it as async work rather than owning its internals. |
| Gas Town | Orchestrator recipe, then API/state integration | The gt CLI exposes Mayor, convoy, sling, feed, dashboard, callbacks, and status commands. Calciforge should talk to Mayor or a work/status API and relay progress/artifacts rather than treating Gas Town as a one-shot chat agent. |
| Paperclip | Orchestrator recipe candidate | Paperclip positions itself as a self-hosted control plane for teams of agents, with org charts, goals, tickets, budgets, governance, heartbeats, and a React UI. It is not a chat adapter; evaluate it as an upstream orchestration system Calciforge can secure, notify, and observe. |
Ironclaw, nullclaw, and similar smaller tools should start as documented recipes unless they expose a stable protocol that needs Calciforge-specific parsing or safety behavior.
Use a recipe when an upstream tool is useful but its protocol is still just a documented command invocation. Recipes can still be security-aware: Calciforge owns identity checks, routing, per-run artifact directories, timeouts, output validation, audit logs, and tested network wrappers where the upstream runtime supports them.
Use a named adapter when Calciforge needs upstream-specific parsing or safety defaults that cannot be expressed cleanly as a recipe. Dirac is the current example: it has JSON events, a final completion event, and approval-mode pitfalls that are worth encoding once.
Use an orchestrator when the upstream owns async work state. Gas Town is the
best candidate: Calciforge should talk to the Mayor by default, submit work,
poll or receive progress, and relay final summaries/artifacts. Direct crew or
polecat targeting should be discoverable and policy-gated rather than treated
as ordinary chat routing. Example starting points live under
examples/orchestrator-recipes/.
kind = "artifact-cli" is the first secured recipe path for multimodal tools
such as npcsh. It is intentionally conservative:
{message} in argv is replaced with a fixed instruction to read stdin,
avoiding prompt leakage through process listings.{artifact_dir} is replaced with a per-run directory under the local temp
tree, and the same path is exposed as CALCIFORGE_ARTIFACT_DIR.Generic artifact recipe:
[[agents]]
id = "media-recipe"
kind = "artifact-cli"
command = "/path/to/media-agent"
args = [
"--output",
"{artifact_dir}/result.png",
"{message}",
]
timeout_ms = 120000
The command above must read the actual task from stdin. {message} is a safe
argv marker that expands to “Read the user task from stdin.”, not to the
request text.
npcsh image-generation recipe:
[[agents]]
id = "npcsh-image"
kind = "artifact-cli"
command = "/opt/calciforge/examples/agent-recipes/npcsh-image-stdin"
timeout_ms = 180000
[agents.env]
NPCSH_IMAGE_GEN_MODEL = "x/z-image-turbo"
NPCSH_IMAGE_GEN_PROVIDER = "ollama"
CALCIFORGE_NPCSH_TIMEOUT_SECONDS = "120"
The working wrapper lives in examples/agent-recipes/npcsh-image-stdin, with a
text/transcript sibling in examples/agent-recipes/npcsh-npc-stdin. The image
recipe has been smoke-tested with local Ollama x/z-image-turbo through npcsh’s
vixynt jinx and produced a real PNG artifact. Treat it as a known-working
example to adapt, not as a default install target: local image models, provider
credentials, and policy should remain operator-owned.
Before promoting a recipe, run:
scripts/agent-recipe-smoke.sh
# or include it in the local Docker deploy smoke:
CALCIFORGE_AGENT_RECIPE_SMOKE=1 scripts/manual-docker-test.sh
The smoke script installs npcsh, OmO/oh-my-opencode, Gas Town, and Paperclip in disposable Docker containers and verifies their current noninteractive CLI surfaces. It does not authenticate providers or run paid model calls.
Artifact and recipe validation is intentionally layered:
scripts/agent-recipe-smoke.sh covers installability and CLI entrypoints for
candidate recipes in disposable Docker runs.That is not yet production-level validation for every documented recipe. A recipe should not be described as known working until it has a reproducible smoke that produces the expected artifact or work-status event through Calciforge’s adapter path.
The deterministic examples/agent-recipes/media-brief-demo recipe is the
baseline artifact plumbing check. It produces a cover PNG, intro WAV, and text
brief for a support-training or product-announcement prompt without calling an
external provider. scripts/artifact-recipe-mock-e2e.py runs that recipe
through the mock channel and verifies the safe channel fallback. Use that before
manual testing a real media agent such as npcsh image generation, OpenAI image
generation, or a text-to-speech backend.
OpenClaw exposes several surfaces that look similar but behave differently:
POST /v1/chat/completions is synchronous and OpenAI-compatible when
gateway.http.endpoints.chatCompletions.enabled = true, but Calciforge does
not use it for OpenClaw agents. It bypasses the channel/plugin semantics
required for reliable slash commands and agent identity. Use
kind = "openai-compat" only when you intentionally want a plain model
endpoint rather than an OpenClaw agent.POST /hooks/agent is useful for trusted external automations. Current
OpenClaw releases acknowledge with a runId and may execute asynchronously,
so Calciforge must not treat a bare { ok: true, runId } response as an
agent reply.POST /calciforge/inbound plus the Calciforge reply callback is the intended
bridge integration. This route lives inside OpenClaw via the Calciforge
plugin. Prefer it when Calciforge should own the human channel while
OpenClaw still sees each request as a native gateway/subagent turn.calciforge install now treats OpenClaw as a first-class managed agent:
the non-interactive openclaw-channel spec requires inbound auth,
reply_webhook, and reply auth, then installs
~/.openclaw/extensions/calciforge-channel, writes
plugins.entries.calciforge-channel, allowlists the plugin when
plugins.allow is present, and restarts openclaw-gateway.
ZeroClaw should follow the same managed-agent pattern when its config
patcher graduates from the current TOML stub.Operational guidance:
/model, /status, /reset, or similar
downstream commands.kind = "openclaw-channel" at another Calciforge instance. If
the target endpoint is Calciforge’s model gateway, use openai-compat; if it
is another managed agent, route to that agent’s actual OpenClaw plugin
endpoint.openclaw-http config as stale and broken. Run
calciforge doctor after install or config edits to catch it before startup.Dirac is attractive for Calciforge because its CLI is scriptable:
printf '%s\n' "Fix the failing test and summarize the result." \
| dirac --json --timeout 120 --cwd /path/to/project
Local smoke testing found:
dirac --json can complete a non-edit task and emit a final
completion_result.--yolo can perform edits and run commands
without interactive approval, so Calciforge does not enable them by default.api_req_started events for the same
request. The Calciforge adapter intentionally ignores those and only returns
final assistant events.Operational guidance:
--yolo for trusted identities and
workspaces after accepting the local command execution risk.timeout_ms generously for real coding tasks; the adapter still kills the
child process if it exceeds Calciforge’s timeout.AgentSwift appears aimed at “Replit for native Swift” rather than a generic agent backend. Public documentation describes a SwiftUI app that:
xcodebuildmcp,openspec to track work.That workflow is useful to study, especially the Xcode/simulator validation loop. It is not yet a good Calciforge adapter target because Calciforge needs a stable process or network interface it can invoke from channel messages.
Better near-term path:
codex-cli,
claude -p, opencode, or dirac-cli adapters plus xcodebuildmcp.