Skip to content

feat: support doubao coding plan - #2238

Merged
Calcium-Ion merged 2 commits into
QuantumNous:mainfrom
seefs001:feature/doubao-coding-plan
Nov 16, 2025
Merged

feat: support doubao coding plan#2238
Calcium-Ion merged 2 commits into
QuantumNous:mainfrom
seefs001:feature/doubao-coding-plan

Conversation

@seefs001

@seefs001 seefs001 commented Nov 16, 2025

Copy link
Copy Markdown
Collaborator

#2230

Summary by CodeRabbit

  • New Features
    • Added support for VolcEngine channel type, specifically Doubao Coding Plan integration.
    • Implemented new configuration interface for Doubao Custom API URLs with a security unlock mechanism.
    • Extended model endpoint routing to support the new channel type and API configurations.

@coderabbitai

coderabbitai Bot commented Nov 16, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds 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

Cohort / File(s) Summary
Build Configuration
.gitignore
Adds web/bun.lock to ignored files
Backend Channel Routing
controller/channel.go, relay/channel/volcengine/adaptor.go
Adds volcengine import and extends FetchUpstreamModels to route VolcEngine channel types. Introduces three new exported constants (DoubaoCodingPlan, DoubaoCodingPlanClaudeBaseURL, DoubaoCodingPlanOpenAIBaseURL) and conditional routing logic in GetRequestURL for Claude and chat completion relay formats
Frontend Channel Configuration
web/src/components/table/channels/modals/EditChannelModal.jsx
Introduces unlockable UI flow for Doubao API URL editing with click-count tracking (10 clicks to unlock). Adds conditional rendering for Doubao Coding Plan base_url option and hides secret URL selection until unlocked

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

  • relay/channel/volcengine/adaptor.go: Review conditional routing logic for Claude and chat completion formats; verify base URL matching and endpoint construction correctness
  • web/src/components/table/channels/modals/EditChannelModal.jsx: Examine click-count tracking, unlock flow state management, conditional rendering logic, and reset behavior; verify unlock threshold and UX flow
  • controller/channel.go: Verify import integration and channel type handling for new VolcEngine routing

Poem

🐰 A secret plan unfolds in clicks, ten taps to unlock,
Doubao coding dances through the backend's routing stocks,
Frontend hides and reveals with UI's gentle lock,
Constants guide the messages to Volcengine's dock,
Adaptor channels flow like streams around the clock! 🌊

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: support doubao coding plan' directly and accurately summarizes the main change across all modified files, which collectively add support for a new Doubao coding plan integration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

  • Provide custom instructions to shape the summary (bullet lists, tables, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example:

"Create a concise high-level summary as a bullet-point list. Then include a Markdown table showing lines added and removed by each contributing author."


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 and usage tips.

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

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 + doubaoApiClickCountRef correctly gate the hidden entry and avoid extra re-renders.
    • Unlock state and click count are reset when inputs.type leaves 45 and when the modal is reset, so no leakage between channel types or sessions.
    • For type 45:
      • Before unlock, the generic base_url input is hidden and a constrained <Select> is shown, including the doubao-coding-plan sentinel option.
      • After unlock, the generic base_url input is shown and the select is hidden, preserving the existing base_url value (including the sentinel if previously chosen).
  • Frontend sentinel value "doubao-coding-plan" matches the backend constant volcengine.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> with type="button" and aria-label while ignoring the click unless inputs.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

📥 Commits

Reviewing files that changed from the base of the PR and between 196fa13 and 9165b7c.

📒 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: Ignoring web/bun.lock is reasonable project hygiene

Keeping 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 consistent

The specialized prompt for type 45 clarifying AppId|AccessToken for 豆包语音输入 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/models to /models

The 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/models to 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/coding endpoint paths. The general ARK documentation does not mention these paths.

However, the verification has surfaced important concerns that validate the original review:

  1. Claude endpoint claim unsubstantiated: The first search confirmed that Volcengine provides only OpenAI-style API, with no official support for Claude-compatible /v1/messages endpoints. The code routes RelayFormatClaude to DoubaoCodingPlanClaudeBaseURL, which assumes Volcengine offers Claude compatibility—this appears unsupported.

  2. Double versioning: The models endpoint path (.../api/coding/v3/v1/models) combines two version segments, which is suspicious and unconfirmed by any documentation found.

  3. 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

@Calcium-Ion
Calcium-Ion merged commit 7598753 into QuantumNous:main Nov 16, 2025
1 check passed
Xiaoshuaiawd referenced this pull request in Xiaoshuaiawd/new-api Nov 18, 2025
* 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
ennnnny pushed a commit to ennnnny/new-api that referenced this pull request Mar 17, 2026
…ng-plan

feat: support doubao coding plan
@coderabbitai coderabbitai Bot mentioned this pull request May 1, 2026
8 tasks
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.

2 participants