Skip to content

fix: propagate models.providers custom pricing to api-proxy defaultAiCreditsPricing#47571

Open
pelikhan with Copilot wants to merge 9 commits into
mainfrom
copilot/fix-custom-pricing-models-providers
Open

fix: propagate models.providers custom pricing to api-proxy defaultAiCreditsPricing#47571
pelikhan with Copilot wants to merge 9 commits into
mainfrom
copilot/fix-custom-pricing-models-providers

Conversation

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

models.providers frontmatter pricing reached the agent-side GH_AW_MODELS_JSON_PATH catalog but was silently dropped from awf-config.json → apiProxy, so the proxy still rejected custom/BYOK models with unknown_model_ai_credits before the first turn. Detection sub-agent runs had the same issue since buildThreatDetectionWorkflowData never inherited ModelCosts.

Changes

  • awf_config.go — adds AWFDefaultAiCreditsPricingConfig struct and DefaultAiCreditsPricing field on AWFAPIProxyConfig; wires extractDefaultAiCreditsPricingFromModelCosts into BuildAWFConfigJSON to populate apiProxy.defaultAiCreditsPricing from WorkflowData.ModelCosts. Per-token cost strings (e.g. "3e-07") are converted to per-million-token floats required by the AWF schema. Model selection prefers an exact case-insensitive match on the workflow's model: field; falls back to the first parseable entry across all providers.

  • threat_detection_external.go — copies ModelCosts from parent WorkflowData into buildThreatDetectionWorkflowData so the detection guardrail config also carries the pricing fallback.

With this fix, a workflow like:

models:
  providers:
    anthropic:
      models:
        accounts/fireworks/models/minimax-m3:
          cost: { input: '3e-07', output: '1.5e-06', cache_read: '3e-08', cache_write: '3.75e-07' }

now produces "apiProxy": { ..., "defaultAiCreditsPricing": {"input": 0.3, "output": 1.5, "cachedInput": 0.03, "cacheWrite": 0.375} } in awf-config.json, unblocking both the main agent and the detection sub-agent.


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


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

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 18 AIC · ⌖ 10.1 AIC · ⊞ 7K ·
Comment /souschef to run again


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

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 12.1 AIC · ⌖ 9.05 AIC · ⊞ 7K ·
Comment /souschef to run again

@github-actions

Copy link
Copy Markdown
Contributor

Hey @Copilot 👋 — thanks for working on fixing custom pricing not reaching the api-proxy! This plan looks well-structured and ready for implementation.

Your checklist clearly maps out:

  • Schema changes to AWFAPIProxyConfig
  • Extraction logic for per-million-token conversion
  • Integration into BuildAWFConfigJSON and threat detection workflow
  • Unit test coverage
  • Build verification

The approach is focused and tied to #47365. Once you’re ready to implement, the plan is ready to go.

Note: This PR is currently a draft with 0 lines changed. Move to “Ready for review” once code changes are committed.

Generated by ✅ Contribution Check · sonnet46 56.5 AIC · ⌖ 10.2 AIC · ⊞ 6.2K ·

…CreditsPricing

- Add AWFDefaultAiCreditsPricingConfig struct and DefaultAiCreditsPricing field on AWFAPIProxyConfig
- Wire extractDefaultAiCreditsPricingFromModelCosts into BuildAWFConfigJSON so frontmatter
  models.providers pricing is included in apiProxy.defaultAiCreditsPricing in the AWF config
- Convert per-token cost strings from frontmatter to per-million-token floats required by AWF schema
- Copy ModelCosts from parent to buildThreatDetectionWorkflowData so detection sub-agent also
  gets the pricing fallback and does not 400 with unknown_model_ai_credits
- Add unit tests: TestExtractDefaultAiCreditsPricingFromModelCosts, TestBuildAWFConfigJSON_DefaultAiCreditsPricingFromModelCosts, TestValidateAWFConfigJSON_AllowsDefaultAiCreditsPricing, TestBuildThreatDetectionWorkflowData_InheritsModelCosts
- Update smoke-copilot golden file and recompile affected lock files

