Skip to content

Bundle models.dev catalog for AI credits model resolution#4589

Merged
lpcox merged 7 commits into
mainfrom
copilot/bundle-catalog-json-from-models-dev
Jun 9, 2026
Merged

Bundle models.dev catalog for AI credits model resolution#4589
lpcox merged 7 commits into
mainfrom
copilot/bundle-catalog-json-from-models-dev

Conversation

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

AWF should be able to resolve model pricing and existence from a bundled models.dev catalog, instead of relying only on the curated pricing table or user-supplied fallback pricing. This adds a catalog-backed fallback so AI credits accounting can recognize more models, including zero-cost/free entries, before treating them as unknown.

  • Catalog-backed model resolution

    • Adds a bundled models.dev catalog JSON to the api-proxy.
    • Introduces a small resolver that normalizes catalog entries into AWF’s pricing shape and canonical model naming.
  • AI credits fallback behavior

    • Keeps the existing curated pricing table as the highest-precedence source.
    • Falls back to the bundled catalog when a model is not in the curated table.
    • Continues to use defaultAiCreditsPricing only when neither the curated table nor the bundled catalog can resolve the model.
  • Known free / zero-cost models

    • Treats zero-cost catalog entries as known models with zero AI credit impact.
    • Prevents these models from being rejected as “unknown” when maxAiCredits is enabled.
  • Guard behavior updates

    • Unknown-model rejection now only applies after curated pricing, bundled catalog lookup, and optional default pricing have all failed.
    • Existing warning/rejection semantics for truly unresolved models remain unchanged.
  • Docs and tests

    • Updates the config spec to describe the bundled catalog fallback.
    • Adds focused coverage for:
      • catalog-only priced models
      • zero-cost/free models
      • token budget behavior now that catalog-backed models are recognized

Example of the new fallback path:

// Before: treated as unknown unless explicitly configured
applyAiCreditsUsage({ input_tokens: 100, output_tokens: 10 }, 'perceptron/perceptron-mk1');

// After: resolved via bundled models.dev catalog pricing
// -> returns aiCreditsThisResponse / totalAiCredits instead of null

Copilot AI linked an issue Jun 9, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add catalog.json bundling from models.dev for cost queries Bundle models.dev catalog for AI credits model resolution Jun 9, 2026
Copilot AI requested a review from lpcox June 9, 2026 14:22
Copilot finished work on behalf of lpcox June 9, 2026 14:22
@lpcox lpcox marked this pull request as ready for review June 9, 2026 15:21
Copilot AI review requested due to automatic review settings June 9, 2026 15:21
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 48d6695

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 96.43% 96.47% 📈 +0.04%
Statements 96.35% 96.39% 📈 +0.04%
Functions 98.76% 98.76% ➡️ +0.00%
Branches 90.72% 90.75% 📈 +0.03%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/config-writer.ts 89.3% → 90.9% (+1.65%) 89.3% → 90.9% (+1.65%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

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

This PR adds a bundled models.dev catalog to the api-proxy and uses it as a fallback source for AI-credits model pricing resolution (after the curated in-repo pricing table), improving recognition of more models including zero-cost entries.

Changes:

  • Added a bundled models.dev catalog JSON plus a resolver to normalize catalog pricing into AWF’s $ / 1M tokens pricing shape.
  • Updated the AI credits guard to consult the bundled catalog when the curated pricing table can’t resolve a model.
  • Updated docs and tests to cover catalog-priced models, zero-cost models, and adjusted token budget tests for newly-recognized models.
Show a summary per file
File Description
docs/awf-config-spec.md Documents the new catalog-backed fallback behavior for default pricing and unknown-model rejection.
containers/api-proxy/ai-credits-pricing.js Clarifies that the in-repo pricing table is curated and takes precedence over the bundled catalog.
containers/api-proxy/models.dev.catalog.json Adds the bundled models.dev catalog data used for fallback resolution.
containers/api-proxy/models-dev-catalog.js Implements catalog indexing and pricing normalization/resolution.
containers/api-proxy/models-dev-catalog.test.js Adds unit tests for catalog pricing and zero-cost models.
containers/api-proxy/guards/ai-credits-guard.js Integrates catalog-backed fallback into AI credits pricing resolution.
containers/api-proxy/guards/ai-credits-guard.test.js Adds coverage for catalog-priced and zero-cost models in the AI credits guard.
containers/api-proxy/token-budget-log.test.js Adjusts tests to use a truly-unknown model now that common models may be recognized via the catalog.

Copilot's findings

Tip

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

  • Files reviewed: 7/8 changed files
  • Comments generated: 4

Comment thread containers/api-proxy/models-dev-catalog.js
Comment on lines +17 to +29
it('recognizes zero-cost catalog models', () => {
expect(resolveCatalogModel('google/gemma-4-31b-it:free')).toEqual({
exists: true,
pricing: {
input: 0,
cachedInput: 0,
cacheWrite: null,
output: 0,
},
zeroCost: true,
});
});
});

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.

Added regression test in commit c200251openrouter/pareto-code (which carries prompt/completion: "-1" in the bundled catalog) asserts pricing: null, zeroCost: false.

Comment thread docs/awf-config-spec.md
Comment on lines +738 to +740
When configured, any model not found in the curated built-in pricing table or
the bundled models.dev catalog uses these rates as a fallback for AI credits
calculation.

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.

Updated in commit c200251 — section 10.7.1 now describes the curated-table → bundled-catalog two-step lookup, the defaultAiCreditsPricing fallback, and zero-cost model handling.

Comment on lines +85 to +99
let prefixMatch = null;
for (const [knownModel, pricing] of pricingByModel.entries()) {
if (canonical.startsWith(`${knownModel}-`)) {
if (!prefixMatch || knownModel.length > prefixMatch.key.length) {
prefixMatch = { key: knownModel, pricing };
}
}
}

if (prefixMatch) {
return { exists: true, pricing: prefixMatch.pricing, zeroCost: isZeroCostPricing(prefixMatch.pricing) };
}

return { exists: knownModels.has(canonical), pricing: null, zeroCost: false };
}

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.

Replaced in commit c200251 with iterative '-' segment stripping that checks the Map at each step — O(k) where k is the number of dash segments, no full scan.

@lpcox

lpcox commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

@copilot address review feedback and merge main

Copilot AI added 2 commits June 9, 2026 19:18
- Reject negative sentinel pricing values (e.g. "-1") in parseDollarsPerToken
- Replace O(N) prefix scan with O(k) iterative '-' segment stripping
- Add regression test for negative sentinel pricing entries
- Update docs section 10.7.1 to describe curated-table → bundled-catalog fallback"

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address review feedback and merge main

Done — all four review items addressed and main merged in commit fix(api-proxy): address catalog resolver review feedback:

  1. Negative sentinel pricing (parseDollarsPerToken): added || parsed < 0 guard so values like "-1" return null instead of a negative price.
  2. Regression test: added a test case for openrouter/pareto-code (which carries "-1" sentinel prices in the bundled catalog) asserting pricing: null.
  3. Docs 10.7.1: expanded the "Model Name Resolution for Pricing" subsection to describe the curated-table → bundled-catalog two-step fallback, including zero-cost model handling.
  4. O(k) prefix search: replaced the full pricingByModel iteration with iterative '-' segment stripping that checks the Map at each step — longest prefix match is found on the first hit.

Copilot finished work on behalf of lpcox June 9, 2026 19:20
@lpcox

lpcox commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Done. Here's the summary:

  • Reviews — All four reviewer threads addressed (negative pricing guard, regression test, docs 10.7.1, O(k) prefix search). Thread 1 was resolved in the previous session; threads 2–4 addressed in commit c200251 and replied to.
  • Checks (local)npm run lint (0 errors), npm run build (clean), npm run test:unit (2458 tests / 122 suites passed), api-proxy jest (3 catalog tests passed). Pre-existing api-proxy suite failures on missing npm deps (https-proxy-agent, etc.) exist on main and are unrelated to this PR.
  • Checks (CI) — Stale after agent push; needs human re-trigger. Prior CI runs were on earlier HEAD.
  • Mergeable — Branch is open, non-draft, up to date with main (merged in this session).

Hand-off: CI must be re-triggered by a maintainer (close/reopen, workflow_dispatch, or push) before merge.

The new module is required by ai-credits-pricing.js but was missing from
the container image, causing MODULE_NOT_FOUND at runtime.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The JSON catalog file is required by models-dev-catalog.js at runtime.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct) Mode ✅

Test Results:

  • ✅ GitHub MCP connectivity (api-proxy sidecar → api.githubcopilot.com working)
  • ✅ BYOK inference path functional (direct COPILOT_PROVIDER_API_KEY mode)
  • ✅ Running in direct BYOK mode via api-proxy sidecar

Status: PASS — Agent has access via api-proxy; real credentials held by sidecar only.

cc/ @lpcox @Copilot

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct) Mode — Azure OpenAI (Foundry, Entra / GitHub OIDC)

• GitHub MCP Connectivity: ✅
• GitHub.com Connectivity: ✅
• File Write/Read Test: ✅
• BYOK Inference Test: ✅

Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra

@lpcox PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.openai.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.openai.com"

See Network Configuration for more information.

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

GitHub API: ✅ PASS
GitHub check: ✅ PASS
File verify: ✅ PASS

Total: PASS

💥 [THE END] — Illustrated by Smoke Claude

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🔬 Smoke Test Results

PR: Bundle models.dev catalog for AI credits model resolution
Author: @Copilot | Assignees: @lpcox, @Copilot

Test Status
GitHub MCP connectivity
GitHub.com connectivity (HTTP 200)
File write/read ⚠️ pre-step data unavailable (template vars unresolved)

Overall: PASS (2/2 verified tests passed)

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🧪 Chroot Runtime Version Comparison

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3 ❌ NO
Node.js v24.16.0 v22.22.3 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Result: FAILED — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🔬 Smoke Test: API Proxy OpenTelemetry Tracing

Scenario Result Detail
1 · Module Loading otel.js loads cleanly; exports: startRequestSpan, setTokenAttributes, endSpan, endSpanError, shutdown, isEnabled + internal helpers
2 · Test Suite 35 passed, 0 failed (otel.test.js — 1 suite)
3 · Env Var Forwarding buildOtelEnvironment() in observability-environment.ts auto-forwards all OTEL_* vars; headers also listed in AWF_ONE_SHOT_TOKENS
4 · Token Tracker Integration onUsage callback present in token-tracker-http.js (line 269) — invoked after normalized usage extraction
5 · OTEL Diagnostics No span file present (expected — no live proxy requests; FileSpanExporter fallback initializes gracefully when OTLP endpoint is unset)

All scenarios pass. OTEL tracing integration is functional.

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Add hard cap on AI credits (10000) and restore agentic-workflows integration ID ✅
Upgrade gh-aw to v0.79.2 (pre-release) ✅
Playwright title check ✅
File write/read ✅
Discussion lookup ✅
Build ❌
Overall: FAIL

🔮 The oracle has spoken through Smoke Codex

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx all passed ✅ PASS
Node.js execa all passed ✅ PASS
Node.js p-limit all passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #4589 · 367.6 AIC · ⊞ 33.8K ·

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: GitHub Actions Services Connectivity

Check Result
Redis PING (host.docker.internal:6379) ❌ Connection timeout
PostgreSQL pg_isready (host.docker.internal:5432) ❌ No response
PostgreSQL SELECT 1 ❌ Connection timeout

Overall: FAIL

host.docker.internal resolves to 172.17.0.1 but both service ports are unreachable (packets dropped/filtered). Service containers may not be running or not bridged to this network.

🔌 Service connectivity validated by Smoke Services

@lpcox lpcox merged commit 7f51699 into main Jun 9, 2026
78 of 82 checks passed
@lpcox lpcox deleted the copilot/bundle-catalog-json-from-models-dev branch June 9, 2026 21:00
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.dev

3 participants