fix: 修复Gemini渠道API端点URL显示问题#123
Conversation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe UI now sets provider-specific default base URLs (OpenAI to Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant UI as AIConfigPanel
participant Builder as apiUrlBuilder
participant API as Remote API
User->>UI: change apiType (e.g., "gemini")
UI->>UI: useEffect checks if baseUrl was customized
alt baseUrl not customized
UI->>UI: set or clear form.baseUrl per defaultApiEndpoints
end
User->>UI: submit request with model
UI->>Builder: buildFinalApiUrl(apiType, baseUrl, model)
alt apiType == "gemini"
Builder->>Builder: return "baseUrl/v1beta/models/{model}:generateContent"
else
Builder->>Builder: return existing OpenAI responses/chat completions path
end
UI->>API: send request to built endpoint
API-->>UI: response
UI-->>User: display result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 56-61: The useEffect references form before its declaration and
only autofills when baseUrl is empty; move the useEffect so it appears after the
form state declaration (the useState that defines form) and change its logic to
handle API-type switches by tracking the previous apiType with a useRef
(prevApiType) — on apiType change, if defaultApiEndpoints[form.apiType] exists
and (form.baseUrl is empty OR form.baseUrl equals
defaultApiEndpoints[prevApiType]) then call setForm(prev => ({ ...prev, baseUrl:
defaultApiEndpoints[form.apiType] })); ensure the effect depends on form.apiType
and form.baseUrl (or use prevApiType ref) and reference the symbols useEffect,
defaultApiEndpoints, form, setForm, baseUrl, apiType, and prevApiType.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 791385aa-137e-4e47-9c99-30dd0cda6de1
📒 Files selected for processing (2)
src/components/settings/AIConfigPanel.tsxsrc/utils/apiUrlBuilder.ts
- 选择Gemini类型时自动填充官方默认端点 https://generativelanguage.googleapis.com/v1beta - 修正buildFinalApiUrl对gemini类型的处理,返回正确的v1beta/models/{model}:generateContent路径 - 更新UI提示文案,Gemini用户看到"只填到v1beta即可,路径会自动生成" Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ec0cc2e to
5e8a2a9
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/components/settings/AIConfigPanel.tsx (1)
76-82:⚠️ Potential issue | 🟠 MajorEndpoint defaults are declared but not applied on API-type switch.
Line 76 defines provider defaults, but switching
form.apiType(Line 366) still does not auto-updateform.baseUrl, so selecting Gemini can keep the previous provider URL. This misses the PR objective.💡 Suggested fix
+ const prevApiTypeRef = useRef<AIApiType>(form.apiType); + + useEffect(() => { + const nextDefault = defaultApiEndpoints[form.apiType]; + const prevDefault = defaultApiEndpoints[prevApiTypeRef.current]; + const shouldAutofill = + !!nextDefault && + (form.baseUrl === '' || form.baseUrl === prevDefault) && + form.baseUrl !== nextDefault; + + if (shouldAutofill) { + setForm(prev => ({ ...prev, baseUrl: nextDefault })); + } + prevApiTypeRef.current = form.apiType; + }, [form.apiType, form.baseUrl]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/settings/AIConfigPanel.tsx` around lines 76 - 82, The defaultApiEndpoints map (defaultApiEndpoints) is defined but not applied when form.apiType changes; update the API-type switch handler (where form.apiType is set) to also set form.baseUrl to defaultApiEndpoints[form.apiType] (or the selected value) when the user selects a new provider, using the form state setter used in this component (e.g., setForm or the form change handler) so that selecting "gemini", "claude", "openai", etc. automatically updates the baseUrl field; ensure you only overwrite baseUrl when the endpoint default is non-empty to avoid clobbering user-entered custom URLs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 85-90: The reset logic uses the current form.apiType to compute
defaultUrl then sets apiType to 'openai', causing mismatched baseUrl; update the
resetForm logic so defaultUrl is derived from the new apiType (the value being
set, e.g., 'openai') or compute baseUrl after you set apiType so that setForm({
apiType, baseUrl }) uses matching values; locate the reset handler where
defaultUrl is computed from form.apiType and change it to use the target apiType
string (or compute baseUrl from defaultApiEndpoints[targetApiType]) so
name/apiType/baseUrl stay consistent.
---
Duplicate comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 76-82: The defaultApiEndpoints map (defaultApiEndpoints) is
defined but not applied when form.apiType changes; update the API-type switch
handler (where form.apiType is set) to also set form.baseUrl to
defaultApiEndpoints[form.apiType] (or the selected value) when the user selects
a new provider, using the form state setter used in this component (e.g.,
setForm or the form change handler) so that selecting "gemini", "claude",
"openai", etc. automatically updates the baseUrl field; ensure you only
overwrite baseUrl when the endpoint default is non-empty to avoid clobbering
user-entered custom URLs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6abd2206-5f11-489e-b685-9d8910755145
📒 Files selected for processing (2)
src/components/settings/AIConfigPanel.tsxsrc/utils/apiUrlBuilder.ts
- 添加useEffect监听form.apiType变化,自动填充对应默认端点 - 使用prevApiTypeRef避免重复设置 - 修复resetForm中apiType与baseUrl不匹配的问题 - 仅在baseUrl为空或等于上一个默认端点时才填充 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/settings/AIConfigPanel.tsx (1)
64-95:⚠️ Potential issue | 🟠 MajorDon't let the custom-endpoint mode inherit OpenAI's default URL.
openai-compatiblehas no default endpoint, so switching from a provider with a default leaveshttps://api.openai.com/v1in the field. That makes the custom-endpoint mode start from the wrong base and can be saved unchanged. Clear the field when the target type has no default, or only preserve user-entered custom values.Suggested fix
useEffect(() => { if (form.apiType !== prevApiTypeRef.current) { const nextDefault = defaultApiEndpoints[form.apiType]; const prevDefault = defaultApiEndpoints[prevApiTypeRef.current]; - if (nextDefault && (form.baseUrl === '' || form.baseUrl === prevDefault)) { - setForm(prev => ({ ...prev, baseUrl: nextDefault })); - } + if (nextDefault) { + if (form.baseUrl === '' || form.baseUrl === prevDefault) { + setForm(prev => ({ ...prev, baseUrl: nextDefault })); + } + } else if (form.baseUrl === prevDefault) { + setForm(prev => ({ ...prev, baseUrl: '' })); + } prevApiTypeRef.current = form.apiType; } }, [form.apiType, form.baseUrl]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/settings/AIConfigPanel.tsx` around lines 64 - 95, The effect that auto-fills baseUrl (useEffect referencing prevApiTypeRef, defaultApiEndpoints, form.apiType, form.baseUrl, and setForm) currently only updates when the new API type has a default endpoint, so switching to 'openai-compatible' can leave the OpenAI URL in place; change the logic so when nextDefault is falsy (no default, e.g., 'openai-compatible') and the current form.baseUrl equals the previous provider's default (prevDefault) you set baseUrl to '' (clear it), while if the user had already entered a custom baseUrl you preserve it; otherwise when nextDefault exists keep the existing behavior (set baseUrl to nextDefault if baseUrl is empty or equals prevDefault).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 64-95: The effect that auto-fills baseUrl (useEffect referencing
prevApiTypeRef, defaultApiEndpoints, form.apiType, form.baseUrl, and setForm)
currently only updates when the new API type has a default endpoint, so
switching to 'openai-compatible' can leave the OpenAI URL in place; change the
logic so when nextDefault is falsy (no default, e.g., 'openai-compatible') and
the current form.baseUrl equals the previous provider's default (prevDefault)
you set baseUrl to '' (clear it), while if the user had already entered a custom
baseUrl you preserve it; otherwise when nextDefault exists keep the existing
behavior (set baseUrl to nextDefault if baseUrl is empty or equals prevDefault).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9a36a99d-8eef-4f3f-8256-cb6677186e43
📒 Files selected for processing (1)
src/components/settings/AIConfigPanel.tsx
当切换到无默认端点的API类型时,如果当前baseUrl等于前一个默认端点则清空 避免用户误以为仍在使用OpenAI的URL Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/settings/AIConfigPanel.tsx (1)
64-82: Avoid duplicating the OpenAI default endpoint.
baseUrlis hardcoded in the initial state and again indefaultApiEndpoints, so the initial form can drift from the reset/switch behavior later. Hoist the map aboveuseStateand initialize fromdefaultApiEndpoints.openai.♻️ Suggested cleanup
+ const defaultApiEndpoints: Record<AIApiType, string> = { + openai: 'https://api.openai.com/v1', + 'openai-responses': 'https://api.openai.com/v1', + claude: 'https://api.anthropic.com/v1', + gemini: 'https://generativelanguage.googleapis.com/v1beta', + 'openai-compatible': '', + }; + const [form, setForm] = useState<AIFormState>({ name: '', apiType: 'openai', - baseUrl: 'https://api.openai.com/v1', + baseUrl: defaultApiEndpoints.openai, apiKey: '',🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/settings/AIConfigPanel.tsx` around lines 64 - 82, Move the defaultApiEndpoints map out of the component state block and define it above the useState call, then initialize the form's baseUrl using defaultApiEndpoints.openai instead of the hardcoded 'https://api.openai.com/v1'; update the AIFormState initial object (used in useState) to reference defaultApiEndpoints.openai and remove the duplicate hardcoded URL so switching/reset logic that uses defaultApiEndpoints stays consistent with the initial form state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 84-100: The auto-fill effect (the useEffect that compares
form.apiType to prevApiTypeRef.current and updates baseUrl) is unintentionally
running when handleEdit hydrates an existing config; to fix, ensure the effect
only reacts to user-driven API-type changes or mark hydration as such. Two
acceptable fixes: (A) update prevApiTypeRef.current to the incoming
config.apiType inside handleEdit before calling setForm so the effect sees no
change, or (B) add a short-lived "isHydrating" ref/state that handleEdit sets
true while it writes form and the useEffect early-returns if isHydrating is
true; reference prevApiTypeRef, useEffect, setForm, and handleEdit when applying
the change.
---
Nitpick comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 64-82: Move the defaultApiEndpoints map out of the component state
block and define it above the useState call, then initialize the form's baseUrl
using defaultApiEndpoints.openai instead of the hardcoded
'https://api.openai.com/v1'; update the AIFormState initial object (used in
useState) to reference defaultApiEndpoints.openai and remove the duplicate
hardcoded URL so switching/reset logic that uses defaultApiEndpoints stays
consistent with the initial form state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b87417b4-61f7-47d0-9267-ba863d933063
📒 Files selected for processing (1)
src/components/settings/AIConfigPanel.tsx
在handleEdit中先同步prevApiTypeRef.current为配置的apiType 避免effect误判为apiType变化而清空或覆盖用户已保存的自定义URL Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/components/settings/AIConfigPanel.tsx (1)
76-82: Consider hoistingdefaultApiEndpointsoutside the component.This constant object is recreated on every render. Since the values are static, moving it outside the component (or wrapping in
useMemo) avoids unnecessary object allocations and ensures referential stability.♻️ Suggested refactor
+const DEFAULT_API_ENDPOINTS: Record<AIApiType, string> = { + openai: 'https://api.openai.com/v1', + 'openai-responses': 'https://api.openai.com/v1', + claude: 'https://api.anthropic.com/v1', + gemini: 'https://generativelanguage.googleapis.com/v1beta', + 'openai-compatible': '', +}; + export const AIConfigPanel: React.FC<AIConfigPanelProps> = ({ t }) => { // ... - const defaultApiEndpoints: Record<AIApiType, string> = { - openai: 'https://api.openai.com/v1', - 'openai-responses': 'https://api.openai.com/v1', - claude: 'https://api.anthropic.com/v1', - gemini: 'https://generativelanguage.googleapis.com/v1beta', - 'openai-compatible': '', - };Then update all references from
defaultApiEndpointstoDEFAULT_API_ENDPOINTS.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/settings/AIConfigPanel.tsx` around lines 76 - 82, Hoist the defaultApiEndpoints object out of the AIConfigPanel component to avoid recreating it on every render: create a top-level constant named DEFAULT_API_ENDPOINTS with the same entries and replace all in-component references to defaultApiEndpoints with DEFAULT_API_ENDPOINTS (alternatively, wrap it in useMemo inside AIConfigPanel if you prefer a hook-based approach); ensure the symbol DEFAULT_API_ENDPOINTS is exported/visible where needed and update usages in this file accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/components/settings/AIConfigPanel.tsx`:
- Around line 76-82: Hoist the defaultApiEndpoints object out of the
AIConfigPanel component to avoid recreating it on every render: create a
top-level constant named DEFAULT_API_ENDPOINTS with the same entries and replace
all in-component references to defaultApiEndpoints with DEFAULT_API_ENDPOINTS
(alternatively, wrap it in useMemo inside AIConfigPanel if you prefer a
hook-based approach); ensure the symbol DEFAULT_API_ENDPOINTS is
exported/visible where needed and update usages in this file accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ebe25747-87d0-44b5-924c-f570ce0f819a
📒 Files selected for processing (1)
src/components/settings/AIConfigPanel.tsx
避免每次渲染时重复创建对象,减少不必要的内存分配 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
https://generativelanguage.googleapis.com/v1betabuildFinalApiUrl对 gemini 类型的处理,返回正确的v1beta/models/{model}:generateContent路径Test plan
.../v1beta/models/{model}:generateContent格式🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes