hzhang a27f6bd067 feat(codex): plexum-host MCP exposure + real consume mirror
Three-part wiring so codex agents get full dynamic-tool consume
support:

1. mcp-host subcommand in the plugin binary (routes argv[1] to
   mcpbridge.Run). Reads PLEXUM_MCP_SOCKET / PLEXUM_MCP_AGENT_ID
   from env, baked into codex's `mcp add --env` registration.

2. EnsureCodexMCPRegistered registers a per-agent stable server
   name (plexum-host-<sanitised>) lazily on first turn. Stable
   per-agent socket path via StableSocketPath so codex's
   registration entry and the per-turn bridge listener agree.

3. Post-turn ParseRolloutToolCalls + EmitCodexToolCalls walks the
   matching rollout-*-<thread_id>.jsonl and emits canonical events
   for every function_call + function_call_output pair using
   codex's REAL call_X ids. dynamic.jsonl now has block_ids that
   match codex's session, so consume mirror has real targets.

4. MutateCodexSession rewrites those response_item entries on
   consume: function_call.arguments → "{}" (heavy), output → marker.
   E2E verified: codex resume sees "...(tool called)" instead of
   the original output.
2026-06-01 20:14:06 +01:00

Plexum-openai-provider

Plexum ProviderPlugin that wraps the local codex CLI binary (OpenAI Codex CLI ≥ 0.135). Same CLI-driven pattern as Plexum-gemini-provider and Plexum-anthropic-provider's contractor mode.

Status

v0.1: subprocess-per-turn, JSONL stream parsing, per-workspace session continuity via codex exec resume <thread_id>. Single model codex advertised by default; operator can override.

Auth

No API key in this plugin's config. The codex CLI handles auth via ~/.codex/ (ChatGPT login OR OPENAI_API_KEY). Run codex login once (or set env) and this plugin just shells out.

Install

cd ~/Plexum-openai-provider
./scripts/install.sh

Operator notes in ~/.plexum/plugins/plexum-openai-provider/config.json:

{
  "binary": "/home/<you>/.local/bin/codex",
  "extra_args": []
}

(absolute path is required when the daemon runs under systemd — systemd doesn't inherit shell PATH).

Then .plugins.allow += ["plexum-openai-provider"] and:

plexum agent-add --model codex my-agent
systemctl --user restart plexum
plexum say --agent-id my-agent --session-id $(plexum new-session --agent-id my-agent) "hello"

How it works

Per Plexum turn:

codex exec [resume <thread_id>] \
  --skip-git-repo-check \
  --dangerously-bypass-approvals-and-sandbox \
  --json \
  [--model <m>] \
  "<last user message>"

cwd = <agent workspace>, stdin = /dev/null (codex would otherwise hang waiting for additional input). Codex emits JSONL:

{"type":"thread.started","thread_id":"..."}
{"type":"turn.started"}
{"type":"item.completed","item":{"id":"...","type":"agent_message","text":"..."}}
{"type":"turn.completed","usage":{"input_tokens":...,...}}

thread.started.thread_id is captured into <workspace>/.plexum-codex-session so the next turn passes exec resume <id> instead of exec. item.completed of type agent_message becomes text_delta; turn.completed.usage populates the canonical Usage on message_end.

ChatGPT account vs API key

ChatGPT-account installs only support the default model; explicit --model gpt-5-codex etc. returns 400 invalid_request_error. With an API key install, operator can declare more model ids via config.supported_models + config.model_args.

License

Same as Plexum.

Description
Plexum ProviderPlugin wrapping the codex CLI binary (OpenAI Codex CLI)
Readme 54 KiB
Languages
Go 93%
Shell 7%