Fixes #47365

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix custom pricing not reaching the api-proxy fix: propagate models.providers custom pricing to api-proxy defaultAiCreditsPricing Jul 23, 2026
Copilot AI requested a review from pelikhan July 23, 2026 13:34
@pelikhan
pelikhan marked this pull request as ready for review July 23, 2026 13:57
Copilot AI review requested due to automatic review settings July 23, 2026 13:57

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

Propagates custom model pricing into AWF API-proxy configuration for main and threat-detection runs.

Changes:

  • Converts per-token model costs into AWF fallback pricing.
  • Propagates model costs to detection workflows.
  • Adds tests and regenerates workflow snapshots.
Show a summary per file
File Description
pkg/workflow/awf_config.go Adds pricing extraction and API-proxy configuration.
pkg/workflow/awf_config_test.go Tests pricing conversion and schema validation.
pkg/workflow/threat_detection_external.go Propagates costs to detection runs.
pkg/workflow/threat_detection_test.go Tests detection cost inheritance.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/smoke-copilot.golden Updates WASM golden output.
.github/workflows/smoke-copilot.lock.yml Regenerates smoke workflow output.
.github/workflows/daily-model-inventory.lock.yml Regenerates inventory workflow output.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (2)

pkg/workflow/awf_config.go:984

  • Valid integer-valued costs are rejected here. The frontmatter schema allows numbers, and goccy/go-yaml decodes unquoted YAML integers as uint64, so a valid input: 0 or output: 0 makes the entire pricing entry disappear. Handle the integer types produced by YAML in addition to float64.
	switch v := raw.(type) {
	case float64:
		perToken = v
	case string:
		parsed, err := strconv.ParseFloat(strings.TrimSpace(v), 64)
		if err != nil {
			return 0, false
		}
		perToken = parsed
	default:
		return 0, false

pkg/workflow/awf_config.go:986

  • ParseFloat accepts NaN, +Inf, and negative strings, but these are not valid AWF prices: non-finite values make json.Marshal fail, while negatives produce config rejected by the schema (minimum: 0). Since the frontmatter schema permits arbitrary numeric strings, reject non-finite or negative values here before multiplying.
		parsed, err := strconv.ParseFloat(strings.TrimSpace(v), 64)
		if err != nil {
			return 0, false
		}
		perToken = parsed
	default:
		return 0, false
	}
	return perToken * 1e6, true
  • Files reviewed: 7/7 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment thread pkg/workflow/awf_config.go Outdated

