Skip to content

Pass custom-provider models through verbatim for OPENAI_BASE_URL/ANTHROPIC_BASE_URL endpoints - #54363

Merged
pelikhan merged 4 commits into
mainfrom
copilot/fix-404-model-not-found
Aug 21, 2026
Merged

Pass custom-provider models through verbatim for OPENAI_BASE_URL/ANTHROPIC_BASE_URL endpoints#54363
pelikhan merged 4 commits into
mainfrom
copilot/fix-404-model-not-found

Conversation

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Routing an engine to a custom OpenAI/Anthropic-compatible provider (e.g. claude + OpenRouter via engine.env.ANTHROPIC_BASE_URL) fails with HTTP 404 model_not_found: the AWF API proxy resolves the requested model against its built-in catalog and rewrites it, and provider-specific slugs like anthropic/claude-sonnet-5 are not in that catalog. The existing workaround — sandbox.agent.model-fallback: false — was only documented for BYOK Azure OpenAI and had no reference section of its own.

Changes

  • pkg/workflow/awf_config.go — new hasCustomLLMAPITarget helper detects OPENAI_BASE_URL / ANTHROPIC_BASE_URL in engine.env. When present and sandbox.agent.model-fallback is unset, the compiler emits apiProxy.modelFallback: {"enabled": false} so the configured model reaches the provider unmodified. Explicit frontmatter (literal or expression) continues to take precedence.
  • pkg/workflow/awf_config_test.go — subtests for the Anthropic target, the OpenAI target, and explicit-override precedence.
  • docs/reference/engines.md — documents the pass-through default under "Custom API Endpoints via Environment Variables", adds the OpenRouter example, and points at token-steering: false as the secondary escape hatch.
  • docs/reference/sandbox.md — adds the missing sandbox.agent.model-fallback section (previously referenced only from the Azure BYOK guide).

This workflow now compiles to "modelFallback":{"enabled":false} in the generated awf-config:

engine:
  id: claude
  env:
    ANTHROPIC_BASE_URL: "https://openrouter.ai/api/v1"
    ANTHROPIC_API_KEY: ${{ secrets.OPENROUTER_KEY }}
network:
  allowed: [defaults, openrouter.ai]
model: anthropic/claude-sonnet-5

Recompiling the 286 workflows in this repository produced no lock-file changes, so no existing workflow is affected.

Copilot AI and others added 2 commits August 20, 2026 22:14
…ic endpoints

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix API proxy returning 404 for Anthropic model slugs Pass custom-provider models through verbatim for OPENAI_BASE_URL/ANTHROPIC_BASE_URL endpoints Aug 20, 2026
Copilot AI requested a review from pelikhan August 20, 2026 22:16
@pelikhan
pelikhan marked this pull request as ready for review August 20, 2026 23:17
Copilot AI balanced review requested due to automatic review settings August 20, 2026 23:17
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories (95 additions detected, threshold is 100).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer failed. Please review the logs for details.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Generated by Ponytail Reviewer for #54363

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-20T23:19:00Z
review_event: COMMENT
top_themes:
  - no actionable blocking issues found in changed lines
  - docs and tests cover the new custom-provider fallback default
files_reviewed:
  - docs/src/content/docs/reference/engines.md
  - docs/src/content/docs/reference/sandbox.md
  - pkg/workflow/awf_config.go
  - pkg/workflow/awf_config_test.go
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 4.55 AIC · ⌖ 6.76 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict

Non-blocking: I didn't find a changed-line correctness or security issue strong enough to block this PR.

Highlights
  • The new default is scoped behind explicit custom OpenAI/Anthropic base URLs and still yields to an explicit sandbox.agent.model-fallback setting.
  • The added tests cover both provider families plus the override path.
  • The docs now explain the behavior and the escape hatch, which matches the implementation.

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 4.55 AIC · ⌖ 6.76 AIC · ⊞ 7K
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean implementation. The else if guard ensures explicit sandbox.agent.model-fallback always wins over the auto-disable logic. hasCustomLLMAPITarget is correctly scoped to OPENAI_BASE_URL/ANTHROPIC_BASE_URL. Three test cases cover Anthropic URL, OpenAI URL, and explicit override. Documentation is accurate and cross-linked. No blocking issues.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 15.7 AIC · ⌖ 8.78 AIC · ⊞ 5.7K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /tdd — one edge case gap identified; requesting a minor change.

📋 Key Themes & Highlights

Key Themes

  • Expression-valued URL gap: hasCustomLLMAPITarget calls extractAPITargetHost, which returns "" for ${{ ... }} values. A workflow with ANTHROPIC_BASE_URL: ${{ vars.LLM_URL }} will not get the auto-disable, silently leaving model rewriting enabled and likely reproducing the original HTTP 404.

