upstream取り込み: mastracode 0.14 + small-model refactor (#3517)#313
upstream取り込み: mastracode 0.14 + small-model refactor (#3517)#313
Conversation
…uperset-sh#3517) * remove 7 day rule * Upgrade mastra * upgrade ai * Ad mastra * refactor(desktop): remove dead provider-diagnostics plumbing The provider-diagnostics store was fed by callSmallModel's per-attempt reporting, which was removed when small-model tasks moved to direct AI-SDK + mastracode's AuthStorage. Nothing writes to the issue map anymore, so the clearIssue mutation, getStatuses query, and diagnosticStatus plumbing in ModelsSettings were all no-ops. Settings still surfaces "Session expired / Reconnect" via auth-status alone. ProviderIssue type collapsed from 8 codes to just "expired" to match. * fix(auth): auto-refresh expired Anthropic OAuth tokens Anthropic credentials were read via authStorage.get() everywhere, so mastracode's built-in refresh flow never ran. Once the 1-hour access token expired, status flipped to "Reconnect" and users had to do a full PKCE re-auth, even though a valid refresh token was already stored. Resolvers now call authStorage.getApiKey() for oauth creds on expiry, which triggers refreshToken() and persists the refreshed credential. getAnthropicAuthStatus does the same before declaring issue: "expired". Mirrors the pattern already used for OpenAI small-model auth. * review: address PR feedback from cubic + coderabbit + greptile - host-service ai-branch-name: run trailing-trim after slice so a 100-char truncation can't re-introduce a bare "." or "-" that git rejects as an invalid ref (coderabbit / cubic #2, #7). - host-service workspace-creation.generateBranchName: reuse the existing listBranchNames helper instead of the inline git walk, which classified off the short refname and could conflate a local "origin/foo" with refs/remotes/origin/foo (coderabbit #3). - packages/chat shared/small-model: drop the unused hasSmallModelCredentials export; only a test mock consumed it (greptile #4). - resolveAnthropicCredential: on refresh failure, return null instead of kind:"oauth" with a stale expiresAt so callers fall back cleanly (cubic #8). - chat-service.getAnthropicAuthStatus: log context when refresh throws instead of silently swallowing (cubic #9). * fix(chat): read auth.json directly instead of importing mastracode Importing createAuthStorage from mastracode loads the entire CLI tree (fastembed → onnxruntime-node's 208 MB native binary) via eager top-level requires in mastracode's CJS entry. This crashed electron-vite bundling and bloated the get-small-model chunk. getSmallModel now reads mastracode's auth.json file directly using the same path resolution logic (~/Library/Application Support/mastracode/ on macOS). Zero mastracode import, zero bundle impact. The chunk stays at 1.2 MB (just @ai-sdk/anthropic + @ai-sdk/openai). Production build verified: compile:app succeeds, Electron main process boots with no onnxruntime error. * docs(desktop): add manual testing plan for PR superset-sh#3517 * fix api key storage slot * fix(auth): store API keys in dedicated slot so OAuth doesn't clobber them setApiKeyForProvider and setStoredAnthropicApiKeyFromEnvVariables now use authStorage.setStoredApiKey() (writes to "apikey:<provider>") instead of authStorage.set() (writes to the main "<provider>" slot shared with OAuth). This way connecting/disconnecting OAuth doesn't overwrite or delete a stored API key. resolveAuthMethodForProvider falls back to hasStoredApiKey() after checking the main slot, so status correctly reports authenticated when only an API key is stored. * fix(auth): backup/restore API keys across OAuth connect/disconnect mastracode's resolveModel only reads API keys from the main authStorage slot (authStorage.get("anthropic")). OAuth login overwrites this slot, and disconnect removes it — losing any previously saved API key. Fix: backup the API key to the dedicated apikey: slot before OAuth connect, restore it after disconnect. setApiKeyForProvider now writes to both slots (main for resolveModel compatibility, apikey: for backup). resolveAuthMethodForProvider checks both. Applies to both Anthropic and OpenAI providers. * chore: add upstream PR reference to auth workaround Point to mastra-ai/mastra#15483 so the backup/restore code can be removed once upstream lands and we bump mastracode. * refactor(desktop): derive settings provider action from status Replace the cascade of if/else + canDisconnect flag with a single getProviderAction(status) → connect | reconnect | logout | null. Fixes "Active" badge + "Connect" button showing simultaneously when authenticated via API key. * fix(desktop): always show Logout when provider is active Active providers now always show a Logout button. Clears OAuth or API key depending on authMethod — no more "Active" badge with no way to disconnect. * fix(desktop): simplify OpenAI OAuth dialog + auto-open browser Match Anthropic dialog's layout: remove the raw OAuth URL display and "Tip" block, auto-open the browser on OAuth start. Change "Back" to "Cancel" for consistency. * refactor(desktop): unify OAuth dialogs into shared OAuthDialog Extract shared OAuthDialog component with provider config object. AnthropicOAuthDialog and OpenAIOAuthDialog become thin wrappers that pass provider-specific labels and options. * fix(desktop): show 'Copied!' feedback on Copy URL button * refactor(desktop): merge provider account + API key into single card Each provider section now renders AccountCard + ConfigRow inside one rounded card with a divider, instead of two separate cards. Removes the standalone "API Keys" collapsible section. * refactor(desktop): compact OAuth row in provider settings card OAuth row is now a single inline row (label + status + action) instead of a stacked AccountCard. Both providers share the same 2-row card layout: OAuth row + API key row with divider. * fix(desktop): contextual buttons in provider settings Connect is now primary (filled). Save only shows when there's input. Clear only shows when a key is saved. Removes visual noise from empty-state provider cards. * ui(desktop): add provider icons to settings section headers * ui(desktop): show 'Not connected' badge instead of subtitle for disconnected providers * ui: remove redundant disconnected subtitle * ui: remove subtitle text from OAuth rows * chore: remove dead AccountCard + getProviderSubtitle * docs: update test plan to match current UI * chore: move shipped plans to done/ --------- Co-authored-by: AviPeltz <aj.peltz@gmail.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 5 minutes and 52 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (50)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a05abe3db6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| providerId: string, | ||
| ): string | null { | ||
| if (!authData) return null; | ||
| const entry = authData[`apikey:${providerId}`]; |
There was a problem hiding this comment.
Read legacy API-key slots when resolving small-model creds
getStoredApiKey only reads apikey:<provider> entries from auth.json. Prior to this change, saved API keys were stored in the main provider slots (for example anthropic / openai-codex), so existing users upgrading with previously saved keys will now resolve no small-model credential until they re-save keys. That silently breaks small-model features (branch/workspace naming, title generation) even while provider auth may still appear connected.
Useful? React with 👍 / 👎.
| } else { | ||
| await clearAnthropicApiKeyMutation.mutateAsync(); | ||
| setAnthropicApiKeyInput(""); |
There was a problem hiding this comment.
Handle env-backed Anthropic logout explicitly
This non-OAuth branch clears only the Anthropic API-key slot. When the provider is connected via managed env credentials (authMethod === "env"), clicking Logout follows this path but does not clear the env config, so auth status stays connected and the Logout action is effectively a no-op for that mode.
Useful? React with 👍 / 👎.
…regression) PR #313 (mastracode 0.14 + small-model refactor) shipped three take-home regressions for fork users: 1. Anthropic OAuth / AUTH_TOKEN broken. get-small-model routed the token through createAnthropic({ apiKey }), but fork's OAuth / managed-proxy credentials require authToken + anthropic-beta / user-agent / x-app headers (see getAnthropicProviderOptions). Users connected via Claude Code OAuth or a gateway that only emits ANTHROPIC_AUTH_TOKEN had all small-model tasks 401. 2. Provider fallback dropped. Old callSmallModel iterated Anthropic then OpenAI. The post-superset-sh#3517 shim collapsed to a single attempt, so a failing Anthropic account never fell through to OpenAI. 3. OAuth-only users saw 'Account not connected'. When getSmallModel returned null (because auth.json only had OAuth entries), the shim fabricated two 'missing-credentials' attempts regardless of what was actually connected. Fix: replace the simple getSmallModel() with a fork-maintained getSmallModelCandidates() that returns the full priority list (Anthropic env -> keychain/config -> auth-storage -> managed env config -> OpenAI env -> OpenAI auth-storage) with OAuth / API key / AUTH_TOKEN each routed through the correct AI-SDK provider options (getAnthropicProviderOptions for Anthropic, createOpenAICodexOAuthModel for OpenAI Codex OAuth). getSmallModel() stays as an upstream- compatible wrapper over the first viable candidate. The callSmallModel shim now iterates candidates and surfaces per-attempt outcomes so describeEnhanceFailure keeps its user messages intact. Restored behaviors: - Anthropic OAuth / AUTH_TOKEN via fork-standard header set. - Anthropic managed env config (~/.superset/chat-anthropic-env.json) with both ANTHROPIC_API_KEY (api-key path) and ANTHROPIC_AUTH_TOKEN (OAuth path). - OpenAI Codex OAuth (rewrites to Codex backend, refreshes access token via mastracode authStorage). - OpenAI stock / openai-codex API-key slot. - Provider fallback: Anthropic failure now tries OpenAI.
fix(desktop): PR #313 small-model regression (OAuth + provider fallback)
#313 の revert で消えた mastracode externalize エントリを復元。 mastracode は @mastra/fastembed → onnxruntime-node を引き込み、 onnxruntime-node の native binding は dynamic require で読まれるため Rollup が bundle 時に解決できず、main プロセスの起動が失敗する。
…stracode-upgrade" This reverts commit ded574f.
概要
upstream
34c9049b6 refactor(desktop): upgrade mastracode + simplify small-model naming (#3517)を取り込む PR。behind 1 → 0。パッケージ安全性調査(ユーザー承認の 7-day policy 3 日例外)
本取り込みは 2026-04-18 時点で 3 日経過の
@mastra/core@1.25.0/mastracode@0.14.0を含むため通常なら AGENTS.md の 7-day policy 違反ですが、以下の安全性調査で問題なしを確認し、ユーザー承認の上で一回限りの例外として取り込み:mastracode@0.14.0に install/postinstall/preinstall/prepare なし(forkignore-scripts=trueも効く)mastracode@0.14.0中身(26 deps、特定 pin、install スクリプト無)直接確認済AGENTS.md の 7-day policy 行は本 PR で 復元(一回限り例外、policy 自体は将来のために維持)。
取り込み commit
34c9049b6fork 適応修正
shim / credential resolution(最重要)
apps/desktop/src/lib/ai/call-small-model.ts: upstream が削除したが fork のenhance-text.ts/git-operations.tsが使用中のため新規 shim として再実装。内部でgetSmallModel()を呼び、従来の{ result, attempts }shape を提供。OAuth-only ユーザーはmissing-credentialsになる(upstream 設計と同じトレードオフ)。packages/chat/src/server/shared/small-model/get-small-model.ts: fork の auth 全経路を見るよう拡張process.env.ANTHROPIC_API_KEY→apikey:anthropicin auth.json → fork の~/.superset/chat-anthropic-env.jsonの env config(parseAnthropicEnvTextで正式フォーマット解釈)process.env.OPENAI_API_KEY→apikey:openai→apikey:openai-codex(fork 独自 Codex CLI slot)getDefaultSmallModelProviders+generateTitleFromMessageWithStreamingModelを新getSmallModel+generateTitleFromMessageに書き換え。provider loop → single-model pattern。generateTitleFromMessageWithStreamingModelimport 削除、OAuth streaming fallback 分岐削除(shim が常に api_key credentials を返すため dead branch)。callSmallModel wrapper 経由で従来通り動作。その他 fork 維持
clearProviderIssueMutation+clearProviderIssuehelper 削除(modelProviders router が削除されたため dead code)、未使用apiKeysOpenstate 削除検証
Codex pre-review
3 ラウンドで承認:
get-small-model.tsを fork auth 全経路対応に拡張して解消parseAnthropicEnvTextを直接 import(get-small-model.ts)+ shim 側は quote/export prefix 対応の簡易版Deferred(upstream 意図挙動、PR7 起因ではない)
テストチェックリスト
openai-codexslot)経由でも small-model が動作~/.superset/chat-anthropic-env.jsonのANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN)経由でも small-model が動作