#Using codex cli via openclaw

1 messages · Page 1 of 1 (latest)

edgy wasp
#

Is possible for openclaw agent to use openai codex cli to invoke codex for tasks? How to do this?

dark heraldBOT
undone pantherBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

dark heraldBOT
spice smeltBOT
#

Yes.

There are two different Codex integrations, and the names are easy to mix up:

  1. Run the actual Codex harness/CLI through OpenClaw
    Use ACP:

    • /acp doctor
    • /acp spawn codex --bind here
    • or /acp spawn codex --mode persistent --thread auto
    • optional repo cwd: /acp spawn codex --bind here --cwd /absolute/path/to/repo

    Fresh installs usually already have the bundled acpx backend enabled. First use may still fetch the Codex adapter.

  2. Use Codex auth/models inside normal OpenClaw runs
    That is the openai-codex/* route, which is not the Codex CLI harness.

If you want real Codex-run coding tasks, ACP is the one you want.

#

One important gotcha: ACP sessions are non-interactive, so if Codex needs to write files or run shell commands, set:

openclaw config set plugins.entries.acpx.config.permissionMode approve-all
openclaw gateway restart

Otherwise you can hit Permission prompt unavailable in non-interactive mode.

If instead you want OpenClaw’s embedded agent runtime to use Codex natively, that’s the bundled Codex harness (codex/*), not ACP.

Docs:

If you want, paste your openclaw --version plus whether you want:

#
  • ACP Codex session, or
  • embedded Codex harness

and I’ll give you the exact config block.

edgy wasp
#

In webchat i got ACP error internal error when use /acp spawn codex

spice smeltBOT
#

Hmm, that usually means the ACP backend failed, not that your command syntax was wrong.

A few concrete things to try:

  1. First, paste your version

    openclaw --version
    
  2. In webchat, run

    /acp doctor
    
  3. Try this instead of bare /acp spawn codex

#
   /acp spawn codex --bind here

or

/acp spawn codex --mode oneshot --thread off

Why: bare /acp spawn codex can go through a thread-binding flow, and webchat may be choking there. --bind here / --thread off narrows that down fast.

  1. If it still fails, grab the gateway log
    openclaw logs --follow
    
    then rerun the spawn and paste the ACP error lines.

Most common causes from the docs:

#
  • acpx backend missing/disabled
  • first-run Codex adapter fetch failed (npm/network issue)
  • permission prompt failure in non-interactive ACP sessions

If the log mentions permission prompt unavailable, fix with:

openclaw config set plugins.entries.acpx.config.permissionMode approve-all
openclaw gateway restart

Docs: https://docs.openclaw.ai/tools/acp-agents

If you paste:

  • openclaw --version
  • /acp doctor
  • the exact log line
#

I can usually tell you the exact fix pretty quickly.

edgy wasp
#

Using /acp spawn codex via web chat i got this error ACP error (ACP_TURN_FAILED) Internal error

spice smeltBOT
#

That narrows it down.

ACP_TURN_FAILED: Internal error means the ACP runtime got far enough to start the turn, then something inside the backend/harness blew up. The webchat message is just hiding the real cause.

I’d do this in order:

  1. Paste your version

    openclaw --version
    
  2. Run ACP doctor
    In webchat:

    /acp doctor
    

    or in CLI:

#
   openclaw acp doctor
  1. Retry with the simplest spawn

    /acp spawn codex --mode oneshot --thread off
    

    Don’t start with bare /acp spawn codex in webchat, that can involve extra binding/thread behavior.

  2. Grab the real error from logs

    openclaw logs --follow
    

    Then rerun the spawn and paste the ACP/Codex lines.

Most likely causes:

#
  • acpx backend not actually healthy
  • first-run Codex adapter fetch failed
  • Codex auth missing on the host
  • non-interactive permission prompt crash

If the logs mention permission prompt unavailable in non-interactive mode, fix with:

openclaw config set plugins.entries.acpx.config.permissionMode approve-all
openclaw gateway restart

If you paste:

  • openclaw --version
  • /acp doctor
  • 10 to 20 lines from openclaw logs --follow
edgy wasp
#

Codex is configured to use toml file non auth

spice smeltBOT
#

Ah, that helps.

~/.codex/config.toml is fine. auth.json is not required. The important part is that the OpenClaw gateway/acpx process can see the same Codex config and any env vars it depends on.

That’s the part that often breaks.

A few key points:

  • If Codex works in your shell, but OpenClaw runs as a daemon/service, the gateway may not inherit the same env/HOME.
  • If your config.toml references something like OPENAI_API_KEY, the gateway service needs that too.

Best next test

Run the gateway in the same shell where Codex works, then retry:

openclaw gateway run
#

Then from webchat try:

/acp spawn codex --mode oneshot --thread off

If that works, the problem is almost certainly service env / HOME / file visibility, not ACP itself.

Also do these

  1. Paste:
    openclaw --version
    
  2. Run:
    /acp doctor
    
#

If the daemon is the problem

Put the needed env in:

~/.openclaw/.env

or enable shell env import in config:

{
  env: {
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
#
  • whether OpenClaw is running as a daemon or foreground process

and I can narrow it down fast.

edgy wasp
#

I started gateway from shell and now respond, is a problem of envirnoment?

spice smeltBOT
#

Yep, that pretty much confirms it.

If it works when you start the gateway from your shell, but not when the background service/daemon runs, then it’s almost certainly an environment / HOME / PATH / file-visibility issue.

Most likely one of these:

  • the daemon does not inherit the env vars your shell has
  • the daemon is running as a different user, so ~/.codex/config.toml is not the same file
  • config.toml depends on env vars like OPENAI_API_KEY, but those exist only in your shell

Best fix

Put the needed vars in:

~/.openclaw/.env
#

or enable shell-env import:

{
  env: {
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
  },
}

Then restart:

edgy wasp
#

How can I assure thet gateway reads .env whe started with openclaw gateway restart?

spice smeltBOT
#

Yep, the reliable way is:

Use ~/.openclaw/.env

Not the project/local .env.

When you run:

openclaw gateway restart

the daemon/service starts fresh and loads env at startup. Per docs, the safe global file is:

~/.openclaw/.env
#

(or $OPENCLAW_STATE_DIR/.env if you changed the state dir)

Example

mkdir -p ~/.openclaw
printf 'OPENAI_API_KEY=sk-...\n' >> ~/.openclaw/.env
openclaw gateway restart

Important nuance

OpenClaw does not override existing env vars.

So load order is roughly:

  1. service process env
  2. .env in current working dir
  3. ~/.openclaw/.env
#
  1. config env block
  2. optional shell import

That means:

  • ~/.openclaw/.env is the best place for daemon-safe vars
  • if the service already has a wrong value baked in, .env will not replace it

How to verify

After restart, check:

openclaw models status

If your Codex setup depends on vars referenced from ~/.codex/config.toml, those vars should also go into ~/.openclaw/.env.

edgy wasp
#

In .env I insert only the key or also the var?

spice smeltBOT
#

Both, the variable name and the value.

Like this:

OPENAI_API_KEY=sk-...

Not just:

sk-...

A few quick rules:

  • one NAME=value per line
#
  • no export
  • no spaces around =

Example ~/.openclaw/.env:

OPENAI_API_KEY=sk-...
ANOTHER_VAR=value

If your ~/.codex/config.toml references a specific env var, use that exact var name in .env.

edgy wasp
#

Ok it works, now this /acp spawn codex is using soul user, memory from?

spice smeltBOT
#

Not exactly.

/acp spawn codex is a separate Codex ACP session, not a normal OpenClaw-native agent run.

So the rough model is:

It does use

  • the messages you send into that ACP session
  • the selected workspace / cwd
  • the Codex session history, if you keep that ACP session alive

It does not automatically use

  • OpenClaw’s native persona/bootstrap files as first-class agent state, like:
    • SOUL.md
    • USER.md
    • memory.md
#

Those are part of the OpenClaw agent bootstrap, not Codex’s own runtime.

But...

If those files are inside the workspace Codex can see, and Codex is prompted to read them, then yes, it can use them as normal files.

So the best mental model is:

  • OpenClaw-native agent → uses OpenClaw soul/user/memory system
  • ACP Codex session → uses Codex session memory + whatever files exist in its cwd

If you want Codex to behave with specific context, point it at a workspace with the files/instructions you want, for example with --cwd /path/to/workspace.

edgy wasp
#

Ok so codex should have his own workspace?

spice smeltBOT
#

Not required, but often a good idea.

Two sane setups

  1. Same workspace
    Use this if you want Codex to work on the same repo/files as the main agent.

  2. Separate workspace
    Use this if you want Codex to have different instructions, memory files, or experiments without mixing things.

My recommendation

  • For real coding on one repo: point Codex at that repo with --cwd /path/to/repo
  • For a different personality / different context / isolated runs: give Codex its own workspace

So yes, Codex can have its own workspace, but it does not have to.

The important split is:

#
  • session memory = separate ACP/Codex session
  • filesystem workspace = shared or separate, your choice

If you want, I can show you a clean setup for:

  • shared repo
  • separate Codex workspace
  • separate Codex agent config
edgy wasp
#

Yes

spice smeltBOT
#

Nice, here’s the clean version.

1) Shared repo workspace

Best when Codex should work on the same project:

/acp spawn codex --bind here --cwd /absolute/path/to/repo

2) Separate Codex workspace

Best when you want Codex to have its own instructions/files:

/acp spawn codex --bind here --cwd /absolute/path/to/codex-workspace

Then put whatever context you want in that workspace.

#

3) Dedicated Codex agent with its own default workspace

If you want this permanently:

{
  acp: {
    enabled: true,
    backend: "acpx",
    defaultAgent: "codex",
    allowedAgents: ["codex"],
  },
  agents: {
    list: [
      {
        id: "codex",
        runtime: {
#
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/absolute/path/to/codex-workspace",
          },
        },
      },
    ],
  },
}

Then you can just do:

#
/acp spawn codex --bind here

and it should use that default Codex workspace.

Practical recommendation

  • Same repo if Codex should edit your project
  • Separate workspace if Codex should have its own context/persona/files

Docs: https://docs.openclaw.ai/tools/acp-agents

Glad you got it working 🎉
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.

edgy wasp
#

How it works tools and commands that codex can execute? Where are defined boundaries?

spice smeltBOT
#

Think of /acp spawn codex as OpenClaw launching an external coding harness, not as normal OpenClaw tool-calls.

Where the boundaries are

  1. cwd / workspace

    • This is Codex’s starting context
    • Good for telling it “work here”
    • But it is not a hard jail by itself
  2. ACPX permission config
    This is the main harness-level control:

    • approve-all → Codex can write files + run shell commands
    • approve-reads → reads only; writes/exec would need prompts
    • deny-all → deny prompts entirely

    And because ACP is non-interactive:

#
  • nonInteractivePermissions=fail → session errors out
    • nonInteractivePermissions=deny → deny and continue
  1. Host OS permissions
    This is the real hard boundary for ACP.
    ACP sessions run on the host, not inside OpenClaw’s sandbox.

    So if the gateway user can access a path or run a command, Codex may be able to as well, depending on the ACPX permission mode.

  2. OpenClaw plugin tools
    By default, ACPX sessions do not get OpenClaw plugin tools.
    They only get them if you explicitly enable:

    openclaw config set plugins.entries.acpx.config.pluginToolsMcpBridge true
    
#

Custom MCP servers are also separate and explicit.

  1. Allowed harnesses
    acp.allowedAgents controls which ACP agents can even be spawned.

Important distinction

  • OpenClaw exec approvals ≠ ACPX harness permissions
  • ACP ≠ sandboxed subagent

If you want hard isolation, ACP is the wrong tool. Use a sandboxed subagent instead.

Practical recommendation

Safer setup:

#
  • dedicated Codex workspace
  • permissionMode=approve-reads
  • nonInteractivePermissions=deny

Autonomous coding setup:

  • dedicated workspace
  • permissionMode=approve-all

But with approve-all, treat it like host-level write/exec access for that gateway user.

Docs:

If you want, I can give you:

  • a safe Codex ACP config
  • or a full-power Codex ACP config
edgy wasp
#

Give me both

spice smeltBOT
#

Yep, here are both.

1) Safe Codex ACP config

Good when you want Codex to read/analyze, but not freely write/exec.

{
  acp: {
    enabled: true,
    backend: "acpx",
    allowedAgents: ["codex"],
  },
  plugins: {
    entries: {
      acpx: {
        enabled: true,
#
        config: {
          permissionMode: "approve-reads",
          nonInteractivePermissions: "deny",
        },
      },
    },
  },
}

Use it like:

/acp spawn codex --bind here --cwd /absolute/path/to/codex-workspace
#

Behavior

  • reads: allowed
  • writes/exec: denied gracefully
  • safer for shared/personal setups

2) Full-power Codex ACP config

Good when you want Codex to edit files and run commands autonomously.

{
  acp: {
    enabled: true,
    backend: "acpx",
    allowedAgents: ["codex"],
#
  },
  plugins: {
    entries: {
      acpx: {
        enabled: true,
        config: {
          permissionMode: "approve-all",
          nonInteractivePermissions: "fail",
        },
      },
    },
  },
}

Use it like:

#
/acp spawn codex --bind here --cwd /absolute/path/to/codex-workspace

Behavior

  • reads: allowed
  • writes: allowed
  • shell commands: allowed
  • basically host-level write/exec as the gateway user

Optional: let Codex use OpenClaw plugin tools too

Off by default.

#
openclaw config set plugins.entries.acpx.config.pluginToolsMcpBridge true

Only enable that if you actually want ACP Codex to call installed OpenClaw plugin tools.


After editing config

Restart the gateway:

openclaw gateway restart

edgy wasp
#

I havent acp entry in config json only acpx is right?

spice smeltBOT
#

Not exactly, they are different things:

  • acpx = the backend plugin/runtime
  • acp = the top-level feature/policy config

So:

  • acpx answers: what runtime plugin runs Codex
  • acp answers: is ACP enabled, which backend to use, which agents are allowed, defaults, limits, etc.

If /acp spawn codex is already working for you, then your current setup is obviously functional. But for a clean explicit config, I’d still recommend having both:

{
  acp: {
    enabled: true,
#
    backend: "acpx",
    allowedAgents: ["codex"],
  },
  plugins: {
    entries: {
      acpx: {
        enabled: true,
      },
    },
  },
}

Then add the plugins.entries.acpx.config.* permission settings on top of that.

So short answer:

edgy wasp
#

Codex gives me this error:

Bwrap: loopback: failed RTM_NEWADDR: Operation not permitted

spice smeltBOT
#

That error is coming from Codex’s own Linux sandbox, not from OpenClaw itself.

bwrap = bubblewrap, which Codex uses on Linux for sandboxing.
So the flow is basically:

  • OpenClaw launches Codex via ACP
  • Codex tries to start its own sandbox
  • Linux blocks the bwrap network/namespace setup
  • Codex fails with:
Bwrap: loopback: failed RTM_NEWADDR: Operation not permitted

What this usually means

On recent Linux, especially Ubuntu 24.04 / WSL / AppArmor-restricted setups, Codex’s bubblewrap sandbox can fail because unprivileged user namespace / loopback setup is blocked.

#

What to try

  1. Make sure the distro bubblewrap package is installed
    Codex’s docs recommend that on Linux.

  2. If it still fails, this is likely an OS/AppArmor restriction
    In that case the fix is on the Codex/Linux side, not OpenClaw.

  3. Pragmatic workaround
    Use a Codex sandbox mode that avoids the broken bwrap path, or run Codex with less sandboxing in a dedicated workspace if you trust that machine.

Important warning

If you relax Codex’s own sandbox and use ACP full-power permissions, then Codex is basically running with host-level access as the gateway user.

So my recommendation is:

  • best: fix the Codex Linux sandbox properly
  • temporary workaround: use a dedicated workspace and loosen Codex sandboxing only there
edgy wasp
#

Ubuntu 24.04.4 LTS
Kernel linux 6.8.0-101-generic
x86_64
Codex-cli 0.122.0
Openclaw 2026.4.5

spice smeltBOT
#

Yep, that combo fits the pattern almost perfectly.

With:

  • Ubuntu 24.04.4
  • Kernel 6.8
  • Codex CLI 0.122.0

that bwrap ... RTM_NEWADDR ... Operation not permitted error is very likely the Codex/Linux bubblewrap sandbox issue on Ubuntu/AppArmor, not an OpenClaw ACP bug.

What that means

Your ACP launch is basically working.

The failure happens after OpenClaw starts Codex, when Codex tries to create its own Linux sandbox.

So I’d read it like this

  • OpenClaw side: mostly fine
#
  • Codex side: sandbox is failing on Ubuntu 24.04/AppArmor/userns restrictions

Best path

  1. Keep treating this as a Codex sandbox problem
  2. Use a dedicated Codex workspace
  3. Either:
    • fix Codex’s Linux sandbox properly, or
    • temporarily relax Codex’s own sandboxing for that dedicated workspace if you trust the machine

Important caution

If you relax Codex sandboxing and also give ACP full-power permissions, then Codex is effectively operating with host-level access as the gateway user.

So for safety I’d recommend:

  • Preferred: fix Codex sandbox, keep boundaries
  • Temporary workaround: dedicated workspace + relaxed Codex sandbox only there
edgy wasp
#

Can openclaw agent message send to codex spawn wit AgenttoAgent conf?

#

?

spice smeltBOT
#

Yes, but use sessions_send, not the message tool.

Short version

If you want:

  • main OpenClaw agent → send work to → Codex ACP agent/session

then you need both:

  1. tools.agentToAgent enabled
  2. tools.sessions.visibility wide enough, usually "all" for cross-agent reach

Minimal shape

{
#
  agents: {
    list: [
      {
        id: "main",
      },
      {
        id: "codex",
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/absolute/path/to/codex-workspace",
          },
#
        },
      },
    ],
  },

  tools: {
    agentToAgent: {
      enabled: true,
      allow: ["codex"],
    },
    sessions: {
      visibility: "all",
    },
  },
}
#

How it works

  • Spawn or bind a Codex ACP session
  • From another agent, use sessions_send
  • Target it by session key or label

Important distinction

  • bindings[].type = "acp" = route a Discord thread/channel directly into Codex
  • tools.agentToAgent + sessions_send = one agent talks to another agent/session internally

So if your goal is:

  • users in this thread talk directly to Codex → use ACP binding
  • one OpenClaw agent delegates to Codex behind the scenes → use agent-to-agent + sessions_send

If you want, I can write the exact JSON5 config for:

  1. direct Discord thread → Codex, or
  2. main agent → Codex relay
#

Yep 🙂

Yes, OpenClaw can send work to a Codex ACP session.

But the clean way is:

  • not message
  • use sessions_send
  • and enable tools.agentToAgent

Simplest mental model

  • Discord thread -> Codex directly
    use: /acp spawn codex --bind here

  • OpenClaw agent -> Codex internally
    use: sessions_send + tools.agentToAgent

#

So the answer is yes, but via session tools, not normal chat-message forwarding.

If you want, I can give you a copy-paste config for the exact setup:

  • A) Discord thread bound to Codex
  • B) main agent delegating to Codex behind the scenes
edgy wasp
#

B option and how to start it from scratch step by step

spice smeltBOT
#

Yep, for B = main agent delegates to Codex behind the scenes, I’d set it up like this.

1) Make a separate codex agent

Add a normal main agent plus a second agent whose runtime is ACP/Codex:

{
  acp: {
    enabled: true,
    backend: "acpx",
    allowedAgents: ["codex"],
  },

  plugins: {
    entries: {
      acpx: {
#
        enabled: true,
        config: {
          // Needed if you want Codex to actually write files / run commands
          permissionMode: "approve-all",
          nonInteractivePermissions: "fail",
        },
      },
    },
  },

  agents: {
    list: [
      {
        id: "main",
        default: true,
#
        workspace: "/absolute/path/to/main-workspace",

        // Let main target codex with sessions_spawn(... agentId:"codex")
        subagents: {
          allowAgents: ["codex"],
        },
      },
      {
        id: "codex",
        workspace: "/absolute/path/to/codex-workspace",
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
#
            mode: "persistent",
            cwd: "/absolute/path/to/codex-workspace",
          },
        },
      },
    ],
  },

  tools: {
    // Allow inter-agent/session messaging
    agentToAgent: {
      enabled: true,
      allow: ["codex"],
    },
#
    // Let sessions_send reach across agent boundaries
    sessions: {
      visibility: "all",
    },
  },
}

2) If you use a tool allowlist, include these too

If your main agent has tools.allow, make sure it includes at least:

  • sessions_spawn
  • sessions_send
  • sessions_list (helpful for discovery/debugging)
  • session_status (optional but useful)
#

3) Restart the gateway

After saving config:

openclaw gateway restart

4) Start a Codex worker session

Now from the main agent chat, ask it to create a persistent Codex worker session.

Conceptually, the main agent should do:

sessions_spawn({
  runtime: "acp",
  agentId: "codex",
#
  mode: "session",
  cleanup: "keep",
  label: "codex-worker"
})

In plain English, you can tell it something like:

Create a persistent ACP session for agent codex, keep it alive, label it codex-worker.

5) Send work to that Codex session

Then the main agent can forward tasks to it with sessions_send, for example:

sessions_send({
#
  label: "codex-worker",
  message: "Open the repo, inspect the auth flow, and propose a fix for the failing login test."
})

In plain English:

Send this task to the codex-worker session and give me back the result.

6) Important gotchas

  • This is not automatic by default.
    The main agent needs to be told to spawn/reuse Codex and send tasks to it.
  • If the requester session is sandboxed, ACP spawn can be blocked.
  • If Codex still throws the bwrap error, that is still the Codex/Linux sandbox problem, not the session routing.

Recommended workflow

#

The simplest pattern is:

  1. main agent session starts
  2. main agent spawns codex-worker once
  3. main agent reuses codex-worker with sessions_send
  4. Codex does code work, main agent summarizes back to you

Docs:

If you want, I can next give you a copy-paste full config with fake paths replaced by real example paths so you can drop it straight into your config.

edgy wasp
#

how can I verify that agent:codex:main is effectively an openai codex harness via acp and not an openclaw harness?

spice smeltBOT
#

The fastest check is the session key shape.

If it is really:

agent:codex:main

then that is not an ACP session.

That key means:

  • agentId = codex
  • session = main

So it is the normal OpenClaw session for the codex agent, not an ACP-spawned external harness session.

ACP sessions look like:

#
agent:codex:acp:<uuid>

From the docs:

  • ACP session key → agent:<agentId>:acp:<uuid>
  • subagent session key → agent:<agentId>:subagent:<uuid>

So if you want to verify “is this really Codex via ACP?”, the answer is:

  • agent:codex:main → no, not ACP
  • agent:codex:acp:... → yes, ACP runtime session

Important nuance

agent:codex:main could still be using the embedded Codex harness, but that is a different path.

#

So there are 3 different cases:

  1. OpenClaw normal session

    • key like agent:codex:main
  2. OpenClaw embedded Codex harness

    • still an OpenClaw session
    • usually driven by model: "codex/..." + embeddedHarness.runtime: "codex"
  3. ACP Codex session

    • key like agent:codex:acp:<uuid>
    • created by /acp spawn codex or sessions_spawn({ runtime: "acp" })

How to verify in practice

  • Check the session key
  • Run /status
  • If you used ACP, also check /acp status
#

so you can tell exactly which path you’re on.

edgy wasp
#

I have this

{ id: "codex", workspace: "/absolute/path/to/codex-workspace", runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent", cwd: "/absolute/path/to/codex-workspace", },

spice smeltBOT
#

Ah, yep, with that config there’s an important nuance:

runtime: {
  type: "acp",
  acp: {
    agent: "codex",
    backend: "acpx",
    mode: "persistent",
    cwd: "/absolute/path/to/codex-workspace",
  },
}

That means the agent is configured to run through ACP.

So agent:codex:main can still be ACP-backed.

#

The correction

I oversimplified earlier: :acp: is the default isolated ACP key shape, but ACP can also be mapped onto a known session key like:

agent:codex:main

So session key alone is not enough in your case.

How to verify properly

1) Check the agent config path

If the active agent really resolves to:

runtime.type = "acp"
#
runtime.acp.agent = "codex"
runtime.acp.backend = "acpx"

then that agent is on the ACP runtime path, not the normal OpenClaw embedded path.

2) Run /acp status

This is the best runtime check.

If agent:codex:main is ACP-backed, /acp status for that session should show ACP runtime state instead of “no ACP session”.

3) Compare against the embedded Codex harness path

The embedded OpenClaw Codex harness is a different config shape:

#
model: "codex/gpt-5.4",
embeddedHarness: {
  runtime: "codex",
}

That is not the same as:

runtime: {
  type: "acp",
  acp: { ... }
}

So:

#
  • runtime.type: "acp" → ACP external harness path
  • model: "codex/..." + embeddedHarness.runtime: "codex" → OpenClaw embedded Codex harness path

Practical answer for your snippet

With the snippet you pasted, yes, that is the ACP path.

The cleanest confirmation is:

  • open that codex agent session
  • run /acp status
  • if it reports Codex/acpx runtime state, you’ve verified it

Docs:

If you want, I can give you a tiny “ACP vs embedded Codex vs openai-codex” cheat sheet with exact config examples for all 3.

edgy wasp
#

this is what I have:

/acp status in main session chat return:
ACP error (ACP_SESSION_INIT_FAILED): Session is not ACP-enabled: agent:main:main

/acp spawn codex works in main session chat and create avery time a new agent spawn with
Spawned ACP sesssion agent:codex:acp:xxxxxx (persistent, backend acpx) Session is unbound

/acp doctor works from main session chat and return values, activeRuntimeSession = 1 only when an agent is spawned otherwise is 0

these parameters I don't know what are needed for
{ id: "codex", workspace: "/absolute/path/to/codex-workspace", runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent", cwd: "/absolute/path/to/codex-workspace", },

can't figure it out how to make opencla relay on codex in a non-spawned sessione one shot

#

so?

spice smeltBOT
#

So, yes:

With this:

runtime: {
  type: "acp",
  acp: {
    agent: "codex",
    backend: "acpx",
    mode: "persistent",
    cwd: "...",
  },
}

your codex agent is configured to use Codex via ACP/acpx, not the normal OpenClaw embedded harness path.

#

Short rule

  • runtime.type: "acp" → ACP Codex path
  • embeddedHarness.runtime: "codex" + model: "codex/..." → embedded Codex harness path

Best runtime check

Run:

/acp status

in that codex agent session.

If it shows ACP runtime state, you’ve confirmed it.

So the answer is: your config is the ACP route.

edgy wasp
#

the behavior I observed is this,

{ id: "codex", workspace: "/absolute/path/to/codex-workspace", runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent", cwd: "/absolute/path/to/codex-workspace", },

these conf simply tells to acp agent that have a persistent home, agent inizialization is only by session_spawn, then main agent can talk with him inside the session, the session persists till is deleted, after this it must be recreated.

spice smeltBOT
#

Yep, that understanding is basically correct.

What that config does

This part:

{
  id: "codex",
  workspace: "...",
  runtime: {
    type: "acp",
    acp: {
      agent: "codex",
      backend: "acpx",
      mode: "persistent",
      cwd: "...",
#
    },
  },
}

does not by itself create a live Codex session.

It mainly says:

  • when this agent uses ACP,
  • use Codex
  • through acpx
  • with persistent mode
  • and default to that workspace/cwd

When the real ACP session is created

#

The actual live session appears when something starts/binds it, for example:

  • sessions_spawn(... runtime: "acp", agentId: "codex" ...)
  • /acp spawn codex
  • or a bindings[].type = "acp" conversation hits that agent

So your summary, cleaned up

  • config = persistent home/defaults
  • sessions_spawn or ACP binding = creates the live session
  • main agent can then talk to that live session with sessions_send
  • the ACP session persists until deleted/reset/expired/closed
  • if deleted, it must be created again on next spawn/bind

One small correction

It is not only sessions_spawn that can initialize it.
A bound ACP conversation can also lazily create/recreate it on first use.

#

So the short answer is:

yes, your mental model is right, except that ACP bindings can also create the session, not just sessions_spawn.

edgy wasp
#

what are real benefit of mode: "persistent" ?

spice smeltBOT
#

Real benefits of mode: "persistent" are mostly about continuity.

What you gain

1) Same Codex session keeps its own context

Codex remembers the prior exchange inside that ACP session, so follow-ups like:

  • “continue”
  • “fix the tests now”
  • “use the same branch”
  • “apply the feedback from before”

work much better.

2) Same workspace / repo state

You keep using the same cwd and the same evolving repo state instead of re-bootstrapping a fresh worker every time.

#

3) Less startup churn

You avoid repeatedly creating new ACP sessions, reinitializing the harness, and re-establishing context.

4) Better for iterative coding

Persistent is most useful when the workflow is:

  • inspect repo
  • make changes
  • run tests
  • revise
  • continue tomorrow

That’s where it actually shines.


What it does not magically give you

#

It does not create a session by itself.
It only means: when a session is created, keep/reuse it instead of treating it like disposable one-shot work.


Downsides

1) Stale context

Old assumptions can stick around.

2) Drift

The Codex session may accumulate messy history over time.

3) You need lifecycle management

If you delete/reset it, it has to be recreated.


#

Practical rule

Use persistent when Codex is acting like a long-lived coding coworker.

Use oneshot when Codex is just:

  • “analyze this”
  • “do one task”
  • “return result”
  • “throw session away”

So the short answer is:

persistent is valuable when you want continuity, iteration, and session memory.
If you only want disposable delegated jobs, it gives you much less.

dark heraldBOT
edgy wasp
#

what happens to acp session context windows is compacted by openclaw or by codex harness? There is a way o monitor this?

spice smeltBOT
#

For ACP Codex sessions, the short answer is:

Who owns compaction?

Codex / the upstream harness owns the real context window.
OpenClaw does not compact that upstream ACP conversation for it.

OpenClaw mainly does 2 things here:

  1. routes messages to the ACP session
  2. keeps a local transcript mirror for channel history, /new, /reset, search, routing, etc.

So for ACP:

  • real working context = Codex-side
  • local mirror/history = OpenClaw-side

So when the ACP session gets long

#

If that Codex ACP session needs to shrink context, that is basically a Codex/harness concern, not OpenClaw’s normal native compaction flow.

That’s different from the embedded Codex harness docs, where OpenClaw explicitly says native compaction is delegated to Codex app-server.

Can you monitor it?

For ACP, only indirectly

You can monitor the session/runtime, but not the upstream context window in a rich OpenClaw-native way.

Useful checks:

  • /acp status
  • /acp sessions
  • gateway logs
  • any harness-side status/diagnostic output the adapter exposes

What OpenClaw does not really give you here

There isn’t a universal “show me current ACP token window and compaction state” dashboard for ACP sessions the way people usually imagine.

#

Practical rule

  • OpenClaw native / PI sessions → OpenClaw compaction logic matters
  • embedded Codex harness (codex/*) → Codex app-server compaction
  • ACP Codex session → Codex harness/session owns context + compaction

So in your case, if you are really using ACP Codex, I would assume:

Compaction is Codex-side, OpenClaw is mostly the control plane + transcript mirror.

If you want, I can make you a 3-column table for:

  • OpenClaw native
  • embedded Codex harness
  • ACP Codex

showing exactly who owns context, compaction, history, and session persistence.

edgy wasp
#

ok

spice smeltBOT
#

Nice, glad we untangled it. If you want to keep going later, I can help compare ACP Codex vs embedded Codex harness side by side.

edgy wasp
#

why codex token acp ctx % are "unknown" in sessions?

spice smeltBOT
#

Because OpenClaw only shows those numbers when it actually has them.

For the unknown / ?% case, it usually means one or more of these are missing:

  • used tokens
  • context window size
  • percent used

From the code path, OpenClaw renders:

  • unknown used if total usage is missing
  • unknown/<ctx> (?%) if it knows context size but not actual used tokens / percent

Why this happens a lot with ACP Codex

With ACP sessions, OpenClaw is mostly the control plane + transcript mirror.

So if the Codex ACP adapter / harness does not report standardized usage stats back, OpenClaw cannot calculate:

#
  • token totals
  • context window
  • ctx %

and it falls back to unknown.

Important point

That usually does not mean the session is broken.
It just means usage telemetry is incomplete on that ACP path.

Why embedded/native sessions look better

For native OpenClaw sessions, /status can often backfill from:

  • live runtime snapshot
  • transcript usage entry

For ACP Codex, that fallback is often much thinner.

#

So the short answer is:

unknown means OpenClaw is not receiving enough token/context telemetry from the ACP Codex session to compute it.

If you want, I can point you to the exact formatting logic and the exact fields that would need to be populated for it to stop showing unknown.