Skip to content

fix(anthropic): restore direct OAuth execution for Claude subscriptions#1862

Merged
gsxdsm merged 3 commits into
mainfrom
fix/anthropic-oauth-direct-access
Jul 1, 2026
Merged

fix(anthropic): restore direct OAuth execution for Claude subscriptions#1862
gsxdsm merged 3 commits into
mainfrom
fix/anthropic-oauth-direct-access

Conversation

@gsxdsm

@gsxdsm gsxdsm commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Problem

Claude subscription (Max/Pro) chats fail with a rotating 404 / 502 / 429 cascade — the same symptom as #1857, which was reported fixed. Raw ANTHROPIC_API_KEY and explicit Claude CLI usage work; direct OAuth does not.

Root cause (proven against git history)

Fix — restore the v0.51.0 path (three independent surfaces, no rerouting)

  • auth-storage.tsgetApiKey("anthropic") resolves subscription/legacy OAuth again (raw API key still takes precedence), so the built-in provider receives the token.
  • pi.ts — remove the runtime reroute and the /v1-based anthropic-subscription execution provider; anthropic/* selections stay on the built-in OAuth-capable provider.
  • register-model-routes.ts — advertise anthropic in the picker for OAuth users so direct OAuth is selectable.
  • Result: direct OAuth, raw ANTHROPIC_API_KEY (precedence), and explicit pi-claude-cli all work independently.

Verification

  • packages/engine: auth-storage.test.ts + pi-create-fn-agent.test.ts137 passed (assertions restored to the correct invariant; the FN-7391/FN-7396 tests encoded the bug).
  • packages/dashboard: routes-auth.test.ts + usage.test.ts352 passed.
  • pnpm --filter @fusion/engine build clean.
  • Docs (settings-reference.md, dashboard-guide.md) + changeset updated.

Fixes #1857

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Restored Anthropic Claude subscription chat reliability by reverting the OAuth execution behavior to the expected direct runtime flow.
    • Improved Anthropic credential precedence and provider visibility across direct API key, subscription OAuth, and Claude CLI modes.
    • Reinstated Claude Sonnet 5 in the model picker with correct catalog/pricing.
  • Documentation
    • Updated the OAuth re-login banner guide and settings reference to clarify Anthropic credential behavior and precedence.
  • Tests
    • Updated authentication, model discovery, session routing, and pricing expectations for Anthropic scenarios.
  • Chores
    • Tightened peer dependency version constraints for the Claude CLI package.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6dfa0840-2b93-4922-90b4-ac7ad586266f

📥 Commits

Reviewing files that changed from the base of the PR and between b7c6443 and e154892.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • packages/pi-claude-cli/package.json

📝 Walkthrough

Walkthrough

This PR restores direct Anthropic OAuth execution on the built-in provider, removes /v1 subscription rerouting, updates provider discovery and auth handling, and reintroduces Claude Sonnet 5 catalog/pricing data with matching test updates.

Changes

Anthropic OAuth Direct-Execution Revert

Layer / File(s) Summary
Core auth resolution
packages/engine/src/auth-storage.ts, .changeset/fix-anthropic-oauth-direct-access.md
Anthropic runtime auth resolution now prefers raw keys, then legacy OAuth, then subscription OAuth, with updated documentation in the changeset and runtime logic.
Provider discovery and routing
packages/dashboard/src/routes/register-model-routes.ts, packages/engine/src/pi.ts
Direct anthropic is advertised from auth storage or persisted auth files, and the subscription-provider reroute path is removed from session setup.
Engine auth tests
packages/engine/src/__tests__/auth-storage.test.ts
Auth-storage coverage is updated for direct Anthropic runtime auth, refresh, cooldown, logout, reload, and race behavior across legacy and subscription OAuth.
Session tests and docs
packages/engine/src/__tests__/pi-create-fn-agent.test.ts, packages/dashboard/src/__tests__/routes-auth.test.ts, docs/dashboard-guide.md, docs/settings-reference.md
Session-routing tests and Anthropic documentation are updated to reflect direct execution, picker visibility, and the three Anthropic surfaces.

Claude Sonnet 5 Catalog Restore

Layer / File(s) Summary
Catalog and pricing restore
.changeset/restore-claude-sonnet-5-catalog.md, packages/core/src/anthropic-models.ts, packages/core/src/model-pricing.ts, packages/core/src/__tests__/model-pricing.test.ts
Sonnet 5 is re-added to supplemental Anthropic model registration and static pricing, with tests updated for the restored catalog row.
Model visibility tests
packages/dashboard/src/__tests__/routes-auth.test.ts, packages/engine/src/__tests__/pi-create-fn-agent.test.ts
Dashboard and agent tests now expect Sonnet 5 to appear in the merged registry, /api/models, and session creation when restored metadata is present.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • Runfusion/Fusion#47: Both PRs change packages/engine/src/auth-storage.ts around Anthropic credential resolution and logout-state handling.
  • Runfusion/Fusion#56: Both PRs modify packages/dashboard/src/routes/register-model-routes.ts provider-discovery logic for surfaced Anthropic providers.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also changes Claude Sonnet 5 catalog/pricing and bumps pi-claude-cli peer deps, which are unrelated to the Anthropic subscription routing fix. Move the Sonnet 5 and peer-dependency updates into a separate PR unless they are required for this regression fix.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main change: restoring direct OAuth execution for Anthropic subscription chats.
Linked Issues check ✅ Passed The changes restore direct Anthropic OAuth execution, remove the /v1 reroute, and keep raw API-key precedence, matching the issue's acceptance criteria.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/anthropic-oauth-direct-access

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Claude subscription (Max/Pro) chats regressed to 404/502/429 because
FN-7396 rerouted subscription OAuth to a /v1-based `anthropic-subscription`
runtime provider — reintroducing issue #1857 that FN-7391 had fixed. Both
routed the OAuth token to api.anthropic.com/v1, the surface that broke.

Proven in code that v0.51.0 (working) sent subscription OAuth directly to
/v1 via pi-ai's built-in `anthropic` provider (Claude Code impersonation:
Bearer + anthropic-beta oauth headers), NOT through the CLI. Restore that:

- auth-storage: getApiKey("anthropic") resolves subscription/legacy OAuth
  again (raw API key still wins), so the built-in provider gets the token.
- pi.ts: remove the runtime reroute and the /v1 `anthropic-subscription`
  execution provider so anthropic/* selections stay on the built-in provider.
- register-model-routes: advertise `anthropic` for OAuth users so direct
  OAuth is selectable in the picker.

Three independent surfaces, no rerouting: direct OAuth, raw ANTHROPIC_API_KEY
(precedence), and explicit pi-claude-cli.

Fixes #1857

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gsxdsm gsxdsm force-pushed the fix/anthropic-oauth-direct-access branch from ba98615 to a1af5de Compare July 1, 2026 22:40
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reverts the FN-7391/FN-7396 regression that had re-introduced the #1857 subscription-chat failure (404/502/429 cascade) by restoring the v0.51.0 direct OAuth execution path for Claude subscription users.

  • auth-storage.ts: resolveAnthropicRuntimeApiKey now resolves subscription and legacy OAuth tokens (in addition to raw API keys) for the built-in anthropic provider, with a clear precedence chain: raw API key → legacy anthropic OAuth → anthropic-subscription OAuth → models.json/fallback.
  • pi.ts: Removes registerAnthropicSubscriptionProvider and routeAnthropicSelectionForAvailableAuth, eliminating the /v1-based anthropic-subscription reroute that was the root cause of the regression.
  • register-model-routes.ts: Advertises the direct anthropic provider for any usable Anthropic auth (OAuth or API key); file-scan path now recognises both api_key and oauth credential types.
  • anthropic-models.ts / model-pricing.ts: Restores claude-sonnet-5 to the supplemental catalog and static pricing table (removed by FN-7374 under an incorrect premise).

Confidence Score: 5/5

Safe to merge — the fix correctly restores the v0.51.0 direct OAuth execution path and is backed by 137 engine tests and 352 dashboard tests passing.

The core logic change — resolving subscription and legacy OAuth credentials in resolveAnthropicRuntimeApiKey and removing the broken anthropic-subscription reroute in pi.ts — is well-reasoned, thoroughly tested, and matches the stated v0.51.0 baseline. Logout guard symmetry is confirmed correct by the existing test suite. The two observations are robustness/UX nits that do not affect correctness of the main OAuth or API-key paths.

The file-scan branch in register-model-routes.ts (lines 89–92) and the claude-sonnet-5 supplemental entry in anthropic-models.ts are worth a second look, but neither represents a blocking issue.

Important Files Changed

Filename Overview
packages/engine/src/auth-storage.ts Restores OAuth credential resolution for the direct anthropic provider. Precedence chain (raw API key → legacy OAuth → subscription OAuth → fallback) is correct; logout guards are properly symmetric per existing tests.
packages/engine/src/pi.ts Removes registerAnthropicSubscriptionProvider and routeAnthropicSelectionForAvailableAuth — the two functions that implemented the broken FN-7396 reroute. No residual dead references observed.
packages/dashboard/src/routes/register-model-routes.ts Auth-storage path correctly uses hasAuth() to advertise the anthropic provider for any auth type; file-scan path now accepts oauth in addition to api_key, but does not validate the credential type for anthropic-subscription entries before advertising the provider.
packages/core/src/anthropic-models.ts Restores claude-sonnet-5 to SUPPLEMENTAL_ANTHROPIC_PROVIDER_REGISTRATION; pricing matches the model-pricing.ts entry. Model will appear in the picker for all Anthropic auth types, including subscription OAuth (which 403s at runtime and falls back via the actionable-failure path).
packages/core/src/model-pricing.ts Restores anthropic:claude-sonnet-5 static pricing ($2/$10/$0.2/$2.5 per 1M tokens); values are consistent with the supplemental model registration.
packages/engine/src/tests/auth-storage.test.ts Test assertions updated to match the restored OAuth-resolution behaviour; new test cases cover stale-refresh vs. fresh-login ordering and Claude-credential-file refresh-and-persist flow.
packages/engine/src/tests/pi-create-fn-agent.test.ts Routing-removal tests updated correctly; dead mock setups removed with explanatory comments, and anthropic-subscription provider registration assertions are now negated as expected.
packages/dashboard/src/tests/routes-auth.test.ts Test names and assertions updated to reflect that subscription OAuth now exposes the direct anthropic provider rows; all inverted expectations correctly flipped.
packages/pi-claude-cli/package.json Peer dependency range tightened from "*" to "^0.80.3"; lock file updated to match. Prevents silent resolution to the older 0.77.x builds.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant Dashboard as Dashboard /api/models
    participant RegRoutes as register-model-routes
    participant AuthStore as auth-storage
    participant PiAgent as pi.ts / createFnAgent
    participant PiAI as pi-ai built-in provider
    participant AnthropicAPI as api.anthropic.com/v1

    User->>Dashboard: GET /api/models
    Dashboard->>RegRoutes: getConfiguredProviderNames()
    RegRoutes->>AuthStore: hasAuth("anthropic") OR hasAuth("anthropic-subscription")
    AuthStore-->>RegRoutes: true (OAuth or API key present)
    RegRoutes-->>Dashboard: providers includes "anthropic"
    Dashboard-->>User: model list (incl. anthropic/claude-sonnet-5)

    User->>PiAgent: "createFnAgent({provider:"anthropic", model:"claude-sonnet-5"})"
    PiAgent->>PiAgent: mergeSupplementalAnthropicModels()
    Note over PiAgent: No registerAnthropicSubscriptionProvider() call
    PiAgent->>AuthStore: getApiKey("anthropic")
    AuthStore->>AuthStore: resolveAnthropicRuntimeApiKey()
    Note over AuthStore: Precedence: raw API key → legacy OAuth → subscription OAuth → fallback
    AuthStore-->>PiAgent: OAuth access token (or raw key)
    PiAgent->>PiAI: "createAgentSession({model:{provider:"anthropic", id:"claude-sonnet-5"}})"
    PiAI->>AnthropicAPI: POST /v1/messages (Bearer OAuth + Claude Code headers)
    AnthropicAPI-->>PiAI: 200 OK (API key) or 403 scope (OAuth+Sonnet5)
    PiAI-->>User: response or actionable-failure fallback
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant Dashboard as Dashboard /api/models
    participant RegRoutes as register-model-routes
    participant AuthStore as auth-storage
    participant PiAgent as pi.ts / createFnAgent
    participant PiAI as pi-ai built-in provider
    participant AnthropicAPI as api.anthropic.com/v1

    User->>Dashboard: GET /api/models
    Dashboard->>RegRoutes: getConfiguredProviderNames()
    RegRoutes->>AuthStore: hasAuth("anthropic") OR hasAuth("anthropic-subscription")
    AuthStore-->>RegRoutes: true (OAuth or API key present)
    RegRoutes-->>Dashboard: providers includes "anthropic"
    Dashboard-->>User: model list (incl. anthropic/claude-sonnet-5)

    User->>PiAgent: "createFnAgent({provider:"anthropic", model:"claude-sonnet-5"})"
    PiAgent->>PiAgent: mergeSupplementalAnthropicModels()
    Note over PiAgent: No registerAnthropicSubscriptionProvider() call
    PiAgent->>AuthStore: getApiKey("anthropic")
    AuthStore->>AuthStore: resolveAnthropicRuntimeApiKey()
    Note over AuthStore: Precedence: raw API key → legacy OAuth → subscription OAuth → fallback
    AuthStore-->>PiAgent: OAuth access token (or raw key)
    PiAgent->>PiAI: "createAgentSession({model:{provider:"anthropic", id:"claude-sonnet-5"}})"
    PiAI->>AnthropicAPI: POST /v1/messages (Bearer OAuth + Claude Code headers)
    AnthropicAPI-->>PiAI: 200 OK (API key) or 403 scope (OAuth+Sonnet5)
    PiAI-->>User: response or actionable-failure fallback
Loading

Reviews (3): Last reviewed commit: "Align pi-claude-cli peer deps to pi-ai 0..." | Re-trigger Greptile

Comment thread packages/engine/src/auth-storage.ts

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

🧹 Nitpick comments (2)
packages/engine/src/auth-storage.ts (1)

518-521: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Tighten this FNXC note to the requirement.

The FNXC body is doing historical/proof narration instead of concise technical requirement prose. Keep the detailed regression story in the changeset/docs and make the code comment state the invariant.

♻️ Proposed comment trim
     /*
     FNXC:ProviderAuth 2026-07-01-14:55:
-    Restore the v0.51.0 direct-OAuth execution path (regressed by FN-7291 → FN-7391 → FN-7396, all built on issue `#1857`'s incorrect "Anthropic blocks subscription OAuth on /v1, must use the CLI" conclusion). PROVEN in code: at v0.51.0 `getApiKey("anthropic")` returned the subscription OAuth access token, and pi-ai's built-in `anthropic` provider POSTs it to `api.anthropic.com/v1/messages` with full Claude Code impersonation (`Authorization: Bearer` + `anthropic-beta: claude-code-20250219,oauth-2025-04-20`), which Anthropic accepts. So `anthropic` runtime auth resolves, in precedence order: (1) raw API key, (2) legacy `anthropic` OAuth, (3) separated `anthropic-subscription` OAuth, (4) models.json / ModelRegistry fallback raw key. Raw key still wins so an explicit `ANTHROPIC_API_KEY` keeps using x-api-key. Direct OAuth, raw API key, and explicit `pi-claude-cli` remain three independent surfaces.
+    Anthropic runtime auth must preserve raw API-key precedence, then resolve legacy `anthropic` OAuth and separated `anthropic-subscription` OAuth on the built-in provider, with models.json/ModelRegistry raw-key fallback last.
+    Keep explicit `pi-claude-cli` as a separate provider surface.
     */

As per coding guidelines, FNXC comments in **/*.{ts,tsx,js,jsx,mjs,cjs} must use FNXC:<Area-of-product>, include a yyyy-MM-dd-hh:mm timestamp, and encode the requirement/change in concise technical prose.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/engine/src/auth-storage.ts` around lines 518 - 521, Rewrite the FNXC
comment in auth-storage.ts to state only the invariant in concise technical
prose, keeping the required FNXC:ProviderAuth tag and yyyy-MM-dd-hh:mm
timestamp. Remove the historical/proof narration and long regression
explanation, and summarize the auth resolution order and precedence around
getApiKey("anthropic") / Anthropic runtime auth in a short requirement-style
comment.

Source: Coding guidelines

packages/engine/src/pi.ts (1)

1174-1177: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten this FNXC comment to the routing invariant.

This comment captures the right behavior, but it is too narrative for an FNXC requirement note.

♻️ Proposed comment trim
 /*
 FNXC:ProviderAuth 2026-07-01-14:55:
-Anthropic has three independent surfaces and NO runtime rerouting between them: (1) direct OAuth — a subscription/OAuth `anthropic/<model>` selection executes on pi-ai's built-in `anthropic` provider, which detects the `sk-ant-oat` token and POSTs to `api.anthropic.com/v1/messages` with full Claude Code impersonation (the v0.51.0 working path; `authStorage.getApiKey("anthropic")` supplies the OAuth token); (2) raw API key — a configured `ANTHROPIC_API_KEY` takes precedence in `getApiKey("anthropic")` and uses x-api-key on the same built-in provider; (3) Claude CLI — an explicit `pi-claude-cli/<model>` selection runs through the vendored CLI extension. FN-7291/FN-7391/FN-7396 added an `/v1`-based `anthropic-subscription` reroute on the incorrect premise that Anthropic blocks subscription OAuth on `/v1`; that reroute is intentionally absent so direct OAuth is not re-broken (issue `#1857`).
+Anthropic has three independent execution surfaces: built-in `anthropic` for OAuth or raw API-key auth, and explicit `pi-claude-cli` for CLI-backed execution.
+Do not register or route through an `anthropic-subscription` provider at runtime.
 */

As per coding guidelines, FNXC comments in **/*.{ts,tsx,js,jsx,mjs,cjs} must use FNXC:<Area-of-product>, include a yyyy-MM-dd-hh:mm timestamp, and encode the requirement/change in concise technical prose.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/engine/src/pi.ts` around lines 1174 - 1177, The FNXC note in pi.ts
is too narrative and should be trimmed to the routing invariant only. Rewrite
the existing ProviderAuth comment near the Anthropic routing logic to a concise
requirement statement that preserves the key rule: direct OAuth and raw API key
must stay on the built-in anthropic provider, and only explicit
pi-claude-cli/<model> should use the CLI path. Keep the FNXC prefix, timestamp,
and a short technical description tied to the Anthropic selection/routing
behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/engine/src/auth-storage.ts`:
- Around line 518-521: Rewrite the FNXC comment in auth-storage.ts to state only
the invariant in concise technical prose, keeping the required FNXC:ProviderAuth
tag and yyyy-MM-dd-hh:mm timestamp. Remove the historical/proof narration and
long regression explanation, and summarize the auth resolution order and
precedence around getApiKey("anthropic") / Anthropic runtime auth in a short
requirement-style comment.

In `@packages/engine/src/pi.ts`:
- Around line 1174-1177: The FNXC note in pi.ts is too narrative and should be
trimmed to the routing invariant only. Rewrite the existing ProviderAuth comment
near the Anthropic routing logic to a concise requirement statement that
preserves the key rule: direct OAuth and raw API key must stay on the built-in
anthropic provider, and only explicit pi-claude-cli/<model> should use the CLI
path. Keep the FNXC prefix, timestamp, and a short technical description tied to
the Anthropic selection/routing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9c371bca-7a1d-4bd8-80ce-413120e46244

📥 Commits

Reviewing files that changed from the base of the PR and between 20e42c6 and a1af5de.

📒 Files selected for processing (9)
  • .changeset/fix-anthropic-oauth-direct-access.md
  • docs/dashboard-guide.md
  • docs/settings-reference.md
  • packages/dashboard/src/__tests__/routes-auth.test.ts
  • packages/dashboard/src/routes/register-model-routes.ts
  • packages/engine/src/__tests__/auth-storage.test.ts
  • packages/engine/src/__tests__/pi-create-fn-agent.test.ts
  • packages/engine/src/auth-storage.ts
  • packages/engine/src/pi.ts

…1862)

Sonnet 5 had disappeared from every surface: pi-ai 0.79.9 (the installed
version) lacks it, and FN-7374 removed the static row expecting the live
registry to carry it. Live-verified that claude-sonnet-5 returns 200 on
api.anthropic.com/v1 with a raw ANTHROPIC_API_KEY and runs via the Claude
CLI (it 403s on subscription-OAuth /v1 — scope-gated; runtime fallback
applies). Note: pi-ai 0.80.3 ships sonnet-5 natively, so this SUPPLEMENTAL
row dedupes once the install catches up.

- core: re-add claude-sonnet-5 to SUPPLEMENTAL_ANTHROPIC_PROVIDER_REGISTRATION
  and restore its static pricing (revert FN-7374); update pricing tests.
- engine/dashboard tests: flip the FN-7374 "withheld" assertions to the
  restored "advertised" behavior.

PR feedback:
- Trim the two FNXC comments (auth-storage.ts, pi.ts) to concise
  requirement prose per coding guidelines (CodeRabbit).
- Replace the now-inert getApiKey mock in two subscription routing tests
  with a clarifying note (Greptile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gsxdsm

gsxdsm commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the review nitpicks in b7c6443:

CodeRabbit — "Tighten this FNXC note to the requirement" (auth-storage.ts) and "Shorten this FNXC comment to the routing invariant" (pi.ts):
Fixed — both FNXC comments were trimmed to concise requirement prose (kept the FNXC:ProviderAuth tag + timestamp and the load-bearing "don't reroute OAuth to an /v1 anthropic-subscription provider — #1857" invariant; dropped the historical/proof narration).

Greptile — "Dead mock setup after routing removal" (pi-create-fn-agent.test.ts):
Fixed — replaced the now-inert authStorageGetApiKeyMock.mockResolvedValue(undefined) in the two subscription-routing tests with a note clarifying that model selection no longer reads getApiKey (production resolves the OAuth token later, at session execution), so a reader won't mistake undefined for the production scenario.

Also in this push (separate from the OAuth fix, surfaced during verification): restored Claude Sonnet 5 to the model picker — it had dropped off every surface (installed pi-ai 0.79.9 lacks it and FN-7374 removed the static row). Live-verified it returns 200 via raw API key and runs via the Claude CLI. Note: pi-ai 0.80.3 ships Sonnet 5 natively, so the SUPPLEMENTAL row dedupes once the install catches up.

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

🧹 Nitpick comments (1)
packages/core/src/__tests__/model-pricing.test.ts (1)

39-54: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tighten assertions to an exact cost value.

Sibling tests in this file (lines 27-37, 56-66) assert exact toBeCloseTo values rather than just positivity, giving stronger regression protection. With the given usage and Sonnet 5 rates, the expected cost is 5.1.

♻️ Proposed tightened assertions
     const anthropic = costFor(usage, { provider: "anthropic", model: "claude-sonnet-5" });
     expect(anthropic.unavailable).toBe(false);
-    expect(anthropic.usd).toBeGreaterThan(0);
+    expect(anthropic.usd).toBeCloseTo(5.1, 2);

     const bare = costFor(usage, { model: "claude-sonnet-5" });
     expect(bare.unavailable).toBe(false);
-    expect(bare.usd).toBeGreaterThan(0);
+    expect(bare.usd).toBeCloseTo(5.1, 2);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/__tests__/model-pricing.test.ts` around lines 39 - 54, The
Anthropic Claude Sonnet 5 pricing test in model-pricing.test should assert the
exact calculated USD amount instead of only checking that it is positive. Update
the existing costFor expectations for both the provider-specific and bare model
cases to use a close-to exact value of 5.1, matching the style used by the
sibling tests in this file and providing stronger regression coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/core/src/__tests__/model-pricing.test.ts`:
- Around line 39-54: The Anthropic Claude Sonnet 5 pricing test in
model-pricing.test should assert the exact calculated USD amount instead of only
checking that it is positive. Update the existing costFor expectations for both
the provider-specific and bare model cases to use a close-to exact value of 5.1,
matching the style used by the sibling tests in this file and providing stronger
regression coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 90710b13-f064-4076-bed1-5a4201462b52

📥 Commits

Reviewing files that changed from the base of the PR and between a1af5de and b7c6443.

📒 Files selected for processing (8)
  • .changeset/restore-claude-sonnet-5-catalog.md
  • packages/core/src/__tests__/model-pricing.test.ts
  • packages/core/src/anthropic-models.ts
  • packages/core/src/model-pricing.ts
  • packages/dashboard/src/__tests__/routes-auth.test.ts
  • packages/engine/src/__tests__/pi-create-fn-agent.test.ts
  • packages/engine/src/auth-storage.ts
  • packages/engine/src/pi.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/restore-claude-sonnet-5-catalog.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/engine/src/pi.ts
  • packages/engine/src/auth-storage.ts

The vendored pi-claude-cli extension declared `@earendil-works/pi-ai` and
`pi-coding-agent` as `*` peers, so its dev/workspace resolution drifted to
0.77.0 while the rest of the workspace is on ^0.80.3. Pin both peers to
^0.80.3 so the extension's `getModels("anthropic")` catalog (which feeds the
pi-claude-cli picker rows) matches the engine/cli — 0.80.3 ships
claude-sonnet-5 natively. Behavior-preserving; the bundled CLI already
provided 0.80.3 at runtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gsxdsm gsxdsm merged commit c59ae0b into main Jul 1, 2026
5 of 6 checks passed
@gsxdsm gsxdsm deleted the fix/anthropic-oauth-direct-access branch July 1, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0.52.0 regression: Anthropic *subscription* chat routed to direct api.anthropic.com/v1 (OAuth) → 429/502; 0.51.0 uses the CLI and works

1 participant