peterhj/contradex

★ 1Forks 0PythonGitHub ↗Compare

README

Contradex

contradex is a Python extraction of the core turn loop from:

  • codex-cli/bin/codex.js (CLI handoff/spawn role)
  • codex-rs/core/src/codex.rs
  • codex-rs/core/src/stream_events_utils.rs
  • codex-rs/core/src/tools/parallel.rs
  • codex-rs/core/src/tools/router.rs

Mapping

  • codex_cli_entry(...)
    • mirrors the launcher role from codex-cli/bin/codex.js
  • run_agent_query_loop(...)
    • mirrors run_turn(...) outer loop behavior in codex.rs
  • run_sampling_request(...) / try_run_sampling_request(...)
    • mirrors request streaming + retry loop in codex.rs
  • handle_output_item_done(...)
    • mirrors classification of output items into tool calls vs non-tool items from stream_events_utils.rs
  • ToolCallRuntime
    • mirrors async tool dispatch behavior in tools/parallel.rs
  • build_tool_call(...)
    • mirrors tool-call parsing in tools/router.rs
  • LocalSummarizationPromptCompactor
    • mirrors local compaction path in compact.rs (run_inline_auto_compact_task, run_compact_task, build_compacted_history)
  • RemoteCompactApiCompactor
    • mirrors remote compact endpoint path in compact_remote.rs + ModelClient::compact_conversation_history in client.rs
  • ReferenceCompactor
    • mirrors strategy routing in codex.rs::run_auto_compact and tasks/compact.rs
  • run_pre_sampling_compact(...) / maybe_run_previous_model_inline_compact(...) / run_auto_compact(...)
    • mirrors compaction entrypoint flow in codex.rs
  • UrlLibResponsesModelClient
    • mirrors request/SSE/compact paths from core/src/client.rs and codex-api/src/sse/responses.rs, implemented with stdlib urllib
  • resolve_responses_api_auth(...) + find_codex_home(...)
    • mirrors auth source selection from core/src/auth.rs and CODEX_HOME resolution from utils/home-dir/src/lib.rs
  • resolve_responses_base_url(...)
    • mirrors provider base-url defaults from core/src/model_provider_info.rs::ModelProviderInfo::to_api_provider (api.openai.com/v1 vs chatgpt.com/backend-api/codex)
  • system_prompts.py
    • dedicated prompt constants file (base/system + compaction prompts)

Run

python3 -m contradex.cli "show me current working directory"

Live API mode (stdlib networking, gpt-5.3-codex + xhigh by default):

OPENAI_API_KEY=... python3 -m contradex.cli "review this repo" \
  --model-client urllib \
  --api-provider auto \
  --model gpt-5.3-codex \
  --reasoning-effort xhigh \
  --reasoning-summary auto

Use ChatGPT codex provider base URL:

python3 -m contradex.cli "review this repo" \
  --model-client urllib \
  --api-provider codex

Live auth resolution for --model-client urllib depends on --api-provider:

  1. --api-provider auto:
    • explicit --api-key
    • auth.json (default $CODEX_HOME/auth.json, fallback ~/.codex/auth.json)
    • OPENAI_API_KEY env var
    • auth.json follows auth_mode when present; otherwise it prefers OPENAI_API_KEY over tokens.access_token
  2. --api-provider api:
    • explicit --api-key
    • OPENAI_API_KEY env var
    • auth.json:OPENAI_API_KEY
  3. --api-provider codex:
    • explicit --api-key
    • auth.json:tokens.access_token

Base URL provider selection uses:

  1. --api-provider auto -> derived from the winning auth source
    • API key auth -> https://api.openai.com/v1
    • ChatGPT token auth -> https://chatgpt.com/backend-api/codex
  2. --api-provider api -> https://api.openai.com/v1
  3. --api-provider codex -> https://chatgpt.com/backend-api/codex
  4. optional --api-base-url overrides any preset

Use auth.json explicitly:

python3 -m contradex.cli "review this repo" \
  --model-client urllib \
  --auth-file ~/.codex/auth.json

This demo includes stubbed model/tool/compaction dependencies, while preserving the core loop semantics:

  1. send model request
  2. parse response actions
  3. execute tool calls in workspace
  4. append outputs and update state
  5. compact optionally
  6. repeat until no follow-up needed

Issues