// First pass: find an exact match on workflowData.Model.
if targetModel != "" {
for _, pData := range providersMap {

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 commit fix: scope exact-match pricing pass to resolved engine provider.

The first pass now extracts resolvedProvider from EngineConfig.LLMProvider (falling back to InlineProviderID) and checks that provider entry exclusively before falling through to the sorted all-providers search. A helper searchProviderForModel eliminates the duplicated inner loop. Three new sub-tests cover the new behaviour: resolved-provider-wins, InlineProviderID-used-when-LLMProvider-empty, and falls-back-when-resolved-provider-lacks-the-model.

Comment thread pkg/workflow/awf_config.go Outdated
Comment on lines +902 to +903
// Second pass: return the first parseable entry across all providers.
for _, pData := range providersMap {
Comment thread pkg/workflow/awf_config.go Outdated
Comment on lines +286 to +288
// CachedInput is the price per 1M cached-read tokens, in USD.
// When omitted the proxy uses input × 0.1 as a default.
CachedInput float64 `json:"cachedInput,omitempty"`
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@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 /diagnosing-bugs, /tdd, and /codebase-design — requesting changes on two correctness issues and one test coverage gap.

📋 Key Themes & Highlights

Issues Found

  1. Non-deterministic fallback selection (awf_config.go lines 878–920): Both the first-pass (model match) and second-pass (first-entry fallback) iterate over map[string]any directly. Go map iteration is random; with multiple providers or models the selected pricing is unpredictable and untestable.
  2. CachedInput float64 vs *float64 (awf_config.go line 288): An explicitly-configured cache_read: "0" would be serialised as absent due to omitempty on a non-pointer float. CacheWrite correctly uses *float64; CachedInput should match.
  3. Detection sub-agent test gap (threat_detection_test.go): The new test only verifies shallow map inheritance, not that defaultAiCreditsPricing actually appears in the detection run's rendered AWF config JSON — the exact failure mode fixed by this PR.

Positive Highlights

  • ✅ Clean, well-commented implementation with clear selection-order documentation
  • ✅ Comprehensive unit tests for extractDefaultAiCreditsPricingFromModelCosts and parseCostFieldToPerMillion covering nil, empty, string, float64, and missing-field cases
  • ✅ Schema validation tests for defaultAiCreditsPricing (allow/reject paths)
  • ✅ Both the main agent and detection sub-agent are fixed in a single, coherent change

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 45.6 AIC · ⌖ 5.04 AIC · ⊞ 6.7K
Comment /matt to run again

Comment thread pkg/workflow/awf_config.go Outdated
if !ok {
continue
}
for _, mData := range modelsMap {

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.

[/diagnosing-bugs] Non-deterministic second-pass fallback: Go map iteration order is random, so when multiple providers or models are present, the pricing entry selected is unpredictable across runs. This could silently apply the wrong model's pricing.

💡 Suggested fix

Sort provider and model keys before iterating to guarantee a deterministic result (e.g. alphabetically first provider/model):

providerKeys := make([]string, 0, len(providersMap))
for k := range providersMap { providerKeys = append(providerKeys, k) }
sort.Strings(providerKeys)
for _, pName := range providerKeys {
    pData := providersMap[pName]
    // ... extract modelsMap ...
    modelKeys := make([]string, 0, len(modelsMap))
    for k := range modelsMap { modelKeys = append(modelKeys, k) }
    sort.Strings(modelKeys)
    for _, mName := range modelKeys {
        if pricing := modelCostEntryToDefaultPricing(modelsMap[mName]); pricing != nil {
            return pricing
        }
    }
}

The same non-determinism exists in the first pass (lines 878-899).

@copilot please address this.

Comment thread pkg/workflow/awf_config.go Outdated
Output float64 `json:"output"`
// CachedInput is the price per 1M cached-read tokens, in USD.
// When omitted the proxy uses input × 0.1 as a default.
CachedInput float64 `json:"cachedInput,omitempty"`

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.

[/codebase-design] CachedInput float64 with omitempty will silently drop an explicitly-configured zero cache-read price. Unlike CacheWrite *float64, a value of 0.0 is indistinguishable from absent for a non-pointer float64.

💡 Suggested fix

Use *float64 (pointer) for CachedInput to match the treatment of CacheWrite, making the zero-vs-omitted distinction explicit:

CachedInput *float64 `json:"cachedInput,omitempty"`

Then set it in modelCostEntryToDefaultPricing with &cachedInputPerM.

If the proxy truly treats zero and absent identically for cachedInput, add a comment explaining that invariant so future readers understand the asymmetry with CacheWrite.

@copilot please address this.

if providers == nil {
t.Fatal("expected detection ModelCosts to contain providers")
}
}

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] The new test verifies that ModelCosts is shallow-copied to the detection WorkflowData, but doesn't verify that defaultAiCreditsPricing is actually emitted in the rendered AWF config JSON for the detection run. The regression path that this fixes (unknown_model_ai_credits on the detection sub-agent) remains untested at the integration level.

💡 Suggested addition

Mirror the pattern from TestBuildAWFConfigJSON_DefaultAiCreditsPricingFromModelCosts but invoke through BuildAWFConfigJSON with a detection-flavoured WorkflowData (i.e. IsDetectionRun: true):

func TestBuildDetectionAWFConfig_PropagatesDefaultAiCreditsPricing(t *testing.T) {
    parent := &WorkflowData{
        AI:         "claude",
        ModelCosts: customPricing, // same map as above
    }
    detected := buildThreatDetectionWorkflowData(parent, "claude")
    cfg, err := BuildAWFConfigJSON(AWFCommandConfig{WorkflowData: detected, ...})
    require.NoError(t, err)
    assert.Contains(t, cfg, "defaultAiCreditsPricing")
}

This regression test would have caught the original bug directly.

@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.

Addressed in commit 6d28311. TestBuildDetectionAWFConfig_PropagatesDefaultAiCreditsPricing now calls BuildAWFConfigJSON with a detection WorkflowData built from a parent with custom ModelCosts and asserts that "defaultAiCreditsPricing" appears in the rendered JSON — directly testing the regression path.

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (498 new lines in pkg/workflow/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/47571-propagate-models-providers-pricing-to-api-proxy.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch at docs/adr/47571-propagate-models-providers-pricing-to-api-proxy.md — it was generated from the PR diff
  2. Complete the missing sections — add context the AI could not infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-47571: Propagate models.providers Custom Pricing to API Proxy defaultAiCreditsPricing

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 47571-propagate-models-providers-pricing-to-api-proxy.md for PR #47571).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 74.4 AIC · ⌖ 12.9 AIC · ⊞ 8.5K ·
Comment /review to run again

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 94/100 — Excellent

Analyzed 5 test(s): 5 design, 0 implementation, 0 violation(s).

📊 Metrics (5 tests)
Metric Value
Analyzed 5 (Go: 5, JS: 0)
✅ Design 5 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 4 (80%)
Duplicate clusters 0
Inflation No (1.7:1 max)
🚨 Violations 0
Test File Classification Issues
TestValidateAWFConfigJSON_AllowsDefaultAiCreditsPricing awf_config_test.go:1218 design_test None
TestValidateAWFConfigJSON_RejectsDefaultAiCreditsPricingMissingOutput awf_config_test.go:1223 design_test None
TestExtractDefaultAiCreditsPricingFromModelCosts awf_config_test.go:1828 design_test None (8 subtests, comprehensive)
TestBuildAWFConfigJSON_DefaultAiCreditsPricingFromModelCosts awf_config_test.go:1998 design_test None (3 subtests)
TestBuildThreatDetectionWorkflowData_InheritsModelCosts threat_detection_test.go:2705 design_test None

Verdict

Passed. 0% implementation tests (threshold: 30%). All tests verify design contracts. Comprehensive edge-case coverage with proper table-driven patterns and error scenarios. No coding guideline violations detected (no mock libraries, all tests properly tagged).

🧪 Test quality analysis by Test Quality Sentinel · haiku45 22.3 AIC · ⌖ 7.71 AIC · ⊞ 7.1K ·
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.

✅ Test Quality Sentinel: 94/100. 0% implementation tests (threshold: 30%).

@pelikhan

Copy link
Copy Markdown
Collaborator

/matt

@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.

REQUEST_CHANGES — Three correctness bugs must be fixed before merge; two affect the core pricing logic directly.

### Blocking issues (3)
  1. Non-deterministic second-pass fallback (awf_config.go ~line 184) — the "first parseable entry across all providers" is Go-map-random per run. Multi-model ModelCosts payloads can produce different pricing on identical inputs, silently under/over-counting credits.

  2. Exact-match failure falls through to wrong-model pricing (awf_config.go ~line 162) — when workflowData.Model matches a key but that entry's pricing is malformed (e.g. missing output), the code falls to the second pass and silently prices the run against a different model.

  3. Model not forwarded to detection WorkflowData (threat_detection_external.go line 566) — without Model, the detection run's extractDefaultAiCreditsPricingFromModelCosts always skips the exact-match pass and uses the non-deterministic fallback, potentially with different pricing than the main agent.

### Non-blocking but should be fixed (2)
  1. omitempty on CachedInput float64 (awf_config.go line 77) — explicit cache_read: 0 is silently dropped; use *float64 consistent with CacheWrite.

  2. No test for provider-prefix vs bare key mismatch (awf_config_test.go) — model: "openai/gpt-4o" with key "gpt-4o" silently falls to the wrong-model fallback; the behaviour is undefined and untested.

🔎 Code quality review by PR Code Quality Reviewer · sonnet46 88.4 AIC · ⌖ 5.34 AIC · ⊞ 5.7K
Comment /review to run again

Comments that could not be inline-anchored

pkg/workflow/awf_config.go:184

Non-deterministic second-pass fallback returns arbitrary pricing from a random model — Go map iteration is randomised per run, so the "first parseable entry across all providers" is not stable and can silently return different pricing on identical inputs.

<details>
<summary>💡 Details and fix</summary>

The second loop (lines ~167-185) iterates over providersMap and modelsMap, both map[string]any. Go randomises map iteration, meaning two identical invocations can return pricing from …

pkg/workflow/awf_config.go:162

Exact-match failure silently falls through to wrong-model pricing — when workflowData.Model is set and the key exists in the map but the entry has incomplete pricing (e.g. missing output), the function does not stop — it falls to the second pass and returns pricing from a completely different model.

<details>
<summary>💡 Details and fix</summary>

The first-pass loop (lines ~141-163):

for mName, mData := range modelsMap {
    if !strings.EqualFold(mName, targetModel) {
        co</details>

<details><summary>pkg/workflow/threat_detection_external.go:566</summary>

**`Model` not forwarded to detection `WorkflowData`exact-match pricing hint is lost**only `ModelCosts` is copied; without `Model`, the detection run always skips the exact-match first pass and falls to the non-deterministic second pass, potentially pricing it on a different model than the one actually running.

&lt;details&gt;
&lt;summary&gt;💡 Details and fix&lt;/summary&gt;

In `extractDefaultAiCreditsPricingFromModelCosts`, the first pass (exact model match) is gated on `workflowData.Model != &quot;&quot;`. When</details>

<details><summary>pkg/workflow/awf_config.go:77</summary>

**`omitempty` on `CachedInput float64` silently drops an explicit zero**if a model defines `cache_read: &quot;0&quot;`, the parsed value is `0.0`, which `omitempty` treats as absent, so the JSON omits the field entirely and the proxy applies its own default (`input × 0.1`) instead of the author&#39;s explicit zero cost.

&lt;details&gt;
&lt;summary&gt;💡 Details and fix&lt;/summary&gt;

The struct fields for the two optional pricing values are inconsistent:
```go
CachedInput float64  `json:&quot;cachedInput,omitempty&quot;` // drops…

</details>

<details><summary>pkg/workflow/awf_config_test.go:373</summary>

**No test for model name with provider prefix vs bare key mismatch** — the exact-match test uses the same string in both `WorkflowData.Model` and the map key, but the real failure case is `model: &quot;openai/gpt-4o&quot;` when the map key is `&quot;gpt-4o&quot;`, which would silently fall to the non-deterministic second pass.

&lt;details&gt;
&lt;summary&gt;💡 Suggested test case&lt;/summary&gt;

```go
t.Run(&quot;provider-prefix model name does not match bare key&quot;, func(t *testing.T) {
    wd := &amp;WorkflowData{
        Model: &quot;openai/g…

</details>

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

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

@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 /diagnosing-bugs and /tdd — requesting changes on two small correctness gaps and one test gap.

📋 Key Themes & Highlights

Key Themes

  • Non-deterministic fallback (correctness): second-pass map iteration is unordered in Go; pricing selection is non-deterministic when model: is unset and multiple custom models are defined.
  • Incomplete required-field test parity (test coverage): missing input → nil is tested but missing output → nil is not.
  • Silent parse failure (debuggability): malformed cost strings are swallowed with no signal; a test and/or log would surface this.
  • ADR is still Draft: update status to Accepted before merge.

Positive Highlights

  • ✅ Root cause properly addressed — per-token pricing is now forwarded to both the main agent config and the threat-detection sub-agent.
  • ✅ Clean three-function decomposition (extractentryToPricingparseCostField) — each function is independently testable.
  • ✅ Comprehensive test suite: nil inputs, string/float64 values, exact-match preference, case-insensitivity, all covered.
  • ✅ ADR documents the trade-offs including the known single-entry limitation and non-determinism — good transparency.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 67.7 AIC · ⌖ 7.77 AIC · ⊞ 6.7K
Comment /matt to run again

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot lint go

Copilot AI and others added 2 commits July 23, 2026 16:07
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI requested a review from gh-aw-bot July 23, 2026 16:15
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address the remaining unresolved review feedback, link the ADR in the PR body if still missing, and rerun checks once the branch is up to date.

Unresolved review feedback (newest first):

  • github-actions review submitted 2026-07-23T14:11:31Z
  • github-actions review submitted 2026-07-23T14:09:50Z

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

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.08 AIC · ⌖ 6.76 AIC · ⊞ 7K ·
Comment /souschef to run again

…ing through to second pass

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

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address the remaining unresolved review feedback, link the ADR in the PR body if still missing, and rerun checks once the branch is up to date.

Unresolved...

The two github-actions CHANGES_REQUESTED reviews (Matt Pocock Skills Reviewer at 14:09:50 and PR Code Quality Reviewer at 14:11:31) were submitted on 87243f1. All blocking issues they raised have now been addressed:

  1. Non-deterministic fallback → fixed in 6d28311 (sorted provider/model keys in both passes)
  2. Exact-match falls through to wrong-model pricing → fixed in b4df2d4searchProviderForModel now returns (pricing, keyFound bool); once a model-key match is found (even with malformed pricing), the function returns nil immediately instead of falling to the second pass
  3. Model not forwarded to detection WorkflowData → fixed in 6d28311
  4. CachedInput float64 should be *float64 → fixed in 6d28311
  5. Resolved engine provider not used for scoping → fixed in 31071fb

Local validation: make fmt, make lint, go test ./pkg/workflow/ all pass. CI re-trigger needed before merge.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🔴 High
Priority Score 72/100
Recommended Action fast_track

Score breakdown: Impact 35 + Urgency 22 + Quality 15

Rationale: Fixes a silent data-loss bug where custom/BYOK model pricing was dropped by api-proxy, breaking BYOK model billing. 30 files (mostly generated lock.yml). One APPROVED review alongside CHANGES_REQUESTED. High business impact. Needs expedited human review.

Generated by 🔧 PR Triage Agent · sonnet46 · 38.1 AIC · ⌖ 6.75 AIC · ⊞ 5.7K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address the unresolved blocking review feedback, and rerun checks once the branch is up to date.

Unresolved review feedback (newest first):

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

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 18 AIC · ⌖ 10.1 AIC · ⊞ 7K ·
Comment /souschef to run again

…defaultAiCreditsPricing

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

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address the unresolved blocking review feedback, and rerun checks once the branch is up to date.

Unresolved review feedback (newest first):...

All blocking issues from both CHANGES_REQUESTED reviews have been addressed:

  1. Non-deterministic second-pass fallback → fixed in 6d28311 (provider and model keys are now sorted before iteration)
  2. Exact-match failure falls through to wrong-model pricing → fixed in a273296 (searchProviderForModel returns nil, true when a key is found but pricing is malformed, stopping the fallback)
  3. Model not forwarded to detection WorkflowData → fixed in 6d28311
  4. CachedInput float64 should be *float64 → fixed in 6d28311
  5. Detection integration test gap → fixed in 6d28311 with TestBuildDetectionAWFConfig_PropagatesDefaultAiCreditsPricing
  6. Exact-match pass ignoring provider → fixed in 31071fb (scopes first pass to resolved engine provider)

Branch is now also updated from main (AWF v0.27.39 bump) with lock files regenerated. Local validation passes: make fmt, make lint, make test-unit all green.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review feedback, and rerun checks once the branch is up to date.

Unresolved requested changes:

  • @github-actions review feedback remains to be addressed.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 12.1 AIC · ⌖ 9.05 AIC · ⊞ 7K ·
Comment /souschef to run again

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review feedback, and rerun checks once the branch is up to date.

Unresolved requested changes:...

The two CHANGES_REQUESTED reviews from github-actions[bot] (#4764912832 and #4764929090) were submitted on commit 87243f1, which is now 8 commits behind HEAD. All blocking issues they raised have been fixed:

  1. Non-deterministic fallback → sorted provider/model keys (6d28311)
  2. Exact-match falls through to wrong-model pricing → searchProviderForModel returns early on malformed match (a273296)
  3. Model not forwarded to detection WorkflowData → fixed (6d28311)
  4. CachedInput float64 → changed to *float64 (6d28311)
  5. Detection integration test gap → TestBuildDetectionAWFConfig_PropagatesDefaultAiCreditsPricing added (6d28311)
  6. Exact-match ignores provider → scoped to resolved engine provider (31071fb)

These review states cannot be cleared by the agent — clearing them requires CI to re-run on the current HEAD so new reviews are generated, or a maintainer to dismiss the stale reviews manually.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, review the latest reply claiming the blocking review items are fixed, verify whether the remaining github-actions requested reviews are stale, and rerun checks once the branch is up to date.

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

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.7 AIC · ⌖ 9.18 AIC · ⊞ 7K ·
Comment /souschef to run again

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, review the latest reply claiming the blocking review items are fixed, verify whether the remaining github-actions requested reviews are stale, and rerun ch...

The two CHANGES_REQUESTED reviews (Matt Pocock Skills Reviewer #4764912832 and PR Code Quality Reviewer #4764929090) are stale — both were submitted on commit 87243f1, which is now 8 commits behind the current HEAD (4ab251e). Every blocking issue they raised has been resolved:

Issue Fix Commit
Non-deterministic second-pass fallback sort.Strings on provider + model keys before iteration 6d28311
Exact-match failure falls through to wrong-model pricing searchProviderForModel returns nil, true on malformed match, stopping fallback a273296
Model not forwarded to detection WorkflowData Added Model: data.Model in buildThreatDetectionWorkflowData 6d28311
CachedInput float64 with omitempty drops explicit zero Changed to *float64 matching CacheWrite 6d28311
Exact-match ignores provider First pass scoped to resolved engine provider (LLMProvider / InlineProviderID) 31071fb
Detection integration test gap TestBuildDetectionAWFConfig_PropagatesDefaultAiCreditsPricing asserts defaultAiCreditsPricing in rendered JSON 6d28311

Local validation status:

  • make fmt — clean
  • make lint — 0 issues
  • go test ./pkg/workflow/ (all pricing/detection tests) — all pass
  • ✅ Branch is up to date with main (base = c834b37, current top of main)

The CHANGES_REQUESTED state cannot be cleared by the agent — a maintainer must dismiss the stale reviews or re-run CI on the current HEAD (close/reopen or workflow_dispatch) so fresh reviews are generated. The last completed CI run (30043209671) passed with success on 4ab251e.

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.

models.providers custom pricing never reaches the api-proxy; custom/BYOK models still 400 with unknown_model_ai_credits

4 participants