Skip to content

feat: custom channel - #2675

Closed
seefs001 wants to merge 4974 commits into
QuantumNous:mainfrom
seefs001:feature/custom-channel
Closed

feat: custom channel#2675
seefs001 wants to merge 4974 commits into
QuantumNous:mainfrom
seefs001:feature/custom-channel

Conversation

@seefs001

@seefs001 seefs001 commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new MultiEndpoint channel type enabling configuration of multiple API endpoints with customizable URL templates.
    • Introduced a dedicated editor interface for managing multi-endpoint mappings and URL configuration.
    • Implemented path-based endpoint selection and dynamic URL template substitution.
  • Tests

    • Added comprehensive unit tests for multi-endpoint URL resolution functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

creamlike1024 and others added 30 commits November 27, 2025 18:01
feat: 视频下载和界面预览统一使用OAI标准接口
fix(aws): extract HTTP status code from AWS SDK errors
fix: nano-banana not compatible imageSize
…und-debugging

feat(playground): enhance SSE debugging and add image paste support with i18n
fix: nano banana pro 4k(StreamScannerMaxBufferMB env)
feat: glm coding plan && kimi coding plan
fix(i18n): fill missing translations in i18n.
…mageConfig

Revert "fix: gemini image correct generationConfig"
…1-i2v

Revert "Gemini Veo3.1[AI Studio]增加图生视频支持"
…-edit

Revert "Gemini Image系列支持图像编辑"
…ana-err

Revert "fix: nano-banana not compatible imageSize"
…-pro-image-preview-oai

Revert "OAI生图接口支持gemini 3 pro image preview"
…dels (Midjourney, Rerank, Suno). Add OpenAPI specifications for backend management and relay interfaces.
RedwindA and others added 26 commits January 9, 2026 18:00
Use the native Gemini Models API (/v1beta/models) instead of the OpenAI-compatible
path when listing models for Gemini channels, improving compatibility with
third-party Gemini-format providers that don't implement OpenAI routes.

- Add paginated model listing with timeout and optional proxy support
- Select an enabled key for multi-key Gemini channels
fix(gemini): fetch model list via native v1beta/models endpoint
* feat: /v1/chat/completion -> /v1/response
* fix: setting ui

* fix: rm global.chat_completions_to_responses_policy

* fix: rm global.chat_completions_to_responses_policy
fix: clean propertyNames for gemini function
…rride

feat: channel testing supports parameter overriding
* feat: codex channel

* feat: codex channel

* feat: codex oauth flow

* feat: codex refresh cred

* feat: codex usage

* fix: codex err message detail

* fix: codex setting ui

* feat: codex refresh cred task

* fix: import err

* fix: codex store must be false

* fix: chat -> responses tool call

* fix: chat -> responses tool call
# Conflicts:
#	common/api_type.go
#	constant/api_type.go
#	constant/channel.go
#	relay/relay_adaptor.go
#	web/src/components/table/channels/modals/EditChannelModal.jsx
…sing Claude's rendering logs, the two approaches handle input rendering differently.
@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Introduces a new multi-endpoint channel type (ChannelTypeMultiEndpoint) that enables routing requests to different upstream endpoints based on configured mappings and request paths. Includes backend URL resolution, relay adaptor implementation, validation logic, and frontend configuration UI.

Changes

Cohort / File(s) Summary
Type Constants
constant/api_type.go, constant/channel.go
Adds APITypeMultiEndpoint constant and ChannelTypeMultiEndpoint = 58 channel type with corresponding ChannelBaseURLs and ChannelTypeNames mappings.
API Type Mapping
common/api_type.go
Adds ChannelType2APIType case to map ChannelTypeMultiEndpoint to APITypeMultiEndpoint.
Multi-Endpoint URL Resolution
common/multi_endpoint_request_url.go
New module implementing ResolveMultiEndpointRequestURL with support for plain URLs and JSON-based endpoint mappings, template substitution ({model}, {path}, {query}), key canonicalization, and comprehensive validation for http(s)/ws(wss) schemes.
URL Resolution Tests
common/multi_endpoint_request_url_test.go
Comprehensive test coverage for URL resolution including plain URLs, JSON mappings, path-based selection, template expansion, key canonicalization, realtime WebSocket schemes, and error conditions.
Channel Validation & Model Listing
controller/channel.go
Adds multi-endpoint channel validation requiring non-empty base_url with http(s)/ws(wss) scheme validation; blocks FetchModels endpoint for multi-endpoint channels.
Relay Adaptor Delegation
relay/relay_adaptor.go
Wires new MultiEndpoint adaptor into GetAdaptor switch for APITypeMultiEndpoint.
Multi-Endpoint Request Handling
relay/channel/multiendpoint/adaptor.go
New adaptor implementing relay interface with delegation to OpenAI, Claude, and Gemini sub-adaptors; resolves URLs via multi-endpoint resolution, routes requests by relay mode, and centralizes response handling.
Frontend Channel Editor
web/src/components/table/channels/modals/EditChannelModal.jsx
Extends EditChannelModal with multi-endpoint editor integration: adds state for editor visibility and draft URL; conditionally renders editor modal and configured/unconfigured status tag for type 58 channels.
Multi-Endpoint URL Editor Component
web/src/components/table/channels/modals/MultiEndpointBaseUrlEditor.jsx
New React component for configuring endpoint mappings with visual (endpoint-per-endpoint) and raw (JSON textarea) editing modes, real-time validation, template utilities, and status indicators for required endpoints.
Frontend Channel Constants
web/src/constants/channel.constants.js
Adds new channel option { value: 58, color: 'green', label: '多端点渠道' } to CHANNEL_OPTIONS.

Sequence Diagram

sequenceDiagram
    participant UI as Frontend<br/>(EditChannelModal)
    participant Ctrl as Controller
    participant Resolver as URL Resolver<br/>(multi_endpoint_request_url)
    participant RelayAdaptor as Relay Adaptor<br/>(multiendpoint)
    participant SubAdaptor as Sub-Adaptor<br/>(OpenAI/Claude/Gemini)

    UI->>Ctrl: POST /channel validate config
    Ctrl->>Resolver: ResolveMultiEndpointRequestURL(baseURL, path)
    Resolver->>Resolver: Parse JSON or plain URL
    Resolver->>Resolver: Apply template {model}, {path}, {query}
    Resolver->>Resolver: Validate scheme & required endpoints
    Resolver-->>Ctrl: Resolved URL or error
    Ctrl-->>UI: Validation result

    UI->>Ctrl: Route request via multi-endpoint channel
    Ctrl->>RelayAdaptor: Init & GetRequestURL
    RelayAdaptor->>Resolver: ResolveMultiEndpointRequestURL(config, requestPath)
    Resolver-->>RelayAdaptor: Resolved URL
    RelayAdaptor->>RelayAdaptor: Select sub-adaptor by relay format/mode
    RelayAdaptor->>SubAdaptor: ConvertRequest & DoRequest
    SubAdaptor-->>RelayAdaptor: Response
    RelayAdaptor->>RelayAdaptor: DoResponse
    RelayAdaptor-->>Ctrl: Final response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 A channel with endpoints galore,
Now routes through the multi-endpoint door,
Templates dance with {model} and {path},
While adaptors split traffic in half,
Multi-endpoint magic, now part of our lore! 🌟

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'feat: custom channel' is overly vague and does not clearly describe the specific change. The PR actually introduces multi-endpoint URL resolution support with new channel type mappings, adapters, and UI components, which is more specific than a generic 'custom channel' feature. Consider revising the title to be more specific, such as 'feat: add multi-endpoint channel support with URL resolution' to better reflect the actual implementation and help reviewers quickly understand the primary change.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

🤖 Fix all issues with AI agents
In `@constant/channel.go`:
- Line 122: Update the incorrect inline index comment for the
ChannelTypeMultiEndpoint entry: change the trailing comment from "//57" to
"//58" near the ChannelTypeMultiEndpoint constant definition (the previous line
already uses index 57 for ChannelTypeCodex), so the comment matches the actual
index without changing any code logic.

In `@relay/channel/multiendpoint/adaptor.go`:
- Around line 118-120: GetModelList on Adaptor currently forwards only to
a.openai.GetModelList(), which omits Claude/Gemini models; update
Adaptor.GetModelList to aggregate and return the union of all sub-adaptors'
model lists (e.g., call a.openai.GetModelList(), a.claude.GetModelList(),
a.gemini.GetModelList()), deduplicate entries, and return the combined slice, or
if model lists are externally configured, document/rename the method to avoid
implying multi-endpoint coverage. Ensure you reference Adaptor.GetModelList and
the sub-adaptor fields a.openai, a.claude, a.gemini when making the change.
🧹 Nitpick comments (7)
common/multi_endpoint_request_url.go (4)

36-36: Incomplete docstring for Realtime behavior.

The function comment starts "Realtime behavior:" but has no content. Either complete the documentation or remove the placeholder.


84-98: Silent skipping of invalid config entries may hide misconfiguration.

Invalid keys (unrecognized after canonicalization) and non-string values are silently ignored. This could make debugging configuration issues difficult for users. Consider logging a warning or returning validation errors for unrecognized keys.


114-115: Consider breaking long case line for readability.

Line 114 contains many aliases making it difficult to read. Consider splitting into multiple lines or grouping related aliases.

♻️ Suggested formatting
-	case "image", "images", "openai_image", "openai_image_generation", "openai_image_edit", "image_generation", "imagegeneration", "image_generations", "imagegenerations", "image_edit", "imageedit", "image_edits", "imageedits":
+	case "image", "images", "openai_image",
+		"openai_image_generation", "openai_image_edit",
+		"image_generation", "imagegeneration",
+		"image_generations", "imagegenerations",
+		"image_edit", "imageedit",
+		"image_edits", "imageedits":
 		return MultiEndpointKeyOpenAIImage

175-177: Brace detection may produce false positives for legitimate URLs.

URLs can legitimately contain { or } characters (especially in query parameters). This check could reject valid URLs. Consider checking only for specific unsupported placeholder patterns like {word} instead.

♻️ Suggested pattern-based check
-	if strings.Contains(out, "{") || strings.Contains(out, "}") {
-		return "", fmt.Errorf("multi-endpoint URL template contains unsupported variables")
+	// Check for unsupported placeholders like {variable}
+	if matched, _ := regexp.MatchString(`\{[a-zA-Z_]+\}`, out); matched {
+		return "", fmt.Errorf("multi-endpoint URL template contains unsupported variables")
 	}
common/multi_endpoint_request_url_test.go (1)

1-139: Comprehensive test coverage for multi-endpoint URL resolution.

The tests cover key scenarios including:

  • Plain URL and JSON config parsing
  • Default/fallback resolution
  • Path-based endpoint selection
  • Key canonicalization (aliases like openai-responseopenai_responses)
  • Template variable substitution ({model}, {path}, {query})
  • WebSocket scheme support
  • Error handling for invalid JSON

Consider adding edge case tests for completeness:

💡 Optional: Additional test cases
func TestResolveMultiEndpointRequestURL_EmptyConfig(t *testing.T) {
	got, err := ResolveMultiEndpointRequestURL("", "/v1/chat/completions", "gpt-4o-mini")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got != "" {
		t.Fatalf("expected empty string, got: %q", got)
	}
}

func TestResolveMultiEndpointRequestURL_WhitespaceOnlyConfig(t *testing.T) {
	got, err := ResolveMultiEndpointRequestURL("   \n\t  ", "/v1/chat/completions", "gpt-4o-mini")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got != "" {
		t.Fatalf("expected empty string, got: %q", got)
	}
}
web/src/components/table/channels/modals/MultiEndpointBaseUrlEditor.jsx (1)

237-241: Consider using value directly in the useEffect dependency array.

The current dependencies [parsed.mapping, parsed.error] might cause the effect to miss updates if the raw value changes but parses to the same mapping. Since parsed is memoized on value, using value directly would be clearer:

💡 Optional: Simplify dependency array
  useEffect(() => {
    setLocal(parsed.mapping);
    setParseError(parsed.error);
    setRawText(typeof value === 'string' ? value : '');
-  }, [parsed.mapping, parsed.error]);
+  }, [value, parsed.mapping, parsed.error]);
relay/channel/multiendpoint/adaptor.go (1)

34-49: Method has side effects that mutate input parameters.

GetRequestURL mutates info.ChannelBaseUrl and info.ChannelMeta.ChannelBaseUrl (lines 43-46), which is unexpected for a method named with a "Get" prefix. This side effect pattern can lead to subtle bugs if callers don't expect mutation.

Consider either:

  1. Renaming to ResolveRequestURL to signal mutation, or
  2. Adding a comment documenting this intentional side effect.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ef99f4 and 8841a2a.

📒 Files selected for processing (11)
  • common/api_type.go
  • common/multi_endpoint_request_url.go
  • common/multi_endpoint_request_url_test.go
  • constant/api_type.go
  • constant/channel.go
  • controller/channel.go
  • relay/channel/multiendpoint/adaptor.go
  • relay/relay_adaptor.go
  • web/src/components/table/channels/modals/EditChannelModal.jsx
  • web/src/components/table/channels/modals/MultiEndpointBaseUrlEditor.jsx
  • web/src/constants/channel.constants.js
🧰 Additional context used
🧠 Learnings (2)
📚 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 (6)
common/api_type.go (2)
constant/channel.go (1)
  • ChannelTypeMultiEndpoint (58-58)
constant/api_type.go (1)
  • APITypeMultiEndpoint (39-39)
web/src/components/table/channels/modals/MultiEndpointBaseUrlEditor.jsx (1)
web/src/helpers/utils.jsx (1)
  • copy (72-95)
controller/channel.go (3)
constant/channel.go (1)
  • ChannelTypeMultiEndpoint (58-58)
common/str.go (1)
  • StrToMap (45-52)
common/multi_endpoint_request_url.go (1)
  • ResolveMultiEndpointRequestURL (37-76)
common/multi_endpoint_request_url_test.go (1)
common/multi_endpoint_request_url.go (1)
  • ResolveMultiEndpointRequestURL (37-76)
relay/relay_adaptor.go (2)
constant/api_type.go (1)
  • APITypeMultiEndpoint (39-39)
relay/channel/multiendpoint/adaptor.go (1)
  • Adaptor (22-26)
common/multi_endpoint_request_url.go (2)
common/json.go (1)
  • Unmarshal (9-11)
relay/constant/relay_mode.go (12)
  • Path2RelayMode (55-91)
  • RelayModeResponses (48-48)
  • RelayModeEmbeddings (12-12)
  • RelayModeImagesGenerations (14-14)
  • RelayModeImagesEdits (15-15)
  • RelayModeEdits (16-16)
  • RelayModeAudioSpeech (35-35)
  • RelayModeAudioTranscription (36-36)
  • RelayModeAudioTranslation (37-37)
  • RelayModeRealtime (50-50)
  • RelayModeRerank (46-46)
  • RelayModeGemini (52-52)
🔇 Additional comments (24)
common/multi_endpoint_request_url.go (3)

1-23: LGTM!

The package structure, imports, and constants are well-defined. The endpoint key constants provide clear, consistent naming for the supported endpoint types.


133-155: LGTM!

The path-to-endpoint-key mapping correctly handles the Claude special case and delegates to Path2RelayMode for standard OpenAI-compatible paths. The default fallback to MultiEndpointKeyOpenAI is appropriate.


181-216: LGTM!

The URL validation is comprehensive:

  • Validates URL syntax and required components (scheme, host).
  • Enforces correct scheme for realtime (ws/wss) vs standard (http/https) endpoints.
  • Requires explicit path and query handling to prevent silent data loss.

This explicit configuration requirement aligns well with the design note at line 218-219.

relay/relay_adaptor.go (1)

124-125: LGTM!

The new case for APITypeMultiEndpoint follows the established pattern and correctly instantiates the multiendpoint adaptor.

web/src/constants/channel.constants.js (1)

122-122: LGTM!

The new channel option correctly maps to the backend's ChannelTypeMultiEndpoint = 58 constant and follows the existing pattern for channel definitions.

constant/api_type.go (1)

39-40: LGTM!

The new APITypeMultiEndpoint constant is correctly placed before the APITypeDummy sentinel, maintaining the iota sequence without affecting existing constant values.

common/api_type.go (1)

78-79: LGTM!

The new mapping from ChannelTypeMultiEndpoint to APITypeMultiEndpoint correctly follows the established pattern and completes the integration between channel types and API types.

controller/channel.go (2)

593-630: Multi-endpoint channel validation logic looks solid.

The validation correctly:

  1. Ensures base_url is non-empty
  2. Validates URL schemes (http/https/ws/wss) for both plain URLs and JSON object values
  3. Uses ResolveMultiEndpointRequestURL to verify at least a default or openai endpoint is configured

One minor observation: the error messages are in Chinese which is consistent with the rest of the codebase.


1167-1173: Appropriate guard for multi-endpoint channels in FetchModels.

Multi-endpoint channels route requests to different backends based on the request path, so there's no single upstream to query for a model list. Returning an informative error message is the right approach.

constant/channel.go (1)

58-58: New channel type constant and name mapping are properly defined.

The constant ChannelTypeMultiEndpoint = 58 and its corresponding name "MultiEndpoint" in ChannelTypeNames are correctly added and follow the existing patterns.

Also applies to: 180-180

web/src/components/table/channels/modals/EditChannelModal.jsx (4)

189-192: State management for multi-endpoint editor is properly initialized.

The two new state variables handle the editor's visibility and draft content appropriately, following the component's existing patterns.


502-518: Codex channel (type 57) template initialization looks appropriate.

The template is only set when base_url is empty, providing a helpful default without overwriting existing configurations.


2578-2610: Multi-endpoint channel UI (type 58) is well-designed.

The UI provides clear visual feedback with a status Tag showing whether endpoints are configured, and a dedicated button to open the endpoint mapping editor. The isIonetLocked check appropriately prevents editing for IO.NET-managed channels.


3403-3433: Modal for endpoint mapping editor is correctly integrated.

The modal properly:

  • Uses draft state to isolate changes until explicitly saved
  • Respects isIonetLocked to prevent unauthorized modifications
  • Applies changes through handleInputChange which triggers proper form state updates
web/src/components/table/channels/modals/MultiEndpointBaseUrlEditor.jsx (5)

44-126: Well-structured endpoint configuration metadata.

The ENDPOINTS array provides clear metadata for each supported endpoint including:

  • Canonical keys for backend matching
  • Descriptions for user guidance
  • Path patterns for auto-fill functionality
  • fillable flag to control quick-fill behavior

The separation of concerns here is clean and maintainable.


130-176: Key canonicalization handles aliases comprehensively.

The function normalizes various key formats (underscores, hyphens, singular/plural) to canonical keys, ensuring flexibility in user input while maintaining consistency. The empty string return for unrecognized keys is safely handled by the caller.


183-222: Config parsing and serialization are well-implemented.

Notable design choices:

  • parseConfig gracefully handles both plain URLs and JSON configs
  • stableStringify maintains consistent key ordering for predictable output
  • Single-endpoint optimization (line 220) returns plain URL when only openai is configured, reducing complexity for simple cases

420-536: Visual editing mode provides excellent UX.

The implementation includes:

  • Clear navigation with status indicators (configured/required/unconfigured)
  • Inline help text explaining the expected input format
  • Quick-fill feature to auto-complete endpoints from a base URL
  • Proper i18n support with t() for all user-facing strings

408-418: Raw editing mode with real-time validation is useful for advanced users.

The textarea provides direct JSON editing with immediate feedback via the error banner when parsing fails.

relay/channel/multiendpoint/adaptor.go (5)

51-66: LGTM!

Header setup correctly delegates to the appropriate sub-adaptor based on relay format, with proper OpenAI-Organization header handling for the default case.


76-81: Consider adding Claude format handling for consistency.

ConvertEmbeddingRequest handles Gemini format explicitly but falls back to OpenAI for Claude format. If Claude supports embeddings with a different format, this could produce incorrect requests. If Claude doesn't support embeddings or uses OpenAI-compatible format, consider adding a comment clarifying this intentional design.


95-105: LGTM!

Request handling correctly routes to the appropriate method (form, WebSocket, or API) based on relay mode.


107-116: LGTM!

Response handling correctly delegates to the appropriate sub-adaptor based on relay format.


126-132: LGTM!

Claude and Gemini request conversion methods correctly delegate to their respective sub-adaptors.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread constant/channel.go
"https://api.openai.com", //55
"https://api.replicate.com", //56
"https://chatgpt.com", //57
"", //57

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 | 🟡 Minor

Incorrect comment: should be //58 not //57.

The comment indicates index 57, but this entry is at index 58 for ChannelTypeMultiEndpoint. The previous line (121) already covers index 57 for ChannelTypeCodex.

🔧 Suggested fix
-	"",                                          //57
+	"",                                          //58
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"", //57
"", //58
🤖 Prompt for AI Agents
In `@constant/channel.go` at line 122, Update the incorrect inline index comment
for the ChannelTypeMultiEndpoint entry: change the trailing comment from "//57"
to "//58" near the ChannelTypeMultiEndpoint constant definition (the previous
line already uses index 57 for ChannelTypeCodex), so the comment matches the
actual index without changing any code logic.

Comment on lines +118 to +120
func (a *Adaptor) GetModelList() []string {
return a.openai.GetModelList()
}

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 | 🟡 Minor

Model list only includes OpenAI models.

GetModelList returns only the OpenAI adaptor's model list, but this multi-endpoint adaptor also supports Claude and Gemini formats. If this method is used for model validation or discovery, it may incorrectly reject valid Claude/Gemini models.

Consider aggregating models from all three sub-adaptors or clarifying if model lists are configured externally.

🤖 Prompt for AI Agents
In `@relay/channel/multiendpoint/adaptor.go` around lines 118 - 120, GetModelList
on Adaptor currently forwards only to a.openai.GetModelList(), which omits
Claude/Gemini models; update Adaptor.GetModelList to aggregate and return the
union of all sub-adaptors' model lists (e.g., call a.openai.GetModelList(),
a.claude.GetModelList(), a.gemini.GetModelList()), deduplicate entries, and
return the combined slice, or if model lists are externally configured,
document/rename the method to avoid implying multi-endpoint coverage. Ensure you
reference Adaptor.GetModelList and the sub-adaptor fields a.openai, a.claude,
a.gemini when making the change.

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.