feat: support doubao coding plan - #2238
Conversation
WalkthroughAdds support for Volcengine's Doubao Coding Plan across backend and frontend components. Includes import extensions in channel controller, new routing constants and logic in the adaptor, and a hidden unlock-based UI flow for API configuration editing in the channel modal. Changes
Sequence DiagramsequenceDiagram
participant User
participant Frontend as EditChannelModal
participant Backend as Channel Controller
participant Adaptor as Volcengine Adaptor
User->>Frontend: Click API Config area (10 times)
Frontend->>Frontend: Increment click counter
Frontend->>Frontend: Unlock Doubao API editor<br/>after 10 clicks
User->>Frontend: Select Doubao Coding Plan<br/>and configure API
Frontend->>Backend: Submit channel config<br/>with DoubaoCodingPlan base_url
Backend->>Backend: FetchUpstreamModels called<br/>for VolcEngine channel
Backend->>Adaptor: GetRequestURL invoked<br/>with DoubaoCodingPlan base_url
alt Claude Relay Format
Adaptor->>Adaptor: Route to<br/>DoubaoCodingPlanClaudeBaseURL/v1/messages
else Chat Completion
Adaptor->>Adaptor: Route to<br/>DoubaoCodingPlanOpenAIBaseURL
end
Adaptor-->>Backend: Routed endpoint URL
Backend-->>Frontend: Models list response
Frontend-->>User: Display available models
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example:
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: 0
🧹 Nitpick comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
192-193: Doubao hidden API edit flow is state‑safe; consider minor UX/accessibility tweaks
- Logic looks coherent:
doubaoApiEditUnlocked+doubaoApiClickCountRefcorrectly gate the hidden entry and avoid extra re-renders.- Unlock state and click count are reset when
inputs.typeleaves 45 and when the modal is reset, so no leakage between channel types or sessions.- For type 45:
- Before unlock, the generic
base_urlinput is hidden and a constrained<Select>is shown, including thedoubao-coding-plansentinel option.- After unlock, the generic
base_urlinput is shown and the select is hidden, preserving the existingbase_urlvalue (including the sentinel if previously chosen).- Frontend sentinel value
"doubao-coding-plan"matches the backend constantvolcengine.DoubaoCodingPlan, so routing stays in sync.Optional refinements:
- The API Config header
<div>is now clickable but not keyboard-focusable; if you want slightly better a11y while keeping the easter‑egg nature, you could switch to a visually identical<button>withtype="button"andaria-labelwhile ignoring the click unlessinputs.type === 45.- To reduce magic numbers, you might extract the
10‑click threshold and the sentinel string into small local constants near the Doubao state declarations.Overall, the hidden unlock flow works as intended without impacting other channel types.
Also applies to: 222-223, 311-323, 743-748, 849-851, 1988-1991, 2122-2127, 2179-2203
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.gitignore(1 hunks)controller/channel.go(2 hunks)relay/channel/volcengine/adaptor.go(2 hunks)web/src/components/table/channels/modals/EditChannelModal.jsx(9 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-05T17:14:17.246Z
Learnt from: neotf
Repo: QuantumNous/new-api PR: 1511
File: setting/ratio_setting/model_ratio.go:118-123
Timestamp: 2025-08-05T17:14:17.246Z
Learning: Claude models handle "-thinking" variants differently from Gemini models. For Claude models, only the base model (without "-thinking") gets an entry in defaultModelRatio map. The "-thinking" variants rely on the Claude relay handler stripping the suffix using strings.TrimSuffix(textRequest.Model, "-thinking") before looking up the ratio, so they automatically use the base model's ratio.
Applied to files:
relay/channel/volcengine/adaptor.go
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
Repo: QuantumNous/new-api PR: 1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the applyModelMapping function transforms the models list by replacing original model names (mapping values) with display names (mapping keys). The database stores this transformed list containing mapped keys. On channel load, data.models contains these mapped display names, making the initialization filter if (data.models.includes(key)) correct.
Applied to files:
web/src/components/table/channels/modals/EditChannelModal.jsx
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
Repo: QuantumNous/new-api PR: 1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the database stores mapped keys (display names) in the models field after applying model mapping transformations. When loading a channel, data.models contains the mapped keys, not the original model names. The filtering logic if (data.models.includes(key)) in the initialization is correct.
Applied to files:
web/src/components/table/channels/modals/EditChannelModal.jsx
🧬 Code graph analysis (3)
controller/channel.go (2)
constant/channel.go (1)
ChannelTypeVolcEngine(45-45)relay/channel/volcengine/adaptor.go (2)
DoubaoCodingPlan(28-28)DoubaoCodingPlanOpenAIBaseURL(30-30)
relay/channel/volcengine/adaptor.go (1)
relay/constant/relay_mode.go (1)
RelayModeChatCompletions(10-10)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
web/src/helpers/utils.jsx (1)
showInfo(161-163)
🔇 Additional comments (4)
.gitignore (1)
20-20: Ignoringweb/bun.lockis reasonable project hygieneKeeping Bun’s lockfile out of version control for the web subproject is consistent with typical per-env lockfile handling.
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
97-118: Updated Doubao (type 45) secret prompt text is consistentThe specialized prompt for type 45 clarifying
AppId|AccessTokenfor 豆包语音输入 aligns with the other type-specific hints and keeps the generic fallback intact.controller/channel.go (1)
14-14: Correct Doubao coding plan models endpoint from/v1/modelsto/modelsThe Volcengine Doubao/Coding Plan OpenAI-compatible API uses vendor paths under
https://ark.cn-beijing.volces.com/api/coding/v3, so the models list endpoint is/models(not/v1/models).Your code currently constructs
.../api/coding/v3/v1/models, which is incorrect. It should be.../api/coding/v3/modelsto match the actual API.Change:
if baseURL == volcengine.DoubaoCodingPlan { url = fmt.Sprintf("%s/models", volcengine.DoubaoCodingPlanOpenAIBaseURL) } else { url = fmt.Sprintf("%s/v1/models", baseURL) }Also applies to: 196-201
⛔ Skipped due to learnings
Learnt from: Sh1n3zZ Repo: QuantumNous/new-api PR: 1659 File: relay/relay_task.go:285-305 Timestamp: 2025-08-26T09:59:00.337Z Learning: In controller/task_video.go, data: URLs (containing base64 encoded video data) are prevented from being stored in task.FailReason by checking if the URL starts with "data:" before assignment. This same pattern should be applied consistently across the codebase.relay/channel/volcengine/adaptor.go (1)
25-31: Based on the searches, I cannot find official Volcengine documentation specifically for the "coding plan" product or its/api/codingendpoint paths. The general ARK documentation does not mention these paths.However, the verification has surfaced important concerns that validate the original review:
Claude endpoint claim unsubstantiated: The first search confirmed that Volcengine provides only OpenAI-style API, with no official support for Claude-compatible
/v1/messagesendpoints. The code routesRelayFormatClaudetoDoubaoCodingPlanClaudeBaseURL, which assumes Volcengine offers Claude compatibility—this appears unsupported.Double versioning: The models endpoint path (
.../api/coding/v3/v1/models) combines two version segments, which is suspicious and unconfirmed by any documentation found.Unsupported modes risk: The original concern remains valid—channels configured with
base_url = "doubao-coding-plan"used for embeddings/images/rerank/audio will generate malformed URLs.The original review's recommendations stand:
- Explicitly validate that Volcengine's coding plan actually supports Claude-compatible routing
- Confirm the exact endpoint versions and paths against official Volcengine specifications
- Either reject unsupported relay modes for coding-plan channels or extend the switch with proper routing
* main: fix: aws update model categories' match rules Merge pull request #2238 from seefs001/feature/doubao-coding-plan feat: linuxdo oauth endpoint -> environment feat(adaptor): Add support for Claude-specific headers in SetupRequestHeader feature: support vertex open source models fix: boundary parser error (error parsing multipart form: multipart: NextPart: bufio: buffer full) feat: support gpt-5.1 prompt_cache_retention (#2228) feat: add wan2.5-i2i-preview support fix(relay/channel/aws): 修复AnthropicBeta字段的omitempty处理 fix(adaptor): Add '-none' suffix to effortSuffixes for model parsing feat(aws): Add support for anthropic-beta header in AwsClaudeRequest feat: add hailuo i2v fl2v r2v feat: get hailuo video url feat: add MiniMax Hailuo video fix: 未设置价格模型不会被拉取,除非设置自用模式 fix(claude): Prevent duplicate header values in WriteHeaders method support reasoning field
…ng-plan feat: support doubao coding plan
#2230
Summary by CodeRabbit