Skip to content

Route TradingAgents through Claude Code and Codex CLIs#806

Open
NagyVikt wants to merge 7 commits into
TauricResearch:mainfrom
NagyVikt:codex-claude-code-provider-2026-05-11
Open

Route TradingAgents through Claude Code and Codex CLIs#806
NagyVikt wants to merge 7 commits into
TauricResearch:mainfrom
NagyVikt:codex-claude-code-provider-2026-05-11

Conversation

@NagyVikt
Copy link
Copy Markdown

@NagyVikt NagyVikt commented May 11, 2026

Summary

Adds experimental local CLI-backed LLM providers so TradingAgents can route model calls through an already authenticated Claude Code or Codex subscription instead of requiring direct Anthropic/OpenAI API keys.

What changed

  • Adds claude-code provider backed by the local claude -p CLI.
  • Adds codex provider backed by the local codex exec CLI in read-only sandbox mode.
  • Wires both providers into the LLM factory, default config, model catalog, validators, API-key detection, and interactive CLI provider picker.
  • Keeps TradingAgents tool execution in LangGraph by translating local-agent JSON tool-call requests into LangChain AIMessage.tool_calls.
  • Supports wrapper commands such as npx claude / npx codex via shlex.split.
  • Reports stdout as a fallback when local CLI failures do not write stderr.
  • Serializes in-process codex exec calls to reduce Codex subscription refresh races during multi-agent runs.
  • Detects Codex refresh-token / websocket 401 failures and returns a clear codex logout / codex login recovery message.
  • Uses TRADINGAGENTS_CLAUDE_CODE_EXTRA_ARGS and TRADINGAGENTS_CODEX_EXTRA_ARGS for adapter-specific extra CLI flags.
  • Documents environment variables, example setup, stale installed-command troubleshooting, and Codex login refresh recovery in the README.
  • Adds focused unit coverage for provider creation, subprocess invocation, no-API-key behavior, custom model validation, tool-call JSON conversion, wrapper commands, stdout-only errors, Codex auth guidance, Codex serialization, and prefixed extra args.

Usage

Claude Code:

export TRADINGAGENTS_LLM_PROVIDER=claude-code
export TRADINGAGENTS_DEEP_THINK_LLM=opus
export TRADINGAGENTS_QUICK_THINK_LLM=sonnet

Codex:

export TRADINGAGENTS_LLM_PROVIDER=codex
export TRADINGAGENTS_DEEP_THINK_LLM=gpt-5.5
export TRADINGAGENTS_QUICK_THINK_LLM=gpt-5.4-mini

Optional overrides:

export TRADINGAGENTS_CLAUDE_CODE_COMMAND=claude
export TRADINGAGENTS_CLAUDE_CODE_TIMEOUT=600
export TRADINGAGENTS_CLAUDE_CODE_EXTRA_ARGS="--verbose"
export TRADINGAGENTS_CODEX_COMMAND=codex
export TRADINGAGENTS_CODEX_TIMEOUT=600
export TRADINGAGENTS_CODEX_EXTRA_ARGS="--profile trading"

If an installed tradingagents command keeps showing old Codex flags such as --ask-for-approval, refresh the installed command from the checkout:

python3 -m pip install --user -e .
python3 -c "import tradingagents, tradingagents.llm_clients.codex_client as c; print(tradingagents.__file__); print(c.__file__)"

Both paths should point at the current checkout, not stale site-packages files.

If Codex reports that its access token could not be refreshed, refresh the local subscription login:

codex logout
codex login

Validation

Focused regression suite:

PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /home/deadpool/.nix-profile/bin/uv run --python 3.13 --with pytest python -m pytest tests/test_codex_client.py tests/test_claude_code_client.py tests/test_api_key_env.py tests/test_model_validation.py -q

Result: 44 passed, 74 subtests passed.

Runtime-path verification after stale install report:

python3.10 -m pip install --user -e .
python3.10 -c "import tradingagents, cli.main, tradingagents.llm_clients.codex_client as c; print(tradingagents.__file__); print(cli.main.__file__); print(c.__file__)"

Result: imports resolve to /home/deadpool/Documents/TradingAgents/..., and Codex subprocess args no longer include --ask-for-approval.

Auth-error verification:

  • The installed editable package resolves tradingagents, cli.main, and codex_client.py to this checkout.
  • The installed Codex adapter exposes _CODEX_EXEC_LOCK and _codex_error_message.
  • Simulated Codex refresh-token failure returns codex logout and codex login guidance.

Local CLI presence checked:

  • claude 2.1.138 (Claude Code)
  • codex-cli 0.130.0

GitHub reports no checks configured for main, so local focused tests are the validation evidence for this PR.

Notes and limits

This is intentionally a subprocess adapter, not a replacement SDK. It constrains Codex to read-only sandbox mode and Claude Code to print mode with Claude Code tools disabled. TradingAgents data tools still execute through the existing LangGraph tool path.

