Skip to content

[Bug]: Codex OAuth can print shell JSON instead of executing tool calls #56920

Description

@minhngoc25a

Bug Description

When using Hermes Agent chat mode with the OpenAI Codex OAuth provider (provider: openai-codex, base_url: https://chatgpt.com/backend-api/codex, model gpt-5.5), the model can emit Codex CLI-style shell JSON in assistant text instead of a structured Responses API function_call item. Hermes then displays the JSON and ends the turn without executing any tool.

Example assistant text observed in the local session DB:

Creating the PowerShell script now.
{"cmd": "mkdir -p /c/Temp && cat > /c/Temp/Create-HermesUpdateTask.ps1 <<'EOF'"}

Steps to Reproduce

  1. Configure Hermes with OpenAI Codex OAuth:
    • model.provider: openai-codex
    • model.default: gpt-5.5
    • model.base_url: https://chatgpt.com/backend-api/codex
  2. Start CLI chat mode.
  3. Ask Hermes to create/write a file using terminal tooling, for example a PowerShell script under C:\Temp.
  4. Observe that the assistant prints a JSON object like {"cmd": "..."} instead of invoking the terminal tool.
  5. Check the session DB/logs: the assistant turn has finish_reason=stop, no structured tool_calls, and tool_turns=0.

Expected Behavior

Hermes should not treat leaked shell JSON as a completed assistant answer. It should either receive and execute a structured Responses API function_call, or classify the leaked tool-call text as incomplete so the existing Codex continuation path can re-elicit a proper tool call.

Actual Behavior

Hermes receives finish_reason=stop with no structured tool_calls. The raw JSON appears in chat output and no terminal/file operation occurs. The turn ends with tool_turns=0.

Affected Component

  • CLI (interactive chat)
  • Tools (terminal, file ops, web, code execution, etc.)
  • Agent Core (conversation loop, context compression, memory)

Messaging Platform (if gateway-related)

N/A (CLI only)

Debug Report

Not uploaded because the local debug report may include private machine/config details. Sanitized local evidence:

Hermes Agent v0.18.0 (2026.7.1), upstream f2b8a5d5
Python: 3.11.15
OpenAI SDK: 2.24.0
Provider: openai-codex
Base URL: https://chatgpt.com/backend-api/codex
Model: gpt-5.5
Observed log path: %LOCALAPPDATA%\hermes\logs\agent.log
Observed session DB: %LOCALAPPDATA%\hermes\state.db
Log evidence: codex_stream_request used, then Turn ended: reason=text_response(finish_reason=stop) ... tool_turns=0
DB evidence: assistant message content contained {"cmd": "..."}, tool_calls was empty/null

Operating System

Windows 10/11

Python Version

3.11.15

Hermes Version

0.18.0 (2026.7.1), upstream f2b8a5d5

Additional Logs / Traceback (optional)

agent.conversation_loop: Turn ended: reason=text_response(finish_reason=stop) model=gpt-5.5 api_calls=1/90 budget=1/90 tool_turns=0 last_msg_role=assistant

Root Cause Analysis (optional)

The Codex Responses adapter already detects one leaked tool-call format: Harmony-style to=functions.<name> text. This case is a different leak format: Codex CLI-style shell JSON ending the assistant message, e.g. {"cmd": "..."}. Since it is not a structured function_call output item, _normalize_codex_response() currently normalizes it as plain assistant content and returns finish_reason="stop".

Additionally, leaked assistant text can be preserved in codex_message_items, which means it may be replayed as a completed assistant message on continuation unless explicitly cleared.

Proposed Fix (optional)

A candidate fix is available on my fork, without a PR:

https://github.com/minhngoc25a/hermes-agent/tree/fix/codex-shell-json-tool-leak

The branch:

  • Detects likely leaked Codex CLI shell JSON only when it follows an immediate action/progress lead-in line.
  • Marks the response incomplete so existing Codex continuation recovery can request a proper structured function_call.
  • Clears codex_message_items for leaked tool-call text so it is not replayed as a completed assistant message.
  • Adds regression tests for leaked shell JSON, Harmony to=functions.* replay clearing, and false-positive cases where {"cmd": ...} is a legitimate JSON payload answer.

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscodexcomp/agentCore agent runtime: loop, agent_init, prompt builder, context-compression, responses endpointcomp/cliCLI entry point, hermes_cli/, setup wizardneeds-reproBug needs reproduction stepsprovider/openaiOpenAI / Codex Responses APItype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions