Skip to content

feat: add vLLM channel type with native dual-format routing - #5912

Open
mlzy wants to merge 2 commits into
QuantumNous:mainfrom
focalcrest:feat/vllm-channel-type
Open

feat: add vLLM channel type with native dual-format routing#5912
mlzy wants to merge 2 commits into
QuantumNous:mainfrom
focalcrest:feat/vllm-channel-type

Conversation

@mlzy

@mlzy mlzy commented Jul 5, 2026

Copy link
Copy Markdown

Summary

  • Add a dedicated vLLM channel type (ID 59) that routes requests based on relay format without any protocol conversion
  • Claude format (Anthropic API) → {baseURL}/v1/messages (passthrough, preserves prompt cache headers)
  • OpenAI format → {baseURL}/v1/chat/completions (or /v1/embeddings, /v1/rerank by relay mode)

Motivation

vLLM natively supports both the Anthropic Messages API (/v1/messages) and the OpenAI Chat Completions API (/v1/chat/completions). When using the generic Custom (OpenAI) channel type to point at a local vLLM instance, New API forces all Claude-format requests through ClaudeToOpenAIRequest, losing Anthropic prompt cache headers and causing intermittent cache misses.

The existing workaround — using the Moonshot channel type — routes Claude requests to {baseURL}/anthropic/v1/messages, which is the Moonshot/Kimi path layout and does not match vLLM's standard /v1/messages endpoint.

Design

The vLLM adaptor mirrors the Moonshot dual-format pattern but uses standard OpenAI-compatible paths:

Format Endpoint
RelayFormatClaude {baseURL}/v1/messages
RelayFormatOpenAI (chat) {baseURL}/v1/chat/completions
embeddings {baseURL}/v1/embeddings
rerank {baseURL}/v1/rerank

ConvertClaudeRequest delegates to claude.Adaptor (passthrough, no conversion). DoResponse delegates to claude.Adaptor or openai.Adaptor based on relay format. No model list is shipped — vLLM serves whatever models are loaded at runtime; users configure model names via channel model mapping.

Files changed

  • relay/channel/vllm/adaptor.go — new adaptor
  • relay/channel/vllm/constants.go — channel name, empty model list
  • constant/channel.goChannelTypeVLLM = 59, base URL entry, name entry
  • constant/api_type.goAPITypeVLLM
  • common/api_type.goChannelTypeVLLM → APITypeVLLM mapping
  • relay/relay_adaptor.go — register APITypeVLLM → &vllm.Adaptor{}

Summary by CodeRabbit

  • New Features
    • Added a new vLLM channel option (ID 59), including configuration details, ordering, and matching icons.
    • Enabled vLLM request/response routing for chat (including Claude-style), embeddings, rerank, and images.
    • Recognized vLLM across API type and adaptor selection to ensure correct forwarding.
  • Notes / Limitations
    • Gemini chat, OpenAI response handling, and audio conversions are not supported.

Add a dedicated vLLM channel type (59) that routes requests based on
the relay format without protocol conversion:
- Claude format (Anthropic API) → {baseURL}/v1/messages
- OpenAI format → {baseURL}/v1/chat/completions (or embeddings/rerank)

This preserves Anthropic prompt cache headers end-to-end when clients
send Claude-format requests to a vLLM instance, which was broken when
using the generic OpenAI channel type (forces Claude→OpenAI conversion).

Unlike the Moonshot channel's SpecialBases mechanism, vLLM uses the
actual configured base URL directly — no magic keyword required.
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a949db76-a574-44ee-b35d-b27773f630bb

📥 Commits

Reviewing files that changed from the base of the PR and between 0214430 and 4790ba2.

📒 Files selected for processing (3)
  • web/default/src/features/channels/constants.ts
  • web/default/src/features/channels/lib/channel-type-config.ts
  • web/default/src/features/channels/lib/channel-utils.ts
✅ Files skipped from review due to trivial changes (1)
  • web/default/src/features/channels/lib/channel-type-config.ts

Walkthrough

This PR adds vLLM as a supported channel type. It introduces backend constants and routing, implements a new relay adaptor, and adds matching web channel metadata for the new type.

Changes

vLLM Channel Integration

Layer / File(s) Summary
Channel constants and API type mapping
constant/channel.go, constant/api_type.go, common/api_type.go
Adds ChannelTypeVLLM, APITypeVLLM, extends channel lookup tables, and maps the new channel type to the new API type.
vLLM relay adaptor and registry
relay/channel/vllm/adaptor.go, relay/channel/vllm/constants.go, relay/relay_adaptor.go
Implements the vLLM relay adaptor, defines its channel metadata, and registers it in the relay adaptor factory.
Web channel metadata for vLLM
web/default/src/features/channels/constants.ts, web/default/src/features/channels/lib/channel-type-config.ts, web/default/src/features/channels/lib/channel-utils.ts
Adds the vLLM channel to the web channel type list, configures its display metadata, and maps its icon lookup.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RelayAdaptor
  participant VLLMAdaptor
  participant ClaudeAdaptor
  participant OpenAIAdaptor

  RelayAdaptor->>VLLMAdaptor: GetAdaptor(APITypeVLLM)
  VLLMAdaptor->>VLLMAdaptor: GetRequestURL(info)
  VLLMAdaptor->>VLLMAdaptor: SetupRequestHeader(...)
  alt Claude format
    VLLMAdaptor->>ClaudeAdaptor: ConvertClaudeRequest(...)
    ClaudeAdaptor-->>VLLMAdaptor: converted request
  else image request
    VLLMAdaptor->>OpenAIAdaptor: ConvertImageRequest(...)
    OpenAIAdaptor-->>VLLMAdaptor: converted request
  end
  alt Claude response format
    VLLMAdaptor->>ClaudeAdaptor: DoResponse(...)
  else
    VLLMAdaptor->>OpenAIAdaptor: DoResponse(...)
  end
Loading

Possibly related PRs

  • QuantumNous/new-api#1915: Extends the same ChannelType2APIType switch and GetAdaptor registry to wire in a new channel adaptor.
  • QuantumNous/new-api#2190: Extends the same backend routing points for a new channel type with similar factory and switch-based wiring.

Suggested reviewers: seefs001

Poem

A rabbit hops with vLLM cheer,
New routes and icons now appear,
Claude and OpenAI lend a paw,
The relay path follows orderly law,
Hop hop hooray, a fresh channel's here! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a vLLM channel type with dual-format routing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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: 1

🤖 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/vllm/adaptor.go`:
- Around line 24-40: The GetRequestURL routing in Adaptor currently misses
RelayModeImagesGenerations and incorrectly falls back to chat completions.
Update the RelayInfo-based switch in GetRequestURL to add a
RelayModeImagesGenerations branch that returns the /v1/images/generations
endpoint, alongside the existing embeddings, rerank, and completions cases, so
ConvertImageRequest calls are sent to the correct upstream path.
🪄 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: 9c10235e-1eff-48e9-9996-48dfc2489d99

📥 Commits

Reviewing files that changed from the base of the PR and between 1ae7574 and 0214430.

📒 Files selected for processing (6)
  • common/api_type.go
  • constant/api_type.go
  • constant/channel.go
  • relay/channel/vllm/adaptor.go
  • relay/channel/vllm/constants.go
  • relay/relay_adaptor.go

Comment on lines +24 to +40
func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
switch info.RelayFormat {
case types.RelayFormatClaude:
return fmt.Sprintf("%s/v1/messages", info.ChannelBaseUrl), nil
default:
switch info.RelayMode {
case relayconstant.RelayModeEmbeddings:
return fmt.Sprintf("%s/v1/embeddings", info.ChannelBaseUrl), nil
case relayconstant.RelayModeRerank:
return fmt.Sprintf("%s/v1/rerank", info.ChannelBaseUrl), nil
case relayconstant.RelayModeCompletions:
return fmt.Sprintf("%s/v1/completions", info.ChannelBaseUrl), nil
default:
return fmt.Sprintf("%s/v1/chat/completions", info.ChannelBaseUrl), 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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant files and nearby adaptors for routing/image support.
git ls-files 'relay/channel/vllm/*' 'relay/channel/*/adaptor.go' | sed -n '1,120p'

echo '--- vllm adaptor outline ---'
ast-grep outline relay/channel/vllm/adaptor.go --view expanded || true

echo '--- vllm adaptor excerpt ---'
cat -n relay/channel/vllm/adaptor.go | sed -n '1,220p'

echo '--- search for RelayModeImagesGenerations routing in adaptors ---'
rg -n "RelayModeImagesGenerations|images/generations|ConvertImageRequest" relay/channel -g 'adaptor.go' -g '*.go'

Repository: QuantumNous/new-api

Length of output: 16659


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- openai adaptor URL routing and image conversion ---'
ast-grep outline relay/channel/openai/adaptor.go --view expanded || true

echo '--- openai adaptor excerpt around URL routing ---'
cat -n relay/channel/openai/adaptor.go | sed -n '1,220p'

echo '--- openai adaptor excerpt around image conversion / response routing ---'
cat -n relay/channel/openai/adaptor.go | sed -n '400,720p'

echo '--- shared request flow ---'
ast-grep outline relay/channel/adapter.go --view expanded || true
cat -n relay/channel/adapter.go | sed -n '1,220p'

echo '--- search for GetRequestURL usage ---'
rg -n "GetRequestURL\\(" relay/channel -g '*.go'

Repository: QuantumNous/new-api

Length of output: 35779


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- vllm constants ---'
cat -n relay/channel/vllm/constants.go | sed -n '1,220p'

echo '--- search for vllm channel registration / supported relay modes ---'
rg -n "vllm|RelayModeImagesGenerations|RelayModeImagesEdits" relay -g '*.go'

Repository: QuantumNous/new-api

Length of output: 4206


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- api request dispatch around conversion selection ---'
cat -n relay/channel/api_request.go | sed -n '250,430p'

echo '--- search for ConvertImageRequest dispatch ---'
rg -n "ConvertImageRequest\\(|RelayModeImagesGenerations|RelayModeImagesEdits" relay/channel/api_request.go relay/helper relay -g '*.go'

Repository: QuantumNous/new-api

Length of output: 17151


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- image handler ---'
cat -n relay/image_handler.go | sed -n '1,220p'

echo '--- image request validation ---'
cat -n relay/helper/valid_request.go | sed -n '120,190p'

echo '--- openai image request test ---'
cat -n relay/channel/openai/image_edit_test.go | sed -n '1,140p'

Repository: QuantumNous/new-api

Length of output: 13515


Route image generation to the image endpoint RelayModeImagesGenerations reaches ConvertImageRequest, but GetRequestURL still falls through to /v1/chat/completions. Add a branch here for /v1/images/generations so image-generation requests are sent to the correct upstream path.

🤖 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/vllm/adaptor.go` around lines 24 - 40, The GetRequestURL
routing in Adaptor currently misses RelayModeImagesGenerations and incorrectly
falls back to chat completions. Update the RelayInfo-based switch in
GetRequestURL to add a RelayModeImagesGenerations branch that returns the
/v1/images/generations endpoint, alongside the existing embeddings, rerank, and
completions cases, so ConvertImageRequest calls are sent to the correct upstream
path.

@Calcium-Ion
Calcium-Ion force-pushed the main branch 2 times, most recently from 51fdfc5 to 2b6f1df Compare August 30, 2026 15:03
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.

1 participant