Native structured output is not supported by these local CLI providers; existing free-text fallback paths handle structured-agent calls. If the Codex CLI refresh token is already invalid, TradingAgents cannot repair it; the user must refresh local Codex login state.

Latest auth-retry finish:

  • Added interactive Codex auth refresh retry: on refresh-token/auth failure, TradingAgents pauses in a TTY, lets the user run codex logout / codex login in another terminal, then retries the failed Codex call once.
  • Added TRADINGAGENTS_CODEX_AUTH_RETRY=0 to disable the pause for unattended runs.
  • Validation: python -m py_compile tradingagents/llm_clients/codex_client.py tests/test_codex_client.py passed.
  • Validation: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/tradingagents-uv-venv-313 /home/deadpool/.nix-profile/bin/uv run --python /home/deadpool/.nix-profile/bin/python3.13 --with pytest pytest tests/test_codex_client.py tests/test_claude_code_client.py tests/test_model_validation.py tests/test_api_key_env.py passed: 46 passed in 1.08s.

NagyVikt added 3 commits May 11, 2026 13:59
TradingAgents can already use Anthropic API keys, but a local Claude Code subscription/session needs a separate subprocess route. This adds an explicit experimental claude-code provider that invokes claude -p, disables Claude Code tools, and converts JSON tool-call requests back into LangGraph tool calls so TradingAgents remains the tool executor.

Constraint: Claude Code is a terminal agent, not a supported chat-completions API.

Rejected: Treat Claude Code as Anthropic API credentials | Claude Code login is not an API key.

Rejected: Let Claude Code use its own filesystem tools during model calls | TradingAgents must keep LangGraph as the tool execution boundary.

Confidence: medium

Scope-risk: moderate

Directive: Keep claude-code marked experimental unless real end-to-end tool-call runs are verified against the installed Claude Code CLI.

Tested: python -m py_compile on touched Python files; direct conda-env smoke check for factory, key mapping, validator, model catalog, subprocess args, and JSON tool-call conversion.

Not-tested: pytest suite; pytest is not installed in the conda env, and uv run pytest failed because a dependency build requires a Rust compiler.
Add local CLI-backed provider support so TradingAgents can use authenticated Claude Code or Codex installations without requiring provider API keys for those paths. Shared prompt/tool JSON handling stays in the Claude Code client module and the Codex adapter reuses that contract for parity.

Constraint: Local CLI providers must preserve TradingAgents LangGraph tool execution instead of allowing external agent tools to run inside the subprocess.

Rejected: Treat Codex as an OpenAI-compatible API provider | codex exec is a local CLI surface, not a chat-completions endpoint.

Confidence: high

Scope-risk: moderate

Directive: Keep local CLI adapters read-only/tool-disabled unless TradingAgents explicitly owns the tool execution boundary.

Tested: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/tradingagents-uv-venv-313 /home/deadpool/.nix-profile/bin/uv run --python /home/deadpool/.nix-profile/bin/python3.13 --with pytest pytest tests/test_claude_code_client.py tests/test_codex_client.py tests/test_model_validation.py tests/test_api_key_env.py

Not-tested: End-to-end live claude or codex CLI analysis run.
The installed codex exec command does not support --ask-for-approval, so the adapter now relies on read-only sandboxing without passing that obsolete flag.

Constraint: User hit runtime failure: unexpected argument '--ask-for-approval' from codex exec.

Rejected: Keep approval flag behind extra args | the local CLI rejects it before the adapter can return a model response.

Confidence: high

Scope-risk: narrow

Directive: Validate Codex adapter flags against codex exec --help before adding runtime options.

Tested: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/tradingagents-uv-venv-313 /home/deadpool/.nix-profile/bin/uv run --python /home/deadpool/.nix-profile/bin/python3.13 --with pytest pytest tests/test_codex_client.py tests/test_claude_code_client.py tests/test_model_validation.py tests/test_api_key_env.py

Tested: python -m py_compile tradingagents/llm_clients/codex_client.py tests/test_codex_client.py

Not-tested: Full live TradingAgents analysis after the user reruns from the shell.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces experimental support for claude-code and codex LLM providers, allowing the system to route calls through local CLI tools via subprocess adapters. The changes include new client implementations, configuration options, documentation, and comprehensive tests. Feedback focuses on ensuring robust subprocess execution by using shlex.split for multi-word commands, enhancing error reporting by capturing both stdout and stderr on failure, and maintaining consistent environment variable naming while removing redundant configuration logic.

