#Codex Harness w/ non-codex models?
44 messages · Page 1 of 1 (latest)
Short version: not in a way I’d rely on.
OpenClaw does have ACP model override plumbing (/acp model, acpx --model), but that only works if the underlying harness adapter actually supports switching to that model. So using the codex harness to run something like Sonnet 4.6 or Kimi is not something I’d count on.
If you want those, use the matching ACP harness instead, for example:
claudefor Claude-family modelskimifor Kimigeminifor Geminiqwenfor Qwen
Current built-in ACP/acpx harness ids include:
claude, codex, copilot, cursor, droid, gemini, iflow, kilocode, kimi, kiro, openclaw, opencode, pi, qwen.
If what you really want is “one harness, many models”, the best fit is usually openclaw (or just native OpenClaw sessions), since then model choice comes from OpenClaw config instead of a vendor-specific CLI.
Docs:
If you want, I can show the exact /acp spawn ... examples for claude vs kimi.
Looks like it's required that you ask it to run it in that harness. Is there a way to make it so it runs the opencode harness by default?
Yep, you can.
If you want ACP spawns to default to opencode, set:
{
acp: {
defaultAgent: "opencode",
allowedAgents: ["opencode"] // or include it in your existing list
}
}
That makes ACP use opencode when the harness target is omitted.
If you want this behavior only for one specific OpenClaw agent, the cleaner option is per-agent runtime config:
{
agents: {
list: [
{
id: "main",
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent"
}
}
}
]
}
}
So basically:
- global default for ACP →
acp.defaultAgent: "opencode" - default only for one agent/profile →
agents.list[].runtime.acp.agent: "opencode"
Docs:
If you want, I can turn that into an exact openclaw config set ... command too.
Does this work in prose workflows? Say, for example, I set it so any anthropic model uses the CLOD ACP and the GPT-4 codex uses the codexed ACP and then anything else uses the open code ACP. Will those models, when chosen in a PROSE workflow, use that harness or do they use some parent harness?
My understanding is that they're sub-agents and I would imagine they use the harness that is configured in the OpenClaw config, but let me know.
Your mental model is mostly right, but there’s one important split:
model selection and harness/runtime selection are separate things.
Based on the current docs:
- OpenProse
session/ Task maps tosessions_spawn sessions_spawndefaults to the native subagent runtime- ACP harnesses are only used when you explicitly spawn
runtime: "acp"(or route through an agent/profile configured to default to ACP)
So in a .prose workflow, this:
agent writer:
model: sonnet
means “spawn a worker with that model override”, not “pick the Claude/OpenCode/Codex ACP harness automatically”.
So for your example:
- “Anthropic models -> Claude ACP”
- “GPT/Codex -> Codex ACP”
- “everything else -> OpenCode ACP”
No, OpenProse won’t auto-map models to harnesses that way.
It won’t look at the chosen model and then swap harnesses underneath.
The practical rule is:
- PROSE session step → usually an OpenClaw subagent
- ACP harness → only if the spawned session is intentionally ACP
- there isn’t really a “parent harness” that model picks inherit from
So if you want PROSE workers to use different harnesses, I’d treat that as a runtime/agent-profile design, not a model-routing rule.
Relevant docs:
- OpenProse runtime mapping: https://docs.openclaw.ai/prose
- ACP vs subagents: https://docs.openclaw.ai/tools/acp-agents
- Config reference: https://docs.openclaw.ai/gateway/configuration-reference
If you want, I can sketch the cleanest config pattern for “some workflow workers use Claude ACP, others use Codex ACP”.
So will the prose session not run in say opencode if I have the default acp set to opencode?
Right, not by itself.
acp.defaultAgent: "opencode" only matters after the runtime is ACP.
OpenProse sessions map to sessions_spawn, and sessions_spawn uses subagent runtime by default. So:
- plain Prose session → normal OpenClaw subagent
- ACP session with no explicit harness → uses
acp.defaultAgent(for exampleopencode)
So just setting:
acp.defaultAgent: "opencode"
does not make Prose sessions run in OpenCode automatically.
It would only kick in if the Prose execution path is actually spawning runtime: "acp" sessions.
Docs:
If you want, I can sketch what would need to change for Prose workers to actually use ACP.
Is it possible to make every runtime 'acp' by default? I want to strictly use the opencode harness for everything
Not as one blanket “make all runtime ACP” switch, at least not in the documented config.
What is supported is the closest version of that:
{
acp: {
enabled: true,
defaultAgent: "opencode",
allowedAgents: ["opencode"]
},
agents: {
list: [
{
id: "main",
default: true,
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent"
}
}
}
]
}
}
That gets you pretty close:
- your main/default agent is ACP-backed
- omitted ACP target resolves to
opencode - ACP sessions will prefer OpenCode
But the catch is: it does not globally rewrite every subagent/default sessions_spawn call into ACP.
Docs still say sessions_spawn defaults to subagent runtime, and things like current OpenProse are documented in terms of subagents.
So if you mean strictly everything everywhere, I’d say not fully, no.
If you mean “make the main interactive agent always use OpenCode ACP and use ACP whenever that path is available”, then yes.
Docs:
- https://docs.openclaw.ai/tools/acp-agents
- https://docs.openclaw.ai/gateway/configuration-reference
- https://docs.openclaw.ai/prose
If you want, I can give you the exact minimal config for an “ACP-first / OpenCode-only” setup.
Ok what's a clean config to have all top level agents use opencode as the ACP
Cleanest pattern is:
- set global ACP to
opencode - make each top-level agent an ACP runtime agent
{
acp: {
enabled: true,
backend: "acpx",
defaultAgent: "opencode",
allowedAgents: ["opencode"],
maxConcurrentSessions: 8,
},
agents: {
list: [
{
id: "main",
default: true,
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent",
},
},
},
{
id: "ops",
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent",
},
},
},
{
id: "research",
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent",
},
},
},
],
},
}
That’s the explicit, boring, reliable version.
A few notes:
- this is JSON5, not YAML
acp.defaultAgent: "opencode"makes omitted ACP targets fall back to OpenCode
allowedAgents: ["opencode"]effectively locks ACP to OpenCoderuntime.type: "acp"on each top-level agent is the key bit
If you want Discord thread-bound ACP spawns too, also make sure:
{
channels: {
discord: {
threadBindings: {
spawnAcpSessions: true,
},
},
},
}
And after changing config, restart the gateway.
Docs:
One caveat, this makes your top-level agents ACP-backed. It still does not force every internal subagent/OpenProse path to ACP automatically. If you want, I can give you a full “OpenCode-only” config block with sane defaults merged together.
For top-level agents, Slack is the same story, the ACP config is global, not Discord-specific.
So this part stays the same:
{
acp: {
enabled: true,
backend: "acpx",
defaultAgent: "opencode",
allowedAgents: ["opencode"],
},
agents: {
list: [
{
id: "main",
default: true,
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent",
},
},
},
],
},
}
And then your Slack channel config is just normal Slack config, for example:
{
channels: {
slack: {
enabled: true,
botToken: "xoxb-...",
appToken: "xapp-...",
thread: {
historyScope: "thread",
inheritParent: false,
},
},
},
}
So, in short:
- top-level agents on Slack → yes, same ACP/OpenCode setup works
- Slack-specific extras → just the normal
channels.slack.*config
One nuance: for ACP thread spawning/binding, the docs explicitly call out Discord and Telegram spawnAcpSessions, but I do not see an equivalent Slack ACP thread-spawn knob documented right now. So I’d expect the agent runtime config to work fine on Slack, but I would not assume Discord-style ACP thread spawn behavior there without testing.
Docs:
If you want, I can write a full Slack + OpenCode ACP example config block you can paste in.
Looks like the ACP default is 10.
Tiny gotcha, the ACP agents page has an example with 8, but the configuration reference default block shows:
acp: {
maxConcurrentSessions: 10
}
So I’d treat 10 as the real default.
Docs: https://docs.openclaw.ai/gateway/configuration-reference#acp
The issue i'm having is i'm running /new in the tui and the agent says it's not using ACP
That sounds like the TUI session was never actually ACP-bound, so /new is just resetting a normal session.
Key bit:
/newdoes not switch runtimes- it only resets the current session
/newstays ACP only if that conversation/session was already bound to ACP
So if you did not first do something like:
/acp spawn opencode --bind here
in that same TUI session, then /new resetting to non-ACP is expected.
Two likely causes:
- the TUI is on a regular session, not an ACP-bound one
- the TUI is attached to a different agent/profile than the one you configured as
runtime.type: "acp"
Quick checks:
openclaw --version
Then in the TUI:
/status
/acp status
If /acp status shows no bound ACP session, that’s the problem.
So the mental model is:
- config can make an agent ACP-backed
- but
/newdoes not magically convert an existing normal TUI session into ACP - it only resets whatever that session already is
Docs: https://docs.openclaw.ai/tools/acp-agents
If you want, paste your agents.list + acp config block and I’ll tell you exactly why the TUI session is missing ACP.
well how do I get every new session to take the acp runtime then?
The closest supported way is:
- make your default/top-level agent ACP-backed
- make sure the TUI is actually opening sessions on that agent
- then
/newwill keep resetting that same ACP-backed agent/session
So, config-wise:
{
acp: {
enabled: true,
backend: "acpx",
defaultAgent: "opencode",
allowedAgents: ["opencode"],
},
agents: {
list: [
{
id: "main",
default: true,
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent",
},
},
},
{
id: "research",
runtime: {
type: "acp",
acp: {
agent: "opencode",
backend: "acpx",
mode: "persistent",
},
},
},
],
},
}
Then in the TUI, make sure you’re actually on one of those agents:
- launch the TUI from that agent’s workspace, or
- switch explicitly with:
/session agent:main:main
After that, /new should keep you on that ACP-backed session.
The important limitation is: there is not a documented single global “every new session everywhere uses ACP” switch.
What you can do is make every top-level agent ACP-backed, then always open/switch sessions under those agents.
If you want, I can give you the exact “single-agent TUI always starts in ACP/OpenCode” setup.
for the elliott agent I have the runtime selected as type acp, exact config you have above.
Then I do all the steps and when I run /status on a new session i'm still getting
🧵 Session: agent:elliott:tui-a942e36b-709e-4d2d-aae3-31e05d8f71c9 • updated just now
⚙️ Runtime: direct · Think: low
🪢 Queue: collect (depth 0)
I think this is expected, and my earlier framing was a bit too optimistic.
Your /status is showing a plain TUI session:
agent:elliott:tui-...Runtime: direct
The key doc detail is that agents.list[].runtime is described as runtime defaults per agent, and the precedence section is specifically for ACP bound sessions. So runtime.type: "acp" on elliott does not seem to turn every brand new openclaw tui session into ACP automatically.
In other words:
- fresh
tui-*session = still normal/direct elliott.runtime.type = "acp"= defaults used when an ACP session is actually spawned/bound/newjust resets that current TUI session, it does not upgrade it to ACP
So yes, seeing:
⚙️ Runtime: direct🪢 Queue: collect
on a new TUI session is probably normal.
Practical takeaway:
- if you want actual ACP/OpenCode, use an ACP-bound session or an explicit ACP spawn path
- I could not find a documented “make every bare TUI session ACP by default” switch
And on the original harness question, I still would not rely on codex to become Sonnet/Kimi just via model override. Use the matching harness, like claude or kimi, or standardize on opencode if that’s the harness you want.
If you want, paste:
openclaw --version