fix: custom API endpoints for Codex/Claude/Gemini engines#21018
fix: custom API endpoints for Codex/Claude/Gemini engines#21018
Conversation
- codex_engine: declare OPENAI_BASE_URL → AWF LLM proxy when firewall enabled - claude_engine: declare ANTHROPIC_BASE_URL → AWF LLM proxy when firewall enabled - awf_helpers: add GEMINI_API_BASE_URL → --gemini-api-target support - codex_mcp: inject openai-compat model_provider in config.toml when OPENAI_BASE_URL is set in engine.env so any model name (e.g. openrouter/free) is accepted without the built-in openai provider falling back to gpt-5.3-codex Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@lpcox ler's chat about making something like this work |
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal!
💥 [THE END] — Illustrated by Smoke Claude
| GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com | ||
| GIT_COMMITTER_NAME: github-actions[bot] | ||
| OPENAI_API_KEY: ${{ secrets.CODEX_API_KEY || secrets.OPENAI_API_KEY }} | ||
| OPENAI_BASE_URL: http://host.docker.internal:10001/v1 |
There was a problem hiding this comment.
Consider documenting why host.docker.internal is used here — this is a Docker-specific hostname for accessing the host from inside a container. Worth a comment for clarity.
| -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && claude --print --disable-slash-commands --no-chrome --mcp-config /tmp/gh-aw/mcp-config/mcp-servers.json --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log | ||
| env: | ||
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| ANTHROPIC_BASE_URL: http://host.docker.internal:10000 |
There was a problem hiding this comment.
The ANTHROPIC_BASE_URL override looks correct for custom API endpoint support. Ensure the endpoint value is validated/sanitized at runtime to prevent SSRF if user-configurable.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal!
💥 [THE END] — Illustrated by Smoke Claude
| GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com | ||
| GIT_COMMITTER_NAME: github-actions[bot] | ||
| OPENAI_API_KEY: ${{ secrets.CODEX_API_KEY || secrets.OPENAI_API_KEY }} | ||
| OPENAI_BASE_URL: http://host.docker.internal:10001/v1 |
There was a problem hiding this comment.
Smoke test review comment #1: OPENAI_BASE_URL correctly points to the local AWF LLM proxy. This ensures custom API endpoints route through the firewall-aware proxy rather than directly to external services. ✅
| -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && claude --print --disable-slash-commands --no-chrome --mcp-config /tmp/gh-aw/mcp-config/mcp-servers.json --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log | ||
| env: | ||
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| ANTHROPIC_BASE_URL: http://host.docker.internal:10000 |
There was a problem hiding this comment.
Smoke test review comment #2: ANTHROPIC_BASE_URL added consistently across Claude engine steps. Good — this mirrors the Codex OPENAI_BASE_URL pattern and ensures all engines declare their proxy base URL. ✅
AWF Compatibility AnalysisChecked the AWF firewall codebase ( ✅ Fully Supported
❌ Gap:
|
|
Hey The PR is well-structured and looks ready for maintainer review once the draft flag is removed. Here's the checklist summary:
Verdict: 🟢 Aligned — quality: The only minor flag is that the PR is still in draft state. Once you're satisfied with CI results, marking it ready for review would be the next step. Everything else looks solid!
|
Summary
Fixes the "Custom API Endpoints doesn't work" issue where using
OPENAI_BASE_URLinengine.env(e.g. to use openrouter.ai) caused Codex to silently fall back to the defaultgpt-5.3-codexmodel instead of the user's configured model.Root cause
Codex's built-in
openaiprovider validates model names against a known list. When a custom model name likeopenrouter/freeis not recognised, it falls back to the default model rather than forwarding the name to the API. Additionally, the engines (Codex, Claude) did not explicitly declare their API base-URL env var, unlike Gemini which already declaredGEMINI_API_BASE_URL.Changes
codex_engine.go— DeclareOPENAI_BASE_URL = http://host.docker.internal:<CodexPort>/v1when the AWF firewall is enabled. A user-providedOPENAI_BASE_URLinengine.envstill overrides this viamaps.Copy; the AWF--openai-api-targetflag (already set byextractAPITargetHost) routes those proxy calls to the custom endpoint.claude_engine.go— Same pattern: declareANTHROPIC_BASE_URL = http://host.docker.internal:<ClaudePort>when firewall is enabled.awf_helpers.go— AddGEMINI_API_BASE_URL→--gemini-api-targetextraction alongside the existingOPENAI_BASE_URLandANTHROPIC_BASE_URLhandlers, completing coverage for all three variable-endpoint engines.codex_mcp.go— WhenOPENAI_BASE_URLis detected inengine.env, inject amodel_provider = "openai-compat"block at the top of the generatedconfig.toml(required by TOML: bare keys must precede section headers). The custom provider points itsbase_urlat the local AWF LLM proxy (host.docker.internal:<CodexPort>/v1); AWF's--openai-api-targetroutes those requests onward to the user's endpoint. Because the provider is user-defined rather than built-in, it passes model names through as-is — enabling e.g.model: "openrouter/free".How the user's example now works
OPENAI_BASE_URL→ emits--openai-api-target openrouter.aito AWFconfig.tomlgainsmodel_provider = "openai-compat"withbase_url = "http://host.docker.internal:10001/v1"model = "openrouter/free"(no validation, no fallback)openrouter.ai, which accepts the model nameSecurity Summary
No new security vulnerabilities introduced. CodeQL scan: 0 alerts.
✨ PR Review Safe Output Test - Run 23102624714
✨ PR Review Safe Output Test - Run 23110576257