Skip to content

feat(channel): add dual endpoint support for ali and minimax token plans - #4639

Closed
kewell-tsao wants to merge 1 commit into
QuantumNous:mainfrom
kewell-tsao:dev
Closed

feat(channel): add dual endpoint support for ali and minimax token plans#4639
kewell-tsao wants to merge 1 commit into
QuantumNous:mainfrom
kewell-tsao:dev

Conversation

@kewell-tsao

@kewell-tsao kewell-tsao commented May 6, 2026

Copy link
Copy Markdown

Add ali-token-plan and minimax-token-plan to ChannelSpecialBases, enabling direct routing to provider-specific endpoints based on RelayFormat
(Claude vs OpenAI) without format conversion.

⚠️ 提交说明 / PR Notice

📝 变更描述 / Description

ChannelTypeAliChannelTypeMiniMax 新增双端点支持。当渠道的 base_url 设置为特定标识字符串时(如
ali-token-planminimax-token-plan),系统可根据请求的 RelayFormat(Claude 格式 vs OpenAI 格式)自动路由到对应的 provider
原生端点,无需进行请求格式转换。

实现方式:

  • ChannelSpecialBases 映射中新增 ali-token-planminimax-token-plan 条目
  • 在 Ali 和 MiniMax 的 GetRequestURL() 方法中优先检查 ChannelSpecialBases,匹配时按格式路由到对应端点

路由规则:

  • ali-token-plan: Claude 格式 → https://token-plan.cn-beijing.maas.aliyuncs.com/apps/anthropic/v1/messages;其他格式 →
    https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/chat/completions
  • minimax-token-plan: Claude 格式 → https://api.minimaxi.com/anthropic/v1/messages;其他格式 → https://api.minimaxi.com/v1/chat/completions

🚀 变更类型 / Type of change

  • ✨ 新功能 (New feature)

🔗 关联任务 / Related Issue

  • 关联 PR: #4571 (扩展阿里云订阅计划支持) — 已添加 ali-token-plan,本次补充
    minimax-token-plan
  • 关联 PR: #2960 (minimax native /v1/messages)

✅ 提交前检查项 / Checklist

  • 人工确认: 已亲自整理并撰写此描述
  • 非重复提交: 已检索 Issues 和 PRs(扩展阿里云订阅计划支持 #4571feat: minimax native /v1/messages #2960),确认本次为 Ali + MiniMax 双端点支持的补充完善
  • Bug fix 说明: 不适用
  • 变更理解: 已理解双端点路由逻辑及影响范围
  • 范围聚焦: 仅涉及 Ali 和 MiniMax 两个 channel adaptor
  • 本地验证: go build 编译通过,gopls check 无错误

📸 运行证明 / Proof of Work

$ go build ./relay/channel/minimax/... ./relay/channel/ali/... ./constant/...
✅ Build passed

$ gopls check relay/channel/minimax/relay-minimax.go relay/channel/ali/adaptor.go constant/channel.go
✅ gopls check passed1

$ go vet ./relay/channel/minimax/... ./relay/channel/ali/... ./constant/...
✅ go vet passed

$ go test ./relay/channel/minimax/... -v
=== RUN TestGetRequestURLForImageGeneration
--- PASS: TestGetRequestURLForImageGeneration (0.00s)
=== RUN TestConvertImageRequest
--- PASS: TestConvertImageRequest (0.00s)
=== RUN TestDoResponseForImageGeneration
--- PASS: TestDoResponseForImageGeneration (0.00s)
PASS
ok github.com/QuantumNous/new-api/relay/channel/minimax 0.008s

📚 参考文档 / Reference Documentation

MiniMax 文档:

阿里云百炼文档:

Summary by CodeRabbit

  • New Features
    • Added support for Ali token plan and Minimax token plan channels
    • Implemented specialized request routing for token plan configurations to optimize URL handling across different relay formats

Add ali-token-plan and minimax-token-plan to ChannelSpecialBases, enabling
direct routing to provider-specific endpoints based on RelayFormat (Claude
vs OpenAI) without format conversion.
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR introduces special-base routing for channel adapters. New entries are added to the ChannelSpecialBases constant map ("ali-token-plan", "minimax-token-plan", and updated "doubao-coding-plan"), and the Ali and Minimax adapters are modified to check these entries and route requests through the corresponding Claude or OpenAI base URLs.

Changes

Special-Base Channel Routing

Layer / File(s) Summary
Data Shape
constant/channel.go
Added entries for "ali-token-plan" and "minimax-token-plan" to ChannelSpecialBases map, each with ClaudeBaseURL and OpenAIBaseURL. Updated "doubao-coding-plan" entry URLs.
Adapter Integration
relay/channel/ali/adaptor.go
GetRequestURL now checks if channel base URL exists in ChannelSpecialBases; if matched, constructs request URL using ClaudeBaseURL for Claude format or OpenAIBaseURL for others, then returns early. Otherwise, falls through to existing logic.
Minimax Relay Integration
relay/channel/minimax/relay-minimax.go
Added conditional logic to route endpoints through ChannelSpecialBases when available, using ClaudeBaseURL for Claude format or OpenAIBaseURL for others. Adjusted Claude case to use local baseUrl variable instead of info.ChannelBaseUrl.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Calcium-Ion

Poem

🐰 The channels now route with special care,
Ali and Minimax plan routing air,
Base URLs checked, then paths align,
Claude or OpenAI—routing divine! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'feat(channel): add dual endpoint support for ali and minimax token plans' accurately reflects the main change: adding dual-endpoint support for ali and minimax token plans through special base identifiers in ChannelSpecialBases.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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: 2

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

Inline comments:
In `@relay/channel/ali/adaptor.go`:
- Around line 96-102: The early-return in adaptor.go that maps
ChannelSpecialBases[baseURL] to either specialPlan.ClaudeBaseURL for
types.RelayFormatClaude or specialPlan.OpenAIBaseURL for others can misroute
requests and bypass relay-mode paths; update the routing so it does not
unconditionally pick Claude vs OpenAI by RelayFormat alone but instead reuses
the same special-plan resolution logic used by ConvertClaudeRequest and
DoResponse (so path, payload shape and response parsing remain consistent),
i.e., determine the intended upstream route based on the request's intended mode
(embedding/rerank/image/response) and the model-gated conversion logic, then
build the URL from specialPlan accordingly rather than short-circuiting on
info.RelayFormat.

In `@relay/channel/minimax/relay-minimax.go`:
- Around line 18-24: When a specialPlan is found the code currently forces all
non-Claude traffic to specialPlan.OpenAIBaseURL + "/chat/completions", dropping
relay-mode routing; change the branch so that after handling RelayFormatClaude
(using specialPlan.ClaudeBaseURL + "/v1/messages") you select the OpenAI
endpoint based on the same relay-format/mode logic used for the normal
(non-special) path, i.e. use info.RelayFormat / any RelayMode fields to choose
the correct path and then return specialPlan.OpenAIBaseURL + that path instead
of always "/chat/completions" (inspect and reuse the routing logic applied
elsewhere for non-special bases).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1e5756e0-5cef-4485-832b-f24ce58fe6fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9acf5fe and 221ee5a.

📒 Files selected for processing (3)
  • constant/channel.go
  • relay/channel/ali/adaptor.go
  • relay/channel/minimax/relay-minimax.go

Comment on lines +96 to +102
if specialPlan, ok := channelconstant.ChannelSpecialBases[baseURL]; ok {
switch info.RelayFormat {
case types.RelayFormatClaude:
return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
default:
return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Special-plan early return can mismatch URL with request/response format paths.

Line 98-101 forces Claude requests to anthropic URL and all non-Claude to chat-completions. That conflicts with existing model-gated conversion/response logic (Line 75-87, Line 255-263) and bypasses relay-mode routes (embeddings/rerank/images/responses), causing invalid upstream calls for reachable paths.

Suggested direction
 baseURL := info.ChannelBaseUrl
 if specialPlan, ok := channelconstant.ChannelSpecialBases[baseURL]; ok {
 	switch info.RelayFormat {
 	case types.RelayFormatClaude:
-		return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
+		if supportsAliAnthropicMessages(info.UpstreamModelName) {
+			return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
+		}
+		// fallback to existing OpenAI-compatible routing path below
 	default:
-		return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
+		// only short-circuit chat-completions; keep other relay modes on existing switch below
+		if info.RelayMode == constant.RelayModeCompletions || info.RelayMode == constant.RelayModeChatCompletions {
+			return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
+		}
 	}
 }

Also ensure ConvertClaudeRequest/DoResponse use the same special-plan rule so URL, payload shape, and response parser stay consistent.

🤖 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 `@relay/channel/ali/adaptor.go` around lines 96 - 102, The early-return in
adaptor.go that maps ChannelSpecialBases[baseURL] to either
specialPlan.ClaudeBaseURL for types.RelayFormatClaude or
specialPlan.OpenAIBaseURL for others can misroute requests and bypass relay-mode
paths; update the routing so it does not unconditionally pick Claude vs OpenAI
by RelayFormat alone but instead reuses the same special-plan resolution logic
used by ConvertClaudeRequest and DoResponse (so path, payload shape and response
parsing remain consistent), i.e., determine the intended upstream route based on
the request's intended mode (embedding/rerank/image/response) and the
model-gated conversion logic, then build the URL from specialPlan accordingly
rather than short-circuiting on info.RelayFormat.

Comment on lines +18 to +24
if specialPlan, ok := channelconstant.ChannelSpecialBases[baseUrl]; ok {
switch info.RelayFormat {
case types.RelayFormatClaude:
return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
default:
return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Special-plan path drops relay-mode routing for non-Claude requests.

At Line 23, all non-Claude traffic is forced to /chat/completions, so image/audio relay modes are misrouted when baseUrl is a special plan.

Suggested fix
 if specialPlan, ok := channelconstant.ChannelSpecialBases[baseUrl]; ok {
 	switch info.RelayFormat {
 	case types.RelayFormatClaude:
 		return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil
 	default:
-		return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
+		switch info.RelayMode {
+		case constant.RelayModeChatCompletions:
+			return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil
+		default:
+			return "", fmt.Errorf("relay mode %d is not supported for special base %q", info.RelayMode, baseUrl)
+		}
 	}
 }
🤖 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 `@relay/channel/minimax/relay-minimax.go` around lines 18 - 24, When a
specialPlan is found the code currently forces all non-Claude traffic to
specialPlan.OpenAIBaseURL + "/chat/completions", dropping relay-mode routing;
change the branch so that after handling RelayFormatClaude (using
specialPlan.ClaudeBaseURL + "/v1/messages") you select the OpenAI endpoint based
on the same relay-format/mode logic used for the normal (non-special) path, i.e.
use info.RelayFormat / any RelayMode fields to choose the correct path and then
return specialPlan.OpenAIBaseURL + that path instead of always
"/chat/completions" (inspect and reuse the routing logic applied elsewhere for
non-special bases).

@seefs001

seefs001 commented May 6, 2026

Copy link
Copy Markdown
Collaborator

无支持计划

@seefs001 seefs001 closed this May 6, 2026
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