Comment thread tradingagents/llm_clients/claude_code_client.py Outdated
Comment thread tradingagents/llm_clients/codex_client.py Outdated
Comment thread tradingagents/llm_clients/claude_code_client.py Outdated
Comment thread tradingagents/llm_clients/claude_code_client.py Outdated
Comment thread tradingagents/llm_clients/codex_client.py Outdated
Comment thread tradingagents/llm_clients/codex_client.py Outdated
@NagyVikt NagyVikt changed the title Codex claude code provider 2026 05 11 Route TradingAgents through Claude Code and Codex CLIs May 11, 2026
NagyVikt added 4 commits May 11, 2026 14:33
Gemini review flagged three reliability gaps in the new Claude Code and Codex adapters: wrapper commands were treated as single executable paths, stdout-only CLI failures lost their diagnostic text, and extra-args environment variables used unprefixed names inconsistent with the rest of TradingAgents config.

This keeps the adapters as subprocess-based providers while making command construction and diagnostics match normal shell wrapper use cases. Tests now pin multi-word wrapper commands, stdout fallback errors, and TRADINGAGENTS-prefixed extra args for both providers.

Constraint: Preserve the local subscription-routing design and avoid adding SDK dependencies.

Rejected: Keep legacy CLAUDE_CODE_* and CODEX_* env fallbacks | they conflict with the TRADINGAGENTS_* config contract and were dead when DEFAULT_CONFIG supplies command and timeout.

Confidence: high

Scope-risk: narrow

Directive: Validate CLI flags against installed claude/codex help before adding more subprocess options.

Tested: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /home/deadpool/.nix-profile/bin/uv run --python 3.13 --with pytest python -m pytest tests/test_claude_code_client.py tests/test_codex_client.py tests/test_api_key_env.py tests/test_model_validation.py -q

Tested: python -m py_compile tradingagents/llm_clients/claude_code_client.py tradingagents/llm_clients/codex_client.py tests/test_claude_code_client.py tests/test_codex_client.py

Not-tested: Live paid Claude Code/Codex TradingAgents run.
Users can run the installed tradingagents entry point after switching branches and still execute stale site-packages code. That makes already-fixed provider adapter flags look broken at runtime, as seen with the old Codex --ask-for-approval argument.

This adds a small troubleshooting note beside the Claude Code and Codex provider docs, showing how to reinstall from the checkout and verify that imports resolve to the current source tree.

Constraint: The runtime fix is installation state, not another adapter code path.

Rejected: Add compatibility fallback for old installed packages | stale package contents cannot be fixed from the source tree until the installed command is refreshed.

Confidence: high

Scope-risk: narrow

Directive: When local CLI provider behavior differs from branch code, verify import paths before changing adapter logic.

Tested: python -m py_compile tradingagents/llm_clients/codex_client.py tradingagents/llm_clients/claude_code_client.py

Not-tested: Markdown renderer preview.
TradingAgents can launch many local Codex subprocesses during one analysis, and the Codex CLI may also need to refresh subscription credentials. When that refresh token is already invalid, the raw CLI output floods the terminal with repeated 401 and refresh-token errors.

This serializes in-process codex exec calls to reduce refresh races and turns known Codex auth failures into one actionable error telling the user to run codex logout and codex login. The README now documents that local subscription-login recovery path.

Constraint: The adapter cannot repair an already-invalid Codex refresh token; only the Codex CLI login flow can.

Rejected: Retry failed codex exec calls automatically | repeated retries make invalid-token storms worse and cannot succeed until the user refreshes login state.

Confidence: high

Scope-risk: narrow

Directive: Keep subscription-auth failures explicit; do not hide them behind generic subprocess errors.

Tested: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /home/deadpool/.nix-profile/bin/uv run --python 3.13 --with pytest python -m pytest tests/test_codex_client.py tests/test_claude_code_client.py tests/test_api_key_env.py tests/test_model_validation.py -q

Tested: python -m py_compile tradingagents/llm_clients/codex_client.py tests/test_codex_client.py

Not-tested: Live Codex run after user reauthenticates with codex login.
Codex CLI auth can fail mid-analysis when its refresh token has been invalidated or the global account needs to be switched. The provider now detects that failure, pauses only in an interactive TTY, lets the user refresh Codex login in another terminal, and retries the failed model call once.

Constraint: TradingAgents shells out to the global codex CLI, so it cannot refresh Codex credentials itself.

Rejected: Always fail fast on Codex auth errors | interactive analysis runs can recover after a manual codex logout/login without losing the current TradingAgents flow.

Rejected: Retry indefinitely | repeated pauses can hang unattended runs and hide persistent auth failures.

Confidence: high

Scope-risk: narrow

Directive: Keep TRADINGAGENTS_CODEX_AUTH_RETRY=0 available for unattended or CI runs.

Tested: python -m py_compile tradingagents/llm_clients/codex_client.py tests/test_codex_client.py

Tested: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/tradingagents-uv-venv-313 /home/deadpool/.nix-profile/bin/uv run --python /home/deadpool/.nix-profile/bin/python3.13 --with pytest pytest tests/test_codex_client.py tests/test_claude_code_client.py tests/test_model_validation.py tests/test_api_key_env.py

Not-tested: Live interactive auth switch against a real expired Codex token.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant