fix(claude): inject COPILOT_GITHUB_TOKEN, scope ANTHROPIC_BASE_URL to Anthropic provider, fix provider-aware api-proxy reflect check, convert Copilot env vars to Anthropic vars in harness, fix smoke model for reasoning effort, and mark model-provider: ...#40930
Conversation
…i-proxy configuration
When model-provider: github is used with the claude engine, the compiled workflow
sets ANTHROPIC_API_KEY=${{ secrets.COPILOT_GITHUB_TOKEN }} and routes ANTHROPIC_BASE_URL
to port 10002 (copilot provider). However, the api-proxy container needs COPILOT_GITHUB_TOKEN
set directly in the host environment to configure the copilot backend at that port.
Without COPILOT_GITHUB_TOKEN in the step env, the api-proxy copilot provider shows ❌
(unconfigured) and every inference request returns 401 Unauthorized.
The fix injects COPILOT_GITHUB_TOKEN alongside ANTHROPIC_API_KEY when firewall is enabled
and model-provider is github. The --exclude-env COPILOT_GITHUB_TOKEN flag already prevents
the raw token from reaching the agent container.
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
@copilot the Anthropic API key is not needed when the provider is github. Only needed for the Anthropic provider.
There was a problem hiding this comment.
Fixed — ANTHROPIC_API_KEY is now only injected when provider == LLMProviderAnthropic. For the GitHub/Copilot provider, only COPILOT_GITHUB_TOKEN is set. The lock file and test have been updated accordingly.
…t GitHub Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
| -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),mcp__github__actions_get,mcp__github__actions_list,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__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__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,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode acceptEdits --output-format stream-json --bare --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log | ||
| env: | ||
| ANTHROPIC_API_KEY: ${{ secrets.COPILOT_GITHUB_TOKEN }} | ||
| ANTHROPIC_BASE_URL: http://host.docker.internal:10002 |
There was a problem hiding this comment.
@copilot make sure the base url matches the selected provider
There was a problem hiding this comment.
Fixed — ANTHROPIC_BASE_URL is now set for all providers when the firewall is enabled, using llmProviderGatewayBaseURL(provider) which returns the correct port per provider (Anthropic → 10000, GitHub → 10002). The golden file and lock file have been updated accordingly.
…s enabled Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
/smoke-claude-on-copilot |
|
❌ Smoke Claude on Copilot failed. Please review the logs for details. |
|
@copilot the check for the api proxy must be aware for the provider endpoint. See failure https://github.com/github/gh-aw/actions/runs/28002330929/job/82877200032#step:26:1 |
…arness Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Fixed in the latest commit. The root cause was that Changes:
|
|
/smoke-claude-on-copilot |
|
❌ Smoke Claude on Copilot failed. Please review the logs for details. |
Fixed in the latest commit. Added |
…EN doc in buildClaudeGitHubProviderEnv Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
/smoke-claude-on-copilot |
|
❌ Smoke Claude on Copilot failed. Please review the logs for details. |
There was a problem hiding this comment.
Pull request overview
This PR fixes Claude/Copilot (GitHub provider) execution under the AWF firewall by correctly wiring provider-specific env vars and by making the harness/reflect probing provider-aware so it queries the api-proxy port that is actually started.
Changes:
- Update Claude engine env injection to (a) only set
ANTHROPIC_*for the Anthropic provider and (b) injectCOPILOT_GITHUB_TOKENfor the GitHub provider when the firewall is enabled. - Add provider→port mapping and provider-aware reflect URL resolution in the JS harness/reflection helpers; update Claude harness to use the provider-aware reflect URL and to translate GitHub-provider env into Anthropic vars for the Claude CLI subprocess.
- Recompile goldens/lockfiles to reflect the new
ANTHROPIC_BASE_URLbehavior for the Anthropic provider.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/claude_engine.go | Adjust provider-scoped env injection (ANTHROPIC_* vs COPILOT_GITHUB_TOKEN) for AWF + Claude. |
| pkg/workflow/claude_engine_test.go | Update/add tests for GitHub-provider and Anthropic+firewall gateway port behavior. |
| pkg/workflow/testdata/TestWasmGolden_AllEngines/claude.golden | Update golden to include Anthropic firewall gateway ANTHROPIC_BASE_URL (port 10000). |
| actions/setup/js/awf_reflect.cjs | Add provider→port mapping and resolveAWFReflectUrl() helper for provider-aware /reflect URL selection. |
| actions/setup/js/awf_reflect.test.cjs | Add tests covering provider-aware reflect URL resolution and port table export. |
| actions/setup/js/claude_harness.cjs | Use provider-aware reflect URL; add GitHub-provider env conversion for Claude CLI subprocess. |
| actions/setup/js/claude_harness.test.cjs | Add tests for GitHub-provider env conversion helper. |
| .github/workflows/typist.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/test-create-pr-error-handling.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/step-name-alignment.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/static-analysis-report.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/smoke-claude.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/smoke-agent-scoped-approved.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/smoke-agent-public-none.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/smoke-agent-public-approved.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/smoke-agent-all-none.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/smoke-agent-all-merged.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/sergo.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/semantic-function-refactor.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/scout.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/safe-output-health.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/ruflo-backed-task.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/prompt-clustering-analysis.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/portfolio-analyst.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/lockfile-stats.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/instructions-janitor.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/hourly-ci-cleaner.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/go-pattern-detector.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/go-logger.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/github-mcp-tools-report.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/github-mcp-structural-analysis.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/example-workflow-analyzer.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/developer-docs-consolidator.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/design-decision-gate.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/deep-report.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-token-consumption-report.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-team-evolution-insights.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-security-red-team.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-safeoutputs-git-simulator.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-safe-outputs-conformance.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-safe-output-optimizer.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-rendering-scripts-verifier.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-reliability-review.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-doc-healer.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-code-metrics.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-choice-test.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-caveman-optimizer.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-aw-cross-repo-compile-check.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-astrostylelite-markdown-spellcheck.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/daily-agentrx-trace-optimizer.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/copilot-session-insights.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/copilot-agent-analysis.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/cloclo.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/cli-version-checker.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/claude-code-user-docs-review.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/ci-doctor.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/blog-auditor.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/aw-failure-investigator.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/avenger.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/audit-workflows.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/approach-validator.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
| .github/workflows/api-consumption-report.lock.yml | Recompiled: add Anthropic firewall ANTHROPIC_BASE_URL (port 10000) where applicable. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 64/64 changed files
- Comments generated: 2
| * The /reflect endpoint is exposed by the api-proxy sidecar on each started provider port. | ||
| * The active provider's gateway port should be used rather than a hardcoded port, since | ||
| * port 10000 (the OpenAI sidecar) is only started when OpenAI credentials are configured. | ||
| * Use resolveAWFReflectUrl() to obtain the correct URL for the active provider, since only | ||
| * the ports whose provider credentials are configured are actually started. | ||
| * This information is saved to AWF_REFLECT_OUTPUT_PATH so the post-run GitHub Actions step |
| // When using the GitHub/Copilot provider (model-provider: github), the api-proxy container | ||
| // needs COPILOT_GITHUB_TOKEN in the host environment to configure the copilot provider at | ||
| // port CopilotLLMGatewayPort. COPILOT_GITHUB_TOKEN is already excluded from the agent | ||
| // container via ExcludeEnvVarNames, so injecting it here only makes it available to the | ||
| // api-proxy, not to the agent process. |
|
@copilot review all comments and address unresolved review feedback.
|
…ort reasoning effort Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
The failure at step 26 was: Root cause: the Copilot proxy at port 10002 correctly receives Claude CLI requests (routing is working), but Fix: changed the smoke workflow model from |
|
/smoke-claude-on-copilot |
|
❌ Smoke Claude on Copilot failed. Please review the logs for details. |
|
@copilot mark this feature as experimental |
|
@copilot please reply to the latest request with the current status and remaining experimental caveats.
|
…aude) Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done — added an experimental feature warning in |
|
``
|
|
``
|
With
model-provider: github, the claude engine never setCOPILOT_GITHUB_TOKENdirectly. The AWF api-proxy readsCOPILOT_GITHUB_TOKENfrom the host env to configure the copilot backend — without it, port 10002 showed❌and every inference call returned 401. Additionally,ANTHROPIC_BASE_URLwas not being set for the Anthropic provider when the firewall was enabled, causing traffic to bypass the Claude gateway proxy. Theclaude_harness.cjsalways fetched the api-proxy/reflectendpoint on the hardcoded Anthropic port (10000), which is never started when only GitHub/Copilot credentials are configured. Claude CLI inside the agent container had noANTHROPIC_BASE_URLorANTHROPIC_API_KEYwhenmodel-provider: githubwas used, so it could not route requests through the Copilot api-proxy at port 10002. Finally, the smoke workflow usedclaude-haiku-4.5which does not support theoutput_config.effort: "high"parameter that Claude CLI sends whenCLAUDE_CODE_DISABLE_FAST_MODE=1, causing GitHub Copilot API to return 400 on every inference call.Changes
pkg/workflow/claude_engine.go:ANTHROPIC_API_KEYis now only injected whenprovider == LLMProviderAnthropic; it is not needed for the GitHub/Copilot provider.ANTHROPIC_BASE_URLis now only set whenprovider == LLMProviderAnthropicand the firewall is enabled (port 10000). It is not set for the GitHub/Copilot provider — Claude CLI does not route GitHub Copilot requests throughANTHROPIC_BASE_URL, so setting it to port 10002 caused the agent step to fail.provider == LLMProviderGitHub,COPILOT_GITHUB_TOKENis injected into the step env. The existing--exclude-env COPILOT_GITHUB_TOKENAWF flag already prevents the token from reaching the agent container.pkg/workflow/claude_engine_test.go— updates assertions:ANTHROPIC_API_KEYandANTHROPIC_BASE_URLmust not be present when using the GitHub provider;COPILOT_GITHUB_TOKENmust be present;TestClaudeEngineLLMProviderAnthropicFirewallUsesClaudeGatewayPortasserts port 10000 is used for Anthropic with firewall enabled.pkg/workflow/testdata/TestWasmGolden_AllEngines/claude.golden— updated to includeANTHROPIC_BASE_URL: http://host.docker.internal:10000for the Anthropic provider..github/workflows/smoke-claude-on-copilot.md— changed model fromclaude-haiku-4.5toclaude-opus-4.7.claude-haiku-4.5does not support theoutput_config.effort: "high"parameter that Claude CLI sends whenCLAUDE_CODE_DISABLE_FAST_MODE=1;claude-opus-4.7supports reasoning effort and works correctly with the Copilot api-proxy..github/workflows/smoke-claude-on-copilot.lock.yml— recompiled;ANTHROPIC_API_KEYandANTHROPIC_BASE_URLno longer appear in the GitHub provider execution step;COPILOT_GITHUB_TOKENis set for the GitHub provider; model updated toclaude-opus-4.7; the Anthropic detection step retainsANTHROPIC_BASE_URL: http://host.docker.internal:10000.actions/setup/js/awf_reflect.cjs— addedAWF_API_PROXY_PROVIDER_PORTStable (anthropic→10000,openai→10001,github→10002) andresolveAWFReflectUrl(providerOverride?)helper that readsGH_AW_LLM_PROVIDERto return the correct api-proxy/reflectURL for the active provider. The AWF api-proxy only starts the sidecar ports whose credentials are configured; using a hardcoded port for the wrong provider results in a connection failure.actions/setup/js/claude_harness.cjs:fetchAWFReflectcalls now passreflectUrl: resolveAWFReflectUrl()so the correct provider port is queried (e.g. port 10002 for GitHub/Copilot instead of the default Anthropic port 10000).buildClaudeGitHubProviderEnv()helper: whenGH_AW_LLM_PROVIDER=github, it injectsANTHROPIC_BASE_URL=http://api-proxy:10002andANTHROPIC_API_KEY=copilot(placeholder; the api-proxy handles Copilot authentication itself viaCOPILOT_GITHUB_TOKENfrom the runner's host environment) into the Claude CLI subprocess env. This converted env is passed to everyrunProcesscall in the retry loop.actions/setup/js/awf_reflect.test.cjs— new tests forresolveAWFReflectUrlcovering all three providers,GH_AW_LLM_PROVIDERenv var reading, unknown-provider fallback, and case-insensitivity.actions/setup/js/claude_harness.test.cjs— new tests forbuildClaudeGitHubProviderEnvcovering non-github providers returningundefined, correctANTHROPIC_BASE_URL/ANTHROPIC_API_KEYinjection for the github provider, preservation of existing env vars, and case-insensitivity.pkg/workflow/compiler_validators.go— added an experimental feature warning that fires when the Claude engine is configured withengine.model-provider: github. The warning"Using experimental feature: engine.model-provider: github (claude)"is emitted at compile time to signal that this provider combination is not yet stable.pkg/workflow/compiler_validators_test.go— new tests for the experimental warning covering: github provider → warning emitted, anthropic provider → no warning, no provider → no warning, non-claude engine with github provider → no warning, nil engine config → no warning.