Positive Highlights

  • ✅ Clean, minimal hasCustomLLMAPITarget helper — well-placed in the precedence chain
  • ✅ Three subtests cover the main positive cases and explicit-override precedence
  • ✅ Documentation is accurate and cross-linked correctly; the OpenRouter example is immediately actionable
  • sandbox.md section fills a real gap (previously the field was only reachable via the Azure BYOK guide)
  • ✅ Recompile of 286 workflows with no lock-file changes is a strong regression guard

The single inline comment covers the expression-URL gap. If the fix is to check key presence instead of extractAPITargetHost, a small follow-up test documents the new behaviour.

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 34.6 AIC · ⌖ 10.1 AIC · ⊞ 7.8K
Comment /matt to run again

}

jsonStr, err := BuildAWFConfigJSON(config)
require.NoError(t, err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] Missing edge case: expression-valued ANTHROPIC_BASE_URL/OPENAI_BASE_URL (e.g. ${{ vars.LLM_URL }}) will silently skip the auto-disable because extractAPITargetHost returns "" for expression values, leaving hasCustomLLMAPITarget returning false.

💡 Suggested test and fix

Add a test to document the gap:

t.Run("model-fallback is NOT auto-disabled for expression-valued custom API target", func(t *testing.T) {
    config := AWFCommandConfig{
        EngineName: "claude",
        WorkflowData: &WorkflowData{
            EngineConfig: &EngineConfig{
                ID: "claude",
                Env: map[string]string{
                    "ANTHROPIC_BASE_URL": "${{ vars.LLM_URL }}",
                },
            },
            NetworkPermissions: &NetworkPermissions{Firewall: &FirewallConfig{Enabled: true}},
        },
    }
    jsonStr, err := BuildAWFConfigJSON(config)
    require.NoError(t, err)
    assert.NotContains(t, jsonStr, `"modelFallback"`)
})

If the intended behaviour for expression-valued URLs is also to disable fallback (which seems correct — the user is clearly targeting a custom provider), hasCustomLLMAPITarget should check for key presence rather than a non-empty extractAPITargetHost return:

func hasCustomLLMAPITarget(workflowData *WorkflowData) bool {
    env := getEngineEnvOverrides(workflowData)
    if env == nil {
        return false
    }
    for _, envVar := range []string{"OPENAI_BASE_URL", "ANTHROPIC_BASE_URL"} {
        if val, ok := env[envVar]; ok && val != "" {
            return true
        }
    }
    return false
}

This would correctly handle ANTHROPIC_BASE_URL: ${{ vars.LLM_URL }}.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 37ba5e4. hasCustomLLMAPITarget now treats non-empty OPENAI_BASE_URL/ANTHROPIC_BASE_URL env values (including expressions like ${{ vars.LLM_URL }}) as custom targets, and I added a regression test that verifies modelFallback auto-disables for expression-valued custom API targets.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Disables AWF model fallback automatically for custom OpenAI- and Anthropic-compatible endpoints, preserving provider-specific model identifiers.

Changes:

  • Detects custom LLM API targets and emits modelFallback.enabled: false.
  • Adds coverage for both providers and explicit overrides.
  • Documents automatic behavior and manual controls.
Show a summary per file
File Description
pkg/workflow/awf_config.go Implements custom-endpoint detection and fallback defaults.
pkg/workflow/awf_config_test.go Tests endpoint detection and override precedence.
docs/src/content/docs/reference/engines.md Documents custom-provider model handling.
docs/src/content/docs/reference/sandbox.md Documents model fallback configuration.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Balanced

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR Triage

Category: bug · Risk: medium · Priority: medium

Score: 56/100 (impact 25/50 + urgency 15/30 + quality 16/20)

Recommended action: fast_track

Focused fix with docs+tests, CI passing, addition-only diff.

Automated triage — run 32432526976

Generated by 🔧 PR Triage Agent · auto · 63.7 AIC · ⌖ 4.49 AIC · ⊞ 8.3K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Quick triage nudge for PR #54363.

Run: https://github.com/github/gh-aw/actions/runs/32434686968

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 20.3 AIC · ⌖ 6.12 AIC · ⊞ 5.5K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Quick triage nudge for PR #54363.

  • Failed checks to investigate:...

Addressed in 37ba5e4:

  • Fixed lint-go by updating AWF config error messages to meet error-quality lint requirements.
  • Addressed the requested edge case by treating expression-valued ANTHROPIC_BASE_URL/OPENAI_BASE_URL as custom API targets and added a regression test.
  • Investigated agent failure: it was a cloud-hypervisor guest connectivity probe failure in the runner environment (infrastructure-level, not reproducible as a code issue locally).

Copilot AI requested a review from gh-aw-bot August 21, 2026 01:32
@pelikhan
pelikhan merged commit 4bc3639 into main Aug 21, 2026
31 checks passed
@pelikhan
pelikhan deleted the copilot/fix-404-model-not-found branch August 21, 2026 03:17
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.87.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Claude engine + ANTHROPIC_BASE_URL (OpenRouter): api-proxy 404s current Anthropic model slugs

4 participants