Skip to content

refactor: Introduce standardized API error and support multi keys for channel - #1360

Merged
t0ng7u merged 20 commits into
alphafrom
multi_keys_channel
Jul 12, 2025
Merged

refactor: Introduce standardized API error and support multi keys for channel#1360
t0ng7u merged 20 commits into
alphafrom
multi_keys_channel

Conversation

@Calcium-Ion

@Calcium-Ion Calcium-Ion commented Jul 12, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added comprehensive multi-key channel support with batch creation, key aggregation modes (random/polling), and per-key status management.
    • Enhanced channel management UI: multi-key file upload, aggregation mode selection, and detailed multi-key status display.
    • Introduced a unified error handling framework for consistent, detailed API error reporting.
    • Improved localization with new translations for key aggregation modes and deployment region inputs.
  • Bug Fixes

    • Improved JSON parsing error handling and validation in channel operations.
    • Fixed multi-key channel key management and cache synchronization issues.
  • Refactor

    • Streamlined error handling across backend and relay layers using a new error type.
    • Updated APIs and internal logic with new multi-key support, including adjusted function signatures and parameter orders.
  • Style

    • Reorganized UI components to improve visibility and usability of channel-specific settings.
  • Documentation

    • Expanded localization strings covering multi-key features and deployment region inputs.

Calcium-Ion and others added 18 commits June 16, 2025 00:37
Previously, the Playground UI allowed users to pick a group, but the request body sent to `/pg/chat/completions` did not include this information, so the backend always fell back to the user’s default group.

Changes introduced
• web/src/helpers/api.js – added `group: inputs.group` to the `payload` built in `buildApiPayload`.

Outcome
• Selected group is now transmitted to the backend, enabling proper channel routing and pricing logic based on group ratios.
• Resolves the issue where group selection appeared ineffective in the Playground.
… multi-to-single mode

WHY
• Backend (0089157) now accepts structured request `{ mode, channel }`, including new `multi_to_single`.
• Need front-end to upload multiple service-account JSON files and generate correct `channel.key`.
• Improve UX: avoid red “uploadFail” state and offer drag-and-drop UI.

WHAT
1. EditChannel.js
   • Added Upload drag-area with IconBolt; `uploadTrigger="custom"`.
   • `handleJsonFileUpload` reads file, pushes content to `jsonFiles`, returns `{ shouldUpload:false, status:'success' }`.
   • New states: `batch`, `mergeToSingle`, `jsonFiles`.
   • Dynamic mode resolver: `single` | `batch` | `multi_to_single`.
   • Builds `channel.key` as JSON-object whose keys are the raw credential texts.
   • UI:
     – “Batch create” checkbox (new build only).
     – Nested “Merge to single channel (multi-key mode)” checkbox enabled when batch=true.
     – Real-time file count display.

2. Upload UX
   • Drag-and-drop, accepts `.json,application/json`.
   • Custom texts: “Click or drop files here” / “JSON credentials only”.
   • Eliminated mandatory `action` warning (`action="#"`).

3. Misc
   • Included IconBolt import.
   • Safeguard toggles reset logic to prevent stale state.

RESULT
Front-end now fully aligns with enhanced AddChannel API:
• Supports Vertex AI multi JSON batch creation.
• Supports new `multi_to_single` flow.
• Clean user feedback with successful file status.
# Conflicts:
#	controller/channel.go
#	docker-compose.yml
#	web/src/components/table/ChannelsTable.js
#	web/src/pages/Channel/EditChannel.js
… settings

Summary
-------
1. Vertex AI JSON key upload
   • Accept multiple `.json` files (drag & drop / click).
   • Parse each `fileInstance`; build valid key array.
   • Malformed files are skipped and collected into **one** toast message.
   • Upload list now仅displays valid files; form state (`vertex_files`) 同步保持.
   • On *Submit* keys are re-parsed to prevent async timing loss.

2. Multi-key mode stability
   • Added `multi_key_mode: "random"` to initial form values.
   • `Form.Select` becomes fully controlled (`value`/`onChange`).
   • Toggling the “multi-key mode” checkbox writes default / removes field, so
     `setValues(inputs)` no longer clears the user’s choice.

3. UX / compatibility tweaks
   • Preserve uploaded files when editing any other field.
   • Use `fileInstance` only – compatible with legacy Semi Upload API.
   • Removed redundant `limit` prop on `Form.Upload`.
   • Aggregated error handling avoids toast spam.

Result
------
Channel creation/update now supports:
• Reliable batch import of Vertex AI service-account keys.
• Consistent retention of multi-key strategy (`random` / `polling`).
• Cleaner, user-friendly error feedback.
…correct Vertex-AI key storage**

Summary
1. **model/channel.go**
   • Replaced the pointer-only `Value()` with a value-receiver implementation
   • GORM can now marshal both `ChannelInfo` and `*ChannelInfo`, eliminating
     `unsupported type model.ChannelInfo` runtime error.

2. **controller/channel.go**
   • Refactored `getVertexArrayKeys()` – every element is now
     - passed through `json.Marshal` when not already a string
     - trimmed & validated before insertion
   • Guarantees each service-account key is persisted as a **pure JSON string**
     instead of the previous `map[...]` dump.

Result
• Channel creation / update succeeds without SQL driver errors.
• Vertex-AI batch & multi-key uploads are stored in canonical JSON, ready for
  downstream SDKs to consume.
Summary
1. Load `channel_info` when editing:
   • Detect if the channel is in multi-key mode (`is_multi_key`).
   • Auto-initialize `batch`, `multiToSingle`, and `multiKeyMode` from backend data.

2. Visibility logic
   • Creation page: “Batch create / Multi-key mode” always available.
   • Edit page: show these controls **only when** the channel itself is multi-key.

3. State consistency
   • `multi_key_mode` added to `inputs`; `setValues(inputs)` now preserves the user’s selection.

Result
Single-key channels no longer display irrelevant “key aggregation” options, while multi-key channels open with the correct defaults, providing a cleaner and more accurate editing experience.
This commit refactors the application's error handling mechanism by introducing a new standardized error type, `types.NewAPIError`. It also renames common JSON utility functions for better clarity.

Previously, internal error handling was tightly coupled to the `dto.OpenAIError` format. This change decouples the internal logic from the external API representation.

Key changes:
- A new `types.NewAPIError` struct is introduced to serve as a canonical internal representation for all API errors.
- All relay adapters (OpenAI, Claude, Gemini, etc.) are updated to return `*types.NewAPIError`.
- Controllers now convert the internal `NewAPIError` to the client-facing `OpenAIError` format at the API boundary, ensuring backward compatibility.
- Channel auto-disable/enable logic is updated to use the new standardized error type.
- JSON utility functions are renamed to align with Go's standard library conventions (e.g., `UnmarshalJson` -> `Unmarshal`, `EncodeJson` -> `Marshal`).
# Conflicts:
#	controller/channel.go
#	middleware/distributor.go
#	model/channel.go
#	model/user.go
#	model/user_cache.go
#	relay/common/relay_info.go
@coderabbitai

coderabbitai Bot commented Jul 12, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This update introduces comprehensive multi-key channel support across backend and frontend, including new error handling abstractions, enhanced channel model and cache structures, and UI changes for managing multi-key channels. Error handling is unified under a new NewAPIError type, and multi-key aggregation modes (random, polling) are now supported, with corresponding API, model, and UI adaptations for key selection, status, and management.

Changes

File(s) Change Summary
types/error.go, types/channel_error.go, constant/multi_key_mode.go Introduced new error handling and channel error types, enums for error codes/types, and multi-key mode constants.
relay/*, relay/channel/*, relay/common_handler/rerank.go Unified error handling to use types.NewAPIError; refactored function signatures and error returns; standardized error construction and propagation.
controller/relay.go, controller/playground.go, controller/channel-test.go, controller/channel.go Refactored controllers for new error types, structured test results, multi-key request handling, and stricter validation.
service/channel.go, service/error.go, service/convert.go Refactored channel enable/disable logic, error handling, and JSON marshaling for compatibility with new types.
model/channel.go, model/channel_cache.go Added ChannelInfo struct for multi-key management, thread-safe key selection, polling locks, and cache update logic.
middleware/auth.go, middleware/distributor.go Added helper for token context setup, improved group extraction, and multi-key channel context handling.
common/str.go, common/json.go, common/gin.go Enhanced JSON utility functions, added error returns, array/object validators, and updated function names.
constant/context_key.go Expanded and unified context key constants for channel properties and multi-key support.
dto/* Updated error fields in DTOs to use new error types from types package.
web/src/components/table/ChannelsTable.js, web/src/pages/Channel/EditChannel.js Added UI for multi-key channels, batch key upload, aggregation mode selection, multi-key status rendering, and enable-all-keys action.
web/src/helpers/api.js Minor change: duplicate group property in API payload construction.
web/src/i18n/locales/en.json Added/updated translations for multi-key and aggregation mode UI.
model/user_cache.go, model/log.go, model/main.go Updated JSON handling, error discards, and removed legacy SQL migration code.
relay/relay-mj.go Updated channel status update call for new multi-key signature.
relay/common/relay_info.go, service/midjourney.go Changed API key extraction to use context keys for consistency.
dto/openai_request.go Updated struct-to-map conversion to use new JSON utility functions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebUI
    participant API
    participant Controller
    participant Model
    participant ChannelCache

    User->>WebUI: Uploads multiple key files (Vertex) or enters keys
    WebUI->>API: Submits Add/Update Channel (mode, multi_key_mode, keys)
    API->>Controller: Receives request, validates input
    Controller->>Model: Processes keys, sets ChannelInfo (multi-key, mode)
    Model->>ChannelCache: Updates channel cache with multi-key info
    Controller->>API: Responds success/failure

    Note over Controller,Model: On relay request:
    API->>Controller: Receives relay request
    Controller->>ChannelCache: Fetches channel info
    alt Multi-key channel
        ChannelCache->>Model: Selects key (random/polling)
    end
    Controller->>API: Proxies request using selected key

    Note over Controller,Model: On error:
    Controller->>types.NewAPIError: Wraps error with code/type
    Controller->>Service: Decides enable/disable channel/key based on error
Loading

Poem

In a meadow of keys, a rabbit hops,
Now channels hold many, not just one in their crops.
With random or polling, the keys take their turn,
Errors unified, so clean—no more to unlearn!
The UI sparkles with batch and mode,
Multi-key magic—let’s hop down this road! 🐇✨

✨ 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🔭 Outside diff range comments (7)
relay/channel/aws/adaptor.go (1)

88-95: Critical: Fix incorrect assignment order and parameter ordering.

The assignment order is incorrect and doesn't match the function signature. The function returns (usage any, err *types.NewAPIError) but the assignments are err, usage = ....

Apply this diff to fix the assignment and parameter ordering:

 func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) {
 	if info.IsStream {
-		err, usage = awsStreamHandler(c, resp, info, a.RequestMode)
+		usage, err = awsStreamHandler(c, info, resp, a.RequestMode)
 	} else {
-		err, usage = awsHandler(c, info, a.RequestMode)
+		usage, err = awsHandler(c, info, resp, a.RequestMode)
 	}
 	return
 }

Note: You'll also need to verify that the handler function signatures in relay/channel/aws/relay-aws.go match these parameter orders and return the correct types.

relay/channel/baidu/adaptor.go (1)

144-156: Fix inconsistent return value assignment order.

The method signature correctly returns (usage any, err *types.NewAPIError), but the handler calls have inconsistent return value assignment. The calls should assign usage, err instead of err, usage to match the standardized return order.

Apply this diff to fix the return value assignment:

-		err, usage = baiduStreamHandler(c, info, resp)
+		usage, err = baiduStreamHandler(c, info, resp)
-			err, usage = baiduEmbeddingHandler(c, info, resp)
+			usage, err = baiduEmbeddingHandler(c, info, resp)
-			err, usage = baiduHandler(c, info, resp)
+			usage, err = baiduHandler(c, info, resp)
relay/channel/ali/adaptor.go (1)

103-119: Fix inconsistent return value assignment patterns.

The method has mixed return value assignment patterns. Lines 106, 108, 110 use err, usage = ... while lines 113, 115 use usage, err = .... All assignments should follow the standardized pattern usage, err = ... to match the method signature.

Apply this diff to fix the inconsistent return value assignments:

-		err, usage = aliImageHandler(c, resp, info)
+		usage, err = aliImageHandler(c, resp, info)
-		err, usage = aliEmbeddingHandler(c, resp)
+		usage, err = aliEmbeddingHandler(c, resp)
-		err, usage = RerankHandler(c, resp, info)
+		usage, err = RerankHandler(c, resp, info)
relay/channel/vertex/adaptor.go (1)

212-241: Fix inconsistent return value assignment for Claude handlers.

The method has mixed return value assignment patterns. Claude handler calls on lines 216 and 229 use err, usage = ... while all other handlers use usage, err = .... All assignments should follow the standardized pattern to match the method signature.

Apply this diff to fix the inconsistent Claude handler assignments:

-			err, usage = claude.ClaudeStreamHandler(c, resp, info, claude.RequestModeMessage)
+			usage, err = claude.ClaudeStreamHandler(c, resp, info, claude.RequestModeMessage)
-			err, usage = claude.ClaudeHandler(c, resp, claude.RequestModeMessage, info)
+			usage, err = claude.ClaudeHandler(c, resp, claude.RequestModeMessage, info)
relay/channel/palm/relay-palm.go (1)

76-125: Return signature inconsistent with other handlers.

This handler returns (*types.NewAPIError, string) while other handlers return (*dto.Usage, *types.NewAPIError). Consider aligning with the standard pattern for consistency.

The current goroutine implementation could be simplified using the helper pattern similar to Baidu's implementation:

-func palmStreamHandler(c *gin.Context, resp *http.Response) (*types.NewAPIError, string) {
+func palmStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Response) (*dto.Usage, *types.NewAPIError) {
relay/channel/openai/relay-openai.go (2)

266-286: Inconsistent return value order.

This function returns (*types.NewAPIError, *dto.Usage) while other handler functions in this file return (usage, error). For consistency with Go conventions and the rest of the codebase, consider changing to:

-func OpenaiSTTHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo, responseFormat string) (*types.NewAPIError, *dto.Usage) {
+func OpenaiSTTHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo, responseFormat string) (*dto.Usage, *types.NewAPIError) {

And update the return statements accordingly:

-		return types.NewError(err, types.ErrorCodeCountTokenFailed), nil
+		return nil, types.NewError(err, types.ErrorCodeCountTokenFailed)
-		return types.NewError(err, types.ErrorCodeReadResponseBodyFailed), nil
+		return nil, types.NewError(err, types.ErrorCodeReadResponseBodyFailed)
-	return nil, usage
+	return usage, nil

330-535: Inconsistent return value order in realtime handler.

Similar to OpenaiSTTHandler, this function returns (*types.NewAPIError, *dto.RealtimeUsage) which is inconsistent with the (usage, error) pattern used elsewhere.

Consider updating to maintain consistency:

-func OpenaiRealtimeHandler(c *gin.Context, info *relaycommon.RelayInfo) (*types.NewAPIError, *dto.RealtimeUsage) {
+func OpenaiRealtimeHandler(c *gin.Context, info *relaycommon.RelayInfo) (*dto.RealtimeUsage, *types.NewAPIError) {

And adjust return statements:

-		return types.NewError(fmt.Errorf("invalid websocket connection"), types.ErrorCodeBadResponse), nil
+		return nil, types.NewError(fmt.Errorf("invalid websocket connection"), types.ErrorCodeBadResponse)
-	return nil, sumUsage
+	return sumUsage, nil
🧹 Nitpick comments (15)
model/main.go (1)

60-60: Consider keeping the SQL type logging for debugging purposes.

Commenting out this logging statement removes visibility into which SQL type is being used for the log database. This information could be valuable for debugging database connection issues.

Consider keeping this log statement or moving it to a debug-level log if you want to reduce noise in production logs:

-	//common.SysLog("Using Log SQL Type: " + common.LogSqlType)
+	if common.DebugEnabled {
+		common.SysLog("Using Log SQL Type: " + common.LogSqlType)
+	}
types/error.go (2)

159-169: Add defensive check for type assertion to prevent potential panic.

The type assertion on line 161 could fail if openAIError.Code is not a string type, even though you have a fallback with fmt.Sprintf.

Consider simplifying this to always use fmt.Sprintf which handles all types safely:

 func WithOpenAIError(openAIError OpenAIError, statusCode int) *NewAPIError {
-	code, ok := openAIError.Code.(string)
-	if !ok {
-		code = fmt.Sprintf("%v", openAIError.Code)
-	}
+	code := fmt.Sprintf("%v", openAIError.Code)
 	return &NewAPIError{
 		RelayError: openAIError,
 		ErrorType:  ErrorTypeOpenAIError,
 		StatusCode: statusCode,
 		Err:        errors.New(openAIError.Message),
 		errorCode:  ErrorCode(code),
 	}
 }

182-187: Consider using a more robust method for identifying channel errors.

Using string prefix matching for error classification could be fragile if error codes change format in the future.

Consider adding a dedicated field or using a type-based approach:

+// Add to ErrorCode constants
+const ErrorCodeChannelPrefix = "channel:"
+
 func IsChannelError(err *NewAPIError) bool {
 	if err == nil {
 		return false
 	}
-	return strings.HasPrefix(string(err.errorCode), "channel:")
+	return strings.HasPrefix(string(err.errorCode), ErrorCodeChannelPrefix)
 }
model/log.go (1)

52-52: Compatibility change for updated StrToMap signature.

The change correctly handles the new error return from common.StrToMap. However, consider whether the error should be logged or handled rather than silently discarded, especially since this involves parsing user data that could be malformed.

Consider logging parse errors for debugging:

-		otherMap, _ = common.StrToMap(logs[i].Other)
+		otherMap, err := common.StrToMap(logs[i].Other)
+		if err != nil {
+			// Log parse error but continue processing
+			otherMap = make(map[string]interface{})
+		}
common/str.go (2)

44-51: Use consistent JSON unmarshaling approach.

The StrToJsonArray function uses json.Unmarshal directly, which is inconsistent with the pattern used in StrToMap that uses common.Unmarshal.

Apply this diff for consistency:

-	err := json.Unmarshal([]byte(str), &js)
+	err := Unmarshal([]byte(str), &js)

53-56: Use consistent JSON unmarshaling approach.

The IsJsonArray function uses json.Unmarshal directly, which is inconsistent with the pattern established in the codebase.

Apply this diff for consistency:

-	return json.Unmarshal([]byte(str), &js) == nil
+	return Unmarshal([]byte(str), &js) == nil
relay/gemini_handler.go (1)

226-230: Fix inconsistent variable naming.

Lines 226-230 still use the old openaiErr variable name instead of the standardized newAPIError used throughout the rest of the function.

Apply this diff for consistency:

-	usage, openaiErr := adaptor.DoResponse(c, resp.(*http.Response), relayInfo)
-	if openaiErr != nil {
-		service.ResetStatusCode(openaiErr, statusCodeMappingStr)
-		return openaiErr
+	usage, newAPIError := adaptor.DoResponse(c, resp.(*http.Response), relayInfo)
+	if newAPIError != nil {
+		service.ResetStatusCode(newAPIError, statusCodeMappingStr)
+		return newAPIError
controller/playground.go (2)

60-68: Remove commented code.

The token setup refactoring looks good, but please remove the commented line.

 userId := c.GetInt("id")
-//c.Set("token_name", "playground-"+group)
 tempToken := &model.Token{

68-73: Remove commented code.

The channel retrieval changes look correct, but please remove the commented line.

 _, err = getChannel(c, group, playgroundRequest.Model, 0)
 if err != nil {
     newAPIError = types.NewError(err, types.ErrorCodeGetChannelFailed)
     return
 }
-//middleware.SetupContextForSelectedChannel(c, channel, playgroundRequest.Model)
service/error.go (1)

30-55: Consider removing commented code instead of keeping it

Since this is a refactor to introduce the new standardized error handling, these commented-out wrapper functions should be removed entirely rather than kept as comments. This helps maintain code cleanliness.

-//// OpenAIErrorWrapper wraps an error into an OpenAIErrorWithStatusCode
-//func OpenAIErrorWrapper(err error, code string, statusCode int) *dto.OpenAIErrorWithStatusCode {
-//	text := err.Error()
-//	lowerText := strings.ToLower(text)
-//	if !strings.HasPrefix(lowerText, "get file base64 from url") && !strings.HasPrefix(lowerText, "mime type is not supported") {
-//		if strings.Contains(lowerText, "post") || strings.Contains(lowerText, "dial") || strings.Contains(lowerText, "http") {
-//			common.SysLog(fmt.Sprintf("error: %s", text))
-//			text = "请求上游地址失败"
-//		}
-//	}
-//	openAIError := dto.OpenAIError{
-//		Message: text,
-//		Type:    "new_api_error",
-//		Code:    code,
-//	}
-//	return &dto.OpenAIErrorWithStatusCode{
-//		Error:      openAIError,
-//		StatusCode: statusCode,
-//	}
-//}
-//
-//func OpenAIErrorWrapperLocal(err error, code string, statusCode int) *dto.OpenAIErrorWithStatusCode {
-//	openaiErr := OpenAIErrorWrapper(err, code, statusCode)
-//	openaiErr.LocalError = true
-//	return openaiErr
-//}
middleware/distributor.go (1)

270-283: Remove commented Authorization header code

The multi-key channel implementation looks good, storing the key in context instead of setting the Authorization header directly. However, line 279 contains commented code that should be removed.

-	// c.Request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))
 	common.SetContextKey(c, constant.ContextKeyChannelKey, key)
relay/channel/dify/relay-dify.go (1)

254-289: Error handling updated correctly, but write errors are no longer captured.

The error handling has been properly updated. However, the error from c.Writer.Write(jsonResponse) at line 287 is no longer captured.

Consider capturing and logging write errors:

-c.Writer.Write(jsonResponse)
+if _, err := c.Writer.Write(jsonResponse); err != nil {
+    common.SysError("error writing response: " + err.Error())
+}
relay/channel/gemini/adaptor.go (1)

242-245: Consider using common.Marshal for consistency.

The JSON marshaling at line 242 uses json.Marshal directly. According to the PR's standardization efforts, consider using common.Marshal instead for consistency with other parts of the codebase.

-	jsonResponse, jsonErr := json.Marshal(openAIResponse)
+	jsonResponse, jsonErr := common.Marshal(openAIResponse)
model/channel.go (1)

744-746: Side effect in GetSetting method

The GetSetting method modifies and saves the channel when encountering invalid JSON. While this auto-corrects invalid data, it's an unexpected side effect in a getter method. Consider logging this action for debugging purposes.

 if err != nil {
     common.SysError("failed to unmarshal setting: " + err.Error())
+    common.SysLog("Auto-clearing invalid setting for channel: " + channel.Name)
     channel.Setting = nil // 清空设置以避免后续错误
     _ = channel.Save()    // 保存修改
 }
controller/relay.go (1)

72-115: Comprehensive error handling update with proper retry logic.

The function correctly implements the new error handling pattern. The retry logic appropriately uses the new error type methods.

Consider removing the commented-out code at lines 106-109 if the 429 error handling logic has been moved elsewhere or is no longer needed:

-		//if newAPIError.StatusCode == http.StatusTooManyRequests {
-		//	common.LogError(c, fmt.Sprintf("origin 429 error: %s", newAPIError.Error()))
-		//	newAPIError.SetMessage("当前分组上游负载已饱和,请稍后再试")
-		//}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b83d47 and 50b76f4.

📒 Files selected for processing (96)
  • common/gin.go (1 hunks)
  • common/json.go (2 hunks)
  • common/str.go (1 hunks)
  • constant/context_key.go (1 hunks)
  • constant/multi_key_mode.go (1 hunks)
  • controller/channel-billing.go (1 hunks)
  • controller/channel-test.go (8 hunks)
  • controller/channel.go (3 hunks)
  • controller/playground.go (2 hunks)
  • controller/relay.go (13 hunks)
  • dto/claude.go (2 hunks)
  • dto/error.go (2 hunks)
  • dto/openai_request.go (1 hunks)
  • dto/openai_response.go (3 hunks)
  • dto/realtime.go (2 hunks)
  • middleware/auth.go (2 hunks)
  • middleware/distributor.go (4 hunks)
  • model/channel.go (5 hunks)
  • model/channel_cache.go (8 hunks)
  • model/log.go (1 hunks)
  • model/main.go (1 hunks)
  • model/user_cache.go (1 hunks)
  • relay/audio_handler.go (4 hunks)
  • relay/channel/adapter.go (2 hunks)
  • relay/channel/ali/adaptor.go (3 hunks)
  • relay/channel/ali/image.go (2 hunks)
  • relay/channel/ali/rerank.go (3 hunks)
  • relay/channel/ali/text.go (5 hunks)
  • relay/channel/aws/adaptor.go (2 hunks)
  • relay/channel/aws/relay-aws.go (5 hunks)
  • relay/channel/baidu/adaptor.go (2 hunks)
  • relay/channel/baidu/relay-baidu.go (2 hunks)
  • relay/channel/baidu_v2/adaptor.go (2 hunks)
  • relay/channel/claude/adaptor.go (2 hunks)
  • relay/channel/claude/relay-claude.go (7 hunks)
  • relay/channel/cloudflare/adaptor.go (2 hunks)
  • relay/channel/cloudflare/relay_cloudflare.go (5 hunks)
  • relay/channel/cohere/adaptor.go (2 hunks)
  • relay/channel/cohere/relay-cohere.go (6 hunks)
  • relay/channel/coze/adaptor.go (2 hunks)
  • relay/channel/coze/relay-coze.go (6 hunks)
  • relay/channel/deepseek/adaptor.go (2 hunks)
  • relay/channel/dify/adaptor.go (2 hunks)
  • relay/channel/dify/relay-dify.go (4 hunks)
  • relay/channel/gemini/adaptor.go (5 hunks)
  • relay/channel/gemini/relay-gemini-native.go (3 hunks)
  • relay/channel/gemini/relay-gemini.go (6 hunks)
  • relay/channel/jina/adaptor.go (2 hunks)
  • relay/channel/mistral/adaptor.go (2 hunks)
  • relay/channel/mokaai/adaptor.go (2 hunks)
  • relay/channel/mokaai/relay-mokaai.go (3 hunks)
  • relay/channel/ollama/adaptor.go (2 hunks)
  • relay/channel/ollama/relay-ollama.go (3 hunks)
  • relay/channel/openai/adaptor.go (2 hunks)
  • relay/channel/openai/relay-openai.go (10 hunks)
  • relay/channel/openai/relay_responses.go (3 hunks)
  • relay/channel/palm/adaptor.go (2 hunks)
  • relay/channel/palm/relay-palm.go (3 hunks)
  • relay/channel/perplexity/adaptor.go (2 hunks)
  • relay/channel/siliconflow/adaptor.go (2 hunks)
  • relay/channel/siliconflow/relay-siliconflow.go (2 hunks)
  • relay/channel/tencent/adaptor.go (3 hunks)
  • relay/channel/tencent/relay-tencent.go (3 hunks)
  • relay/channel/vertex/adaptor.go (2 hunks)
  • relay/channel/vertex/relay-vertex.go (1 hunks)
  • relay/channel/volcengine/adaptor.go (2 hunks)
  • relay/channel/xai/adaptor.go (2 hunks)
  • relay/channel/xai/text.go (3 hunks)
  • relay/channel/xunfei/adaptor.go (2 hunks)
  • relay/channel/xunfei/relay-xunfei.go (4 hunks)
  • relay/channel/zhipu/adaptor.go (2 hunks)
  • relay/channel/zhipu/relay-zhipu.go (3 hunks)
  • relay/channel/zhipu_4v/adaptor.go (2 hunks)
  • relay/claude_handler.go (4 hunks)
  • relay/common/relay_info.go (3 hunks)
  • relay/common_handler/rerank.go (3 hunks)
  • relay/embedding_handler.go (2 hunks)
  • relay/gemini_handler.go (7 hunks)
  • relay/helper/common.go (3 hunks)
  • relay/image_handler.go (5 hunks)
  • relay/relay-mj.go (1 hunks)
  • relay/relay-text.go (9 hunks)
  • relay/rerank_handler.go (2 hunks)
  • relay/responses_handler.go (6 hunks)
  • relay/websocket.go (3 hunks)
  • router/relay-router.go (1 hunks)
  • service/channel.go (5 hunks)
  • service/convert.go (1 hunks)
  • service/error.go (4 hunks)
  • service/midjourney.go (1 hunks)
  • types/channel_error.go (1 hunks)
  • types/error.go (1 hunks)
  • web/src/components/table/ChannelsTable.js (7 hunks)
  • web/src/helpers/api.js (1 hunks)
  • web/src/i18n/locales/en.json (2 hunks)
  • web/src/pages/Channel/EditChannel.js (9 hunks)
🧰 Additional context used
🧠 Learnings (28)
service/midjourney.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/helper/common.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/common/relay_info.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
controller/channel-billing.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/channel/coze/adaptor.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/image_handler.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/relay-mj.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/audio_handler.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/vertex/adaptor.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/ollama/relay-ollama.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
middleware/auth.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/gemini/relay-gemini-native.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/channel/cloudflare/relay_cloudflare.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/baidu/relay-baidu.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/claude_handler.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/gemini_handler.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/channel/palm/relay-palm.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/xunfei/relay-xunfei.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/channel/cohere/relay-cohere.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
constant/context_key.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/claude/relay-claude.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/tencent/adaptor.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/gemini/adaptor.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
relay/relay-text.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
middleware/distributor.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/tencent/relay-tencent.go (3)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
relay/channel/gemini/relay-gemini.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
controller/playground.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
🧬 Code Graph Analysis (37)
router/relay-router.go (2)
middleware/auth.go (1)
  • UserAuth (140-144)
middleware/distributor.go (1)
  • Distribute (28-130)
model/log.go (1)
common/str.go (1)
  • StrToMap (35-42)
dto/openai_request.go (1)
common/json.go (2)
  • Marshal (20-22)
  • Unmarshal (8-10)
dto/claude.go (1)
types/error.go (1)
  • ClaudeError (17-20)
service/midjourney.go (2)
common/gin.go (1)
  • GetContextKeyString (56-58)
constant/context_key.go (1)
  • ContextKeyChannelKey (32-32)
dto/error.go (1)
types/error.go (1)
  • OpenAIError (10-15)
relay/channel/vertex/relay-vertex.go (1)
common/str.go (2)
  • IsJsonObject (58-61)
  • StrToMap (35-42)
dto/openai_response.go (1)
types/error.go (1)
  • OpenAIError (10-15)
service/convert.go (1)
common/json.go (1)
  • Marshal (20-22)
relay/helper/common.go (3)
common/json.go (1)
  • Marshal (20-22)
types/error.go (1)
  • OpenAIError (10-15)
dto/error.go (1)
  • OpenAIError (5-10)
relay/channel/adapter.go (2)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/channel/aws/adaptor.go (3)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/common/relay_info.go (2)
common/gin.go (2)
  • GetContextKeyStringMap (72-74)
  • GetContextKeyString (56-58)
constant/context_key.go (3)
  • ContextKeyChannelParamOverride (26-26)
  • ContextKeyChannelBaseUrl (23-23)
  • ContextKeyChannelKey (32-32)
dto/realtime.go (1)
types/error.go (1)
  • OpenAIError (10-15)
relay/channel/dify/adaptor.go (3)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/channel/mokaai/adaptor.go (3)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/channel/zhipu/adaptor.go (3)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/channel/ali/adaptor.go (4)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/channel/openai/relay-openai.go (2)
  • OaiStreamHandler (109-183)
  • OpenaiHandler (185-241)
relay/common_handler/rerank.go (4)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
dto/openai_response.go (1)
  • Usage (173-186)
types/error.go (4)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeReadResponseBodyFailed (61-61)
  • ErrorCodeBadResponseBody (64-64)
common/json.go (1)
  • Unmarshal (8-10)
relay/relay-mj.go (1)
model/channel.go (1)
  • UpdateChannelStatus (504-569)
common/str.go (1)
common/json.go (1)
  • Unmarshal (8-10)
relay/websocket.go (4)
types/error.go (6)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeChannelModelMappedError (50-50)
  • ErrorCodeModelPriceError (41-41)
  • ErrorCodeInvalidApiType (42-42)
  • ErrorCodeDoRequestFailed (44-44)
relay/helper/model_mapped.go (1)
  • ModelMappedHelper (14-92)
relay/relay_adaptor.go (1)
  • GetAdaptor (38-98)
service/error.go (1)
  • ResetStatusCode (112-129)
relay/channel/vertex/adaptor.go (7)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
relay/channel/claude/relay-claude.go (2)
  • ClaudeStreamHandler (590-612)
  • ClaudeHandler (652-674)
relay/channel/gemini/relay-gemini-native.go (2)
  • GeminiTextGenerationStreamHandler (65-138)
  • GeminiTextGenerationHandler (17-63)
relay/channel/gemini/relay-gemini.go (2)
  • GeminiChatStreamHandler (797-864)
  • GeminiChatHandler (866-911)
relay/channel/openai/relay-openai.go (2)
  • OaiStreamHandler (109-183)
  • OpenaiHandler (185-241)
middleware/auth.go (2)
model/token.go (1)
  • Token (13-30)
model/user.go (1)
  • IsAdmin (512-523)
relay/channel/cohere/adaptor.go (3)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
model/channel_cache.go (3)
model/channel.go (3)
  • Channel (19-49)
  • ChannelInfo (51-57)
  • GetChannelById (300-315)
model/main.go (1)
  • DB (63-63)
common/constants.go (2)
  • ChannelStatusEnabled (192-192)
  • MemoryCacheEnabled (71-71)
relay/channel/mokaai/relay-mokaai.go (6)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
dto/openai_response.go (1)
  • Usage (173-186)
types/error.go (3)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeBadResponseBody (64-64)
dto/embedding.go (1)
  • EmbeddingResponse (52-57)
common/http.go (2)
  • CloseResponseBodyGracefully (12-20)
  • IOCopyBytesGracefully (22-57)
common/json.go (1)
  • Marshal (20-22)
relay/channel/openai/relay_responses.go (5)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
dto/openai_response.go (2)
  • Usage (173-186)
  • OpenAIResponsesResponse (202-225)
types/error.go (6)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeReadResponseBodyFailed (61-61)
  • ErrorCodeBadResponseBody (64-64)
  • WithOpenAIError (158-170)
  • ErrorCodeBadResponse (63-63)
common/http.go (1)
  • CloseResponseBodyGracefully (12-20)
common/json.go (1)
  • Unmarshal (8-10)
relay/channel/dify/relay-dify.go (5)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
dto/openai_response.go (1)
  • Usage (173-186)
types/error.go (3)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeBadResponseBody (64-64)
relay/channel/dify/dto.go (1)
  • DifyChatCompletionResponse (32-37)
common/http.go (1)
  • CloseResponseBodyGracefully (12-20)
service/channel.go (7)
types/channel_error.go (1)
  • ChannelError (3-10)
model/channel.go (1)
  • UpdateChannelStatus (504-569)
common/constants.go (4)
  • ChannelStatusAutoDisabled (194-194)
  • ChannelStatusEnabled (192-192)
  • AutomaticDisableChannelEnabled (101-101)
  • AutomaticEnableChannelEnabled (102-102)
service/user_notify.go (1)
  • NotifyRootUser (11-17)
types/error.go (3)
  • NewAPIError (75-81)
  • IsChannelError (182-187)
  • IsLocalError (189-195)
service/str.go (1)
  • AcSearch (81-101)
setting/operation_setting/operation_setting.go (1)
  • AutomaticDisableKeywords (8-16)
service/error.go (4)
types/error.go (4)
  • NewAPIError (75-81)
  • WithOpenAIError (158-170)
  • NewErrorWithStatusCode (148-156)
  • ErrorCodeBadResponseStatusCode (62-62)
common/http.go (1)
  • CloseResponseBodyGracefully (12-20)
dto/error.go (1)
  • GeneralErrorResponse (18-32)
common/json.go (1)
  • Unmarshal (8-10)
common/gin.go (1)
common/json.go (1)
  • Unmarshal (8-10)
relay/channel/tencent/adaptor.go (5)
common/gin.go (1)
  • GetContextKeyString (56-58)
constant/context_key.go (1)
  • ContextKeyChannelKey (32-32)
relay/channel/adapter.go (1)
  • Adaptor (13-29)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (1)
  • NewAPIError (75-81)
controller/channel.go (6)
constant/multi_key_mode.go (1)
  • MultiKeyMode (3-3)
model/channel.go (3)
  • Channel (19-49)
  • ChannelInfo (51-57)
  • GetChannelById (300-315)
common/json.go (2)
  • Unmarshal (8-10)
  • Marshal (20-22)
constant/channel.go (1)
  • ChannelTypeVertexAi (41-41)
common/str.go (1)
  • StrToMap (35-42)
common/utils.go (1)
  • GetTimestamp (192-194)
model/channel.go (9)
constant/multi_key_mode.go (3)
  • MultiKeyMode (3-3)
  • MultiKeyModeRandom (6-6)
  • MultiKeyModePolling (7-7)
common/json.go (2)
  • Marshal (20-22)
  • Unmarshal (8-10)
types/error.go (4)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeChannelNoAvailableKey (48-48)
  • ErrorCodeGetChannelFailed (45-45)
common/constants.go (4)
  • ChannelStatusEnabled (192-192)
  • DebugEnabled (70-70)
  • MemoryCacheEnabled (71-71)
  • ChannelStatusAutoDisabled (194-194)
model/channel_cache.go (3)
  • CacheGetChannelInfo (215-234)
  • CacheGetChannel (198-213)
  • CacheUpdateChannelStatus (236-245)
model/main.go (1)
  • DB (63-63)
common/utils.go (1)
  • GetTimestamp (192-194)
model/ability.go (1)
  • UpdateAbilityStatus (254-256)
common/logger.go (1)
  • SysError (55-58)
relay/channel/openai/relay-openai.go (7)
relay/common/relay_info.go (2)
  • RelayInfo (62-112)
  • RelayFormatClaude (38-38)
dto/openai_response.go (3)
  • Usage (173-186)
  • OpenAITextResponse (28-36)
  • SimpleResponse (8-11)
types/error.go (7)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeBadResponse (63-63)
  • ErrorCodeReadResponseBodyFailed (61-61)
  • ErrorCodeBadResponseBody (64-64)
  • WithOpenAIError (158-170)
  • ErrorCodeCountTokenFailed (40-40)
common/logger.go (1)
  • LogError (68-70)
common/http.go (2)
  • CloseResponseBodyGracefully (12-20)
  • IOCopyBytesGracefully (22-57)
common/json.go (2)
  • Unmarshal (8-10)
  • Marshal (20-22)
service/convert.go (1)
  • ResponseOpenAI2Claude (381-417)
relay/channel/ali/image.go (5)
relay/common/relay_info.go (1)
  • RelayInfo (62-112)
types/error.go (7)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeReadResponseBodyFailed (61-61)
  • ErrorCodeBadResponseBody (64-64)
  • ErrorCodeBadResponse (63-63)
  • WithOpenAIError (158-170)
  • OpenAIError (10-15)
dto/openai_response.go (1)
  • Usage (173-186)
relay/channel/ali/dto.go (1)
  • AliResponse (82-86)
common/http.go (1)
  • CloseResponseBodyGracefully (12-20)
🪛 Biome (1.9.4)
web/src/pages/Channel/EditChannel.js

[error] 503-505: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (181)
dto/openai_response.go (1)

3-6: LGTM! Good refactoring to centralize error types.

Moving the error types to a dedicated package improves code organization and ensures consistency across the codebase.

Also applies to: 34-34, 207-207

router/relay-router.go (1)

23-23: LGTM! Correct middleware ordering for playground routes.

Adding the Distribute() middleware after UserAuth() ensures proper authentication before channel distribution logic executes. This aligns well with the multi-key channel support feature.

service/convert.go (1)

166-167: LGTM! Consistent with JSON function standardization.

The change from EncodeJson to Marshal aligns with the codebase-wide standardization of JSON marshaling functions.

common/gin.go (1)

35-35: LGTM: Function rename aligns with JSON utility standardization.

The change from UnmarshalJson to Unmarshal is consistent with the function renaming in common/json.go and maintains the same functionality.

dto/realtime.go (2)

3-3: LGTM: Added types import for error standardization.

The import aligns with the unified error handling framework being introduced across the codebase.


30-30: LGTM: Error field standardized to use types package.

Changing from local *OpenAIError to *types.OpenAIError is consistent with the broader refactoring to unify error types across the system, as mentioned in the AI summary.

dto/claude.go (2)

6-6: LGTM: Added types import for error standardization.

The import supports the transition to unified error types across the codebase.


232-232: LGTM: Error field standardized to use types package.

Changing from local *ClaudeError to *types.ClaudeError aligns with the unified error handling framework and is consistent with similar changes in other DTO files.

common/json.go (2)

8-10: LGTM: Function rename improves naming consistency.

Renaming UnmarshalJson to Unmarshal aligns better with Go's standard naming conventions and improves consistency across the codebase.


20-22: LGTM: Function rename improves naming consistency.

Renaming EncodeJson to Marshal aligns with Go's standard JSON package naming conventions and maintains the same functionality.

model/user_cache.go (1)

38-38: LGTM! Standardized JSON handling.

The change from json.Unmarshal to common.Unmarshal aligns with the codebase-wide standardization of JSON processing functions. This ensures consistent error handling and behavior across the project.

dto/error.go (2)

3-3: LGTM! Added types package import for error standardization.

The import is necessary to use the centralized types.OpenAIError type in the GeneralErrorResponse struct.


19-23: LGTM! Standardized error type usage.

The change from local OpenAIError to types.OpenAIError aligns with the codebase-wide error handling standardization. The field alignment adjustments improve code readability without affecting functionality.

relay/channel/vertex/relay-vertex.go (1)

7-11: LGTM! Improved JSON parsing with proper error handling.

The changes enhance the function by:

  • Using IsJsonObject instead of IsJsonStr for more precise validation
  • Adding explicit error handling for StrToMap to prevent potential panics
  • Gracefully falling back to the original string if JSON parsing fails

This makes the code more robust and follows better error handling practices.

constant/multi_key_mode.go (1)

1-8: LGTM! Clean constant definitions for multi-key functionality.

The implementation properly defines a string alias type with well-named constants for multi-key modes. This provides a foundation for the multi-key channel support mentioned in the PR objectives.

service/midjourney.go (1)

207-207: Good refactoring to use standardized context key approach.

This change aligns with the multi-key channel support by retrieving the authorization token from context rather than directly from HTTP headers. This enables proper key rotation and selection in multi-key setups.

dto/openai_request.go (1)

68-69: Good standardization of JSON marshalling functions.

The change from common.EncodeJson/UnmarshalJson to common.Marshal/Unmarshal provides consistency across the codebase. The functionality remains equivalent as these are simple wrappers around the standard library functions.

relay/helper/common.go (3)

10-13: Good import organization and addition of types package.

The reordering of imports to group local packages before third-party packages improves readability. The addition of "one-api/types" supports the unified error handling approach.


90-90: Consistent JSON marshalling function usage.

The change to common.Marshal aligns with the codebase standardization of JSON functions, maintaining consistency with other similar changes across the project.


123-123: Good adoption of unified error type.

The parameter type change from dto.OpenAIError to types.OpenAIError aligns with the broader error handling unification mentioned in the PR objectives. This promotes consistency across the relay components.

relay/channel/cloudflare/adaptor.go (3)

13-13: Import addition supports unified error handling.

The addition of "one-api/types" import enables the use of the new standardized error types, supporting the error handling unification effort.


98-98: Good adoption of unified error type in method signature.

The return type change from *dto.OpenAIErrorWithStatusCode to *types.NewAPIError aligns with the broader error handling standardization across relay channel adaptors, promoting consistency and maintainability.


104-111: Consistent parameter ordering across handler calls.

The parameter order change from (c, resp, info) to (c, info, resp) standardizes the calling convention across relay channel adaptors, with info *relaycommon.RelayInfo consistently placed before resp *http.Response.

relay/channel/aws/adaptor.go (1)

11-11: LGTM: Import statement correctly added.

The import for the new error type is properly included.

relay/channel/mistral/adaptor.go (2)

11-11: LGTM: Import statement correctly added.

The import for the new error type is properly included.


73-80: LGTM: DoResponse method correctly updated.

The method signature, parameter ordering, and return value assignments are all correctly updated to use the new error type and consistent conventions.

relay/channel/baidu_v2/adaptor.go (2)

12-12: LGTM: Import statement correctly added.

The import for the new error type is properly included.


96-103: LGTM: DoResponse method correctly updated.

The method signature, parameter ordering, and return value assignments are all correctly updated to use the new error type and consistent conventions.

relay/channel/adapter.go (2)

8-8: LGTM: Import statement correctly added.

The import for the new error type is properly included.


25-25: LGTM: Interface method signature correctly updated.

The DoResponse method signature properly updates the error return type to *types.NewAPIError, establishing the correct contract for all adapter implementations.

relay/channel/xai/adaptor.go (2)

11-11: LGTM: Import statement correctly added.

The import for the new error type is properly included.


99-111: LGTM: DoResponse method correctly updated.

The method signature, parameter ordering, and return value assignments are all correctly updated across all handler call branches to use the new error type and consistent conventions.

relay/relay-mj.go (1)

578-578: LGTM: Consistent migration to multi-key channel status update.

The change from UpdateChannelStatusById to UpdateChannelStatus with an empty usingKey parameter aligns with the multi-key channel support refactoring. This maintains backward compatibility for non-multi-key channels while using the unified API.

relay/channel/mokaai/adaptor.go (2)

12-12: LGTM: Necessary import for new error type.

Adding the "one-api/types" import is required to support the new types.NewAPIError return type in the DoResponse method.


88-92: LGTM: Consistent error type and parameter order standardization.

The changes properly migrate from *dto.OpenAIErrorWithStatusCode to *types.NewAPIError and reorder parameters to pass info before resp for consistency across all channel adaptors.

relay/channel/claude/adaptor.go (2)

12-12: LGTM: Required import for error type migration.

The "one-api/types" import is properly added to support the new standardized error handling.


98-105: LGTM: Proper error type migration.

The method signature correctly updates to return *types.NewAPIError instead of *dto.OpenAIErrorWithStatusCode, maintaining consistency with the broader error handling refactor.

types/channel_error.go (2)

3-10: LGTM: Well-designed ChannelError struct for enhanced error handling.

The ChannelError struct properly encapsulates all necessary channel context including multi-key support (IsMultiKey, UsingKey) and auto-ban functionality. The JSON tags ensure proper serialization for API responses.


12-21: LGTM: Clean constructor function.

The NewChannelError constructor provides a clean way to instantiate the struct with all required fields, ensuring consistent initialization across the codebase.

relay/channel/dify/adaptor.go (2)

11-11: LGTM: Required import addition.

The "one-api/types" import is correctly added to support the new error type.


100-106: LGTM: Consistent error type and parameter standardization.

The changes properly:

  • Update the return type to *types.NewAPIError
  • Reorder parameters in handler calls to pass info before resp
  • Maintain the correct return order of (usage, err)

This follows the established pattern across all channel adaptors.

relay/channel/deepseek/adaptor.go (2)

13-13: LGTM: Import addition for new error type.

The import of "one-api/types" is correctly added to support the new standardized error handling.


85-89: LGTM: Consistent refactoring to standardized error handling.

The changes correctly implement the unified error handling pattern:

  • Return type changed to *types.NewAPIError
  • Parameter order standardized to (c, info, resp)
  • Return value assignments match the function signature (usage, err)
relay/channel/perplexity/adaptor.go (2)

12-12: LGTM: Import addition for new error type.

The import of "one-api/types" is correctly added to support the new standardized error handling.


77-81: LGTM: Consistent refactoring to standardized error handling.

The changes correctly implement the unified error handling pattern:

  • Return type changed to *types.NewAPIError
  • Parameter order standardized to (c, info, resp)
  • Return value assignments match the function signature (usage, err)
relay/channel/coze/adaptor.go (1)

12-12: LGTM: Import addition for new error type.

The import of "one-api/types" is correctly added to support the new standardized error handling.

relay/channel/zhipu_4v/adaptor.go (2)

13-13: LGTM: Import addition for new error type.

The import of "one-api/types" is correctly added to support the new standardized error handling.


84-88: LGTM: Consistent refactoring to standardized error handling.

The changes correctly implement the unified error handling pattern:

  • Return type changed to *types.NewAPIError
  • Parameter order standardized to (c, info, resp)
  • Return value assignments match the function signature (usage, err)
relay/channel/jina/adaptor.go (2)

14-14: LGTM: Import addition for new error type.

The import of "one-api/types" is correctly added to support the new standardized error handling.


77-83: LGTM: Consistent refactoring to standardized error handling.

The changes correctly implement the unified error handling pattern:

  • Return type changed to *types.NewAPIError
  • Parameter order standardized to (c, info, resp)
  • Return value assignments match the function signature (usage, err)
relay/channel/volcengine/adaptor.go (2)

16-16: LGTM: Import added for new error type.

The addition of the one-api/types import supports the new standardized error handling approach.


229-243: LGTM: DoResponse method updated to use standardized error handling.

The method signature change to return *types.NewAPIError and the parameter/return order standardization across all handler calls (putting info before resp and returning usage before err) aligns with the broader refactoring effort for consistency across relay channel adaptors.

relay/channel/palm/adaptor.go (2)

12-12: LGTM: Import added for new error type.

Consistent with the standardized error handling approach across all relay channel adaptors.


74-83: LGTM: DoResponse method standardized.

The method signature change to *types.NewAPIError and parameter reordering in the palmHandler call (putting info before resp) follows the established pattern for consistency across the codebase.

relay/common/relay_info.go (3)

216-216: LGTM: Context key updated for better organization.

The change from constant.ContextKeyParamOverride to constant.ContextKeyChannelParamOverride follows the new granular naming convention with the "ContextKeyChannel" prefix, improving context key organization.


232-232: LGTM: Context key updated for channel-specific base URL.

The change to constant.ContextKeyChannelBaseUrl aligns with the refactored context key naming scheme for better categorization of channel-related context values.


250-250: LGTM: API key retrieval simplified.

Getting the API key directly from context using constant.ContextKeyChannelKey instead of extracting from the Authorization header is cleaner and more consistent with the new context key management approach.

relay/channel/siliconflow/adaptor.go (2)

13-13: LGTM: Import added for standardized error handling.

Consistent addition of the one-api/types import to support the new error type across all relay channel adaptors.


80-96: LGTM: DoResponse method standardized across all relay modes.

The method signature change to return *types.NewAPIError and the consistent parameter reordering in all handler calls (siliconflowRerankHandler, openai.OaiStreamHandler, openai.OpenaiHandler) demonstrates proper adherence to the standardization effort across different relay modes.

relay/channel/zhipu/adaptor.go (2)

11-11: LGTM: Import added for new error type.

Completes the consistent addition of the one-api/types import across all relay channel adaptors.


81-88: LGTM: DoResponse method standardized for both stream and non-stream modes.

The method signature change to *types.NewAPIError and parameter reordering in both zhipuStreamHandler and zhipuHandler calls (putting info before resp) completes the consistent standardization across all relay channel adaptors.

relay/channel/xunfei/adaptor.go (1)

10-10: LGTM! Consistent error handling refactor implementation.

The changes properly implement the standardized error handling approach:

  • Import updated to use "one-api/types" package
  • Method signature correctly returns *types.NewAPIError
  • Error construction uses types.NewError with appropriate error codes (ErrorCodeChannelInvalidKey, ErrorCodeInvalidRequest)
  • Handler function calls maintain correct parameter order and return value assignment

The refactor maintains existing functionality while improving error handling consistency.

Also applies to: 77-91

relay/channel/ollama/adaptor.go (1)

12-12: LGTM! Correct implementation of the error handling refactor.

The changes properly implement the standardized error handling approach:

  • Import correctly added for "one-api/types" package
  • Method signature properly returns (usage any, err *types.NewAPIError)
  • All handler calls consistently use the correct parameter order (c, info, resp) and return value assignment usage, err = ...

This file demonstrates the correct pattern that should be followed across all adaptor implementations.

Also applies to: 78-89

relay/channel/cohere/adaptor.go (2)

12-12: LGTM: Import added for new error handling system.

The addition of the types package import is necessary for the new standardized error handling.


75-85: LGTM: Function signature and parameter order standardized correctly.

The changes properly implement the standardized approach:

  • Return type changed from *dto.OpenAIErrorWithStatusCode to *types.NewAPIError
  • Parameter order standardized to place info before resp in handler calls
  • Both streaming and non-streaming code paths updated consistently

This aligns with the Adaptor interface definition and the broader refactor described in the summary.

relay/common_handler/rerank.go (5)

11-13: LGTM: Import updates for standardized error handling.

The addition of the types package import and reordering of imports aligns with the new error handling system.


16-16: LGTM: Function signature standardized correctly.

The return type change to (*dto.Usage, *types.NewAPIError) follows the new pattern of returning usage first and the standardized error type second.


19-19: LGTM: Error handling standardized with specific error codes.

The migration from generic error wrappers to types.NewError with specific error codes (ErrorCodeReadResponseBodyFailed, ErrorCodeBadResponseBody) provides better error categorization and handling.

Also applies to: 30-30, 65-65


28-28: LGTM: JSON operations standardized.

The change from common.UnmarshalJson to common.Unmarshal follows the standardization of JSON operations across the codebase.

Also applies to: 63-63


72-72: LGTM: Return value order corrected.

Returning usage first (&jinaResp.Usage) and error second (nil) aligns with the new function signature and standardized return pattern.

relay/responses_handler.go (4)

17-17: LGTM: Import added for new error handling system.

The addition of the types package import enables the new standardized error handling.


50-50: LGTM: Function signature updated for standardized error handling.

The return type change to *types.NewAPIError aligns with the broader refactor to standardize error handling across relay handlers.


54-54: LGTM: Comprehensive error handling migration with specific error codes.

All error handling has been consistently migrated to use types.NewError with appropriate error codes:

  • ErrorCodeInvalidRequest for validation failures
  • ErrorCodeSensitiveWordsDetected for content filtering
  • ErrorCodeChannelModelMappedError for model mapping issues
  • ErrorCodeModelPriceError for pricing issues
  • And other specific codes for different failure scenarios

This provides much better error categorization and handling compared to generic error wrappers.

Also applies to: 63-63, 69-69, 82-82, 96-96, 103-103, 109-109, 113-113, 120-120, 127-127, 140-140


85-87: LGTM: Variable naming and error handling updated consistently.

The variable renaming from openaiErr to newAPIError and the consistent handling of the new error type throughout the function (including deferred quota return logic) maintains code clarity and correctness.

Also applies to: 90-92, 149-152, 157-160

web/src/i18n/locales/en.json (2)

1145-1145: LGTM: Minor improvement to organization field translation.

The change from "组织,不填则为默认组织" to "Organization, default if empty" is more concise and clear.


1760-1768: LGTM: Comprehensive localization for multi-key channel features.

The new translation entries provide complete English localization for the multi-key functionality:

  • "密钥聚合模式": "Key aggregation mode" - Clear and accurate
  • "随机": "Random" and "轮询": "Polling" - Correct aggregation mode translations
  • File upload and deployment region instructions are well-translated and informative

These translations align with the multi-key channel support mentioned in the PR objectives and AI summary.

relay/channel/mokaai/relay-mokaai.go (1)

53-82: LGTM! Excellent refactoring to standardize error handling.

The function has been successfully updated to align with the new unified error handling pattern:

  • Function signature properly updated with info *relaycommon.RelayInfo parameter
  • Return type correctly changed to (*dto.Usage, *types.NewAPIError)
  • Error handling consistently uses types.NewError with appropriate error codes
  • JSON marshaling updated to use common.Marshal wrapper
  • Response writing improved with common.IOCopyBytesGracefully

All changes maintain the original logic while improving consistency across the codebase.

relay/audio_handler.go (1)

59-134: LGTM! Comprehensive and consistent error handling refactoring.

The AudioHelper function has been successfully updated to use the new unified error handling:

  • Function signature correctly updated to return *types.NewAPIError
  • All error returns consistently use types.NewError with appropriate error codes
  • Variable naming standardized from openaiErr to newAPIError
  • Business logic remains intact while improving error consistency

The refactoring maintains all existing functionality while providing better error standardization across the relay system.

common/str.go (1)

35-42: LGTM! Good improvement to error handling.

The StrToMap function properly returns errors and uses the standardized common.Unmarshal wrapper function, improving error handling consistency.

relay/gemini_handler.go (1)

108-178: LGTM! Excellent standardization of error handling.

The GeminiHelper function has been successfully refactored to use the new unified error handling:

  • Function signature correctly updated to return *types.NewAPIError
  • Error returns consistently use types.NewError with appropriate error codes
  • Variable naming properly standardized to newAPIError
  • All business logic preserved while improving error consistency

This aligns well with the broader system-wide error handling standardization.

relay/channel/ali/rerank.go (1)

34-74: LGTM! Excellent refactoring to standardize error handling.

The RerankHandler function has been successfully updated to align with the new unified error handling pattern:

  • Function signature properly updated with parameter reordering and new return type
  • Error handling consistently uses types.NewError and types.WithOpenAIError with appropriate error codes
  • Proper error differentiation between system errors and API errors
  • Response writing simplified while maintaining functionality

The refactoring maintains all original functionality while improving consistency with the broader codebase standardization.

relay/image_handler.go (1)

111-244: LGTM! Consistent error handling refactoring.

The function has been correctly updated to use the new standardized types.NewAPIError error handling approach. All error returns use appropriate error codes, variable names have been updated consistently, and the deferred quota return logic properly checks the new error variable.

relay/channel/siliconflow/relay-siliconflow.go (1)

15-44: LGTM! Function signature and error handling correctly updated.

The function has been properly updated to align with the new standardized error handling pattern:

  • Function signature updated to accept info parameter and return (*dto.Usage, *types.NewAPIError)
  • Error handling migrated to use types.NewError with appropriate error codes
  • Response writing updated to use common.IOCopyBytesGracefully for better error handling

Note: The info parameter is not used in the function body, which is acceptable if it's part of interface standardization.

relay/websocket.go (1)

15-76: LGTM! WebSocket handler correctly updated to new error type.

The function has been systematically updated to use the new types.NewAPIError error handling:

  • Function signature correctly changed to return the new error type
  • All error creation calls updated to use types.NewError with appropriate error codes
  • Variable naming updated consistently throughout
  • Deferred quota return logic properly checks the new error variable
  • Status code mapping functionality preserved
relay/embedding_handler.go (1)

37-116: LGTM! Embedding handler successfully migrated to new error handling.

The function has been correctly refactored to use the standardized types.NewAPIError approach:

  • Function signature properly updated
  • All error conditions use appropriate error codes from the types package
  • Variable naming consistently updated throughout
  • Deferred quota handling correctly checks the new error variable
  • Core embedding processing logic preserved
relay/channel/ali/image.go (1)

129-171: LGTM! Ali image handler correctly updated with proper error conversion.

The function has been properly migrated to the new error handling system:

  • Function signature updated to return (*types.NewAPIError, *dto.Usage)
  • Appropriate use of types.NewError for general errors and types.WithOpenAIError for OpenAI-compatible error conversion
  • Error codes are appropriate for each error condition
  • Final return now provides a non-nil usage pointer for consistency

The use of types.WithOpenAIError for the Ali-specific task status error (lines 154-159) correctly converts Ali error format to OpenAI-compatible format.

relay/channel/coze/relay-coze.go (3)

15-15: LGTM: Import addition for new error framework

The addition of the types package import supports the new standardized error handling.


47-47: LGTM: Function signature standardization

The parameter reordering (placing info before resp) and return type changes to use *types.NewAPIError align with the broader refactoring to standardize relay handler interfaces.

Also applies to: 98-98


50-50: LGTM: Consistent error handling conversion

The conversion from service.OpenAIErrorWrapper to types.NewError with appropriate error codes (ErrorCodeBadResponseBody) maintains the existing error handling logic while adopting the new standardized error framework.

Also applies to: 59-59, 62-62, 89-89, 139-139

relay/channel/ollama/relay-ollama.go (2)

87-87: LGTM: Improved function signature

The updated signature accepting a single info *relaycommon.RelayInfo parameter instead of multiple discrete parameters improves consistency and makes the context information more cohesive.


108-111: LGTM: Proper usage of info struct fields

The updated code correctly uses info.PromptTokens and info.UpstreamModelName instead of the previous discrete parameters, maintaining consistency with the new signature.

Also applies to: 115-115

middleware/auth.go (2)

237-243: LGTM: Improved error handling and modularity

The refactoring to use SetupContextForToken helper function improves modularity and makes the context setup logic more testable. The error handling is also more explicit.


245-274: LGTM: Well-structured helper function

The SetupContextForToken helper function properly encapsulates the context setup logic with appropriate error handling. The admin privilege checking for specific channel IDs (lines 266-272) correctly uses model.IsAdmin and provides proper error responses.

relay/rerank_handler.go (3)

26-26: LGTM: Function signature update

The updated function signature to return *types.NewAPIError aligns with the new standardized error handling framework.


32-32: LGTM: Comprehensive error handling conversion

All error returns have been consistently updated to use types.NewError with appropriate error codes (e.g., ErrorCodeInvalidRequest, ErrorCodeChannelModelMappedError, ErrorCodeModelPriceError). This maintains the existing error handling logic while adopting the standardized error framework.

Also applies to: 38-38, 41-41, 46-46, 54-54, 69-69, 75-75, 79-79, 87-87


77-77: LGTM: JSON processing standardization

The switch to common.Marshal for JSON processing is consistent with the broader standardization effort across relay handlers.

relay/channel/gemini/relay-gemini-native.go (3)

17-17: LGTM: Consistent function signature updates

The parameter reordering (placing info before resp) and return type changes to use *types.NewAPIError maintain consistency with the broader relay handler refactoring.

Also applies to: 65-65


23-23: LGTM: Error handling standardization

The conversion to types.NewError with ErrorCodeBadResponseBody maintains the existing error handling logic while adopting the new standardized error framework.

Also applies to: 34-34, 57-57


32-32: LGTM: JSON processing consistency

The updates to use common.Unmarshal and common.Marshal align with the standardization of JSON processing across relay handlers.

Also applies to: 55-55

relay/claude_handler.go (5)

15-15: LGTM: Import reorganization follows consistent pattern.

The addition of the types package import aligns with the error handling refactoring across the codebase.


36-36: LGTM: Function signature updated consistently.

The return type change from error to *types.NewAPIError is consistent with the broader refactoring pattern across relay handlers.


43-43: LGTM: Error creation migrated correctly.

All error creation calls have been properly migrated to use types.NewError with appropriate error codes that clearly indicate the failure context.

Also applies to: 52-52, 58-58, 63-63


67-71: LGTM: Error variable handling updated correctly.

The variable name change to newAPIError and the conditional check in the defer function are properly updated to work with the new error type.


115-115: LGTM: JSON marshaling updated to use common utility.

The change from json.Marshal to common.Marshal follows the pattern of using common utilities for consistent JSON handling.

relay/channel/cloudflare/relay_cloudflare.go (6)

13-13: LGTM: Import reorganization follows consistent pattern.

The addition of types package import and moving gin to the bottom aligns with the standardized import organization across the codebase.

Also applies to: 17-17


30-30: LGTM: Function signature standardized correctly.

The parameter reordering to place info *relaycommon.RelayInfo before resp *http.Response and the return type change to *types.NewAPIError are consistent with the broader refactoring pattern.


91-91: LGTM: Function signature updated consistently.

The cfHandler function signature follows the same standardization pattern as cfStreamHandler.


94-94: LGTM: Error handling migrated properly.

All error returns in cfHandler have been correctly migrated to use types.NewError with appropriate error codes.

Also applies to: 100-100, 112-112


120-120: LGTM: Function signature updated consistently.

The cfSTTHandler function signature follows the same standardization pattern.


124-124: LGTM: Error handling migrated properly.

All error returns in cfSTTHandler have been correctly migrated to use types.NewError with the appropriate ErrorCodeBadResponseBody error code.

Also applies to: 129-129, 138-138

constant/context_key.go (1)

20-32: LGTM: Context key expansion supports multi-key channels.

The comprehensive set of channel-related context keys provides good support for the multi-key channel functionality. The naming convention is consistent and descriptive.

relay/channel/zhipu/relay-zhipu.go (5)

11-11: LGTM: Import reorganization follows consistent pattern.

The addition of relaycommon and types imports, and the reorganization of third-party imports at the bottom are consistent with the broader refactoring.

Also applies to: 13-13, 18-19


155-155: LGTM: Function signature standardized correctly.

The addition of info *relaycommon.RelayInfo parameter and the return type change to return usage before error are consistent with the standardization pattern.


219-219: LGTM: Function signature updated consistently.

The zhipuHandler function signature follows the same standardization pattern as zhipuStreamHandler.


223-223: LGTM: Error handling migrated properly.

All error returns have been correctly migrated to use types.NewError with appropriate error codes.

Also applies to: 228-228, 239-239


231-234: LGTM: OpenAI error wrapping updated correctly.

The migration from service.OpenAIErrorWrapper to types.WithOpenAIError correctly preserves the error structure while using the new error type.

relay/relay-text.go (7)

22-22: LGTM: Import addition supports error handling refactoring.

The addition of the types package import is necessary for the new error handling implementation.


88-88: LGTM: Function signature updated consistently.

The return type change to *types.NewAPIError is consistent with the broader refactoring pattern across relay handlers.


96-96: LGTM: Error creation migrated correctly.

All error creation calls have been properly migrated to use types.NewError with appropriate error codes that clearly indicate the failure context.

Also applies to: 107-107, 113-113, 125-125, 132-132


136-139: LGTM: Error variable handling updated correctly.

The variable name change to newApiErr and proper propagation of the new error type are correctly implemented.


193-193: LGTM: JSON utilities updated consistently.

The change to use common.Unmarshal and common.Marshal follows the pattern of using common utilities for consistent JSON handling across the codebase.

Also applies to: 197-197


281-281: LGTM: Function signature updated consistently.

The preConsumeQuota function signature change to return *types.NewAPIError is consistent with the broader refactoring pattern.


284-284: LGTM: Error handling migrated properly.

All error returns in preConsumeQuota have been correctly migrated to use types.NewError or types.NewErrorWithStatusCode with appropriate error codes and HTTP status codes where needed.

Also applies to: 287-287, 290-290, 314-314, 318-318

controller/playground.go (2)

12-12: LGTM!

The import addition and error type change are consistent with the project-wide error handling refactoring.

Also applies to: 19-19


21-27: LGTM!

The deferred error response correctly uses the new error type's conversion method.

relay/channel/tencent/adaptor.go (3)

9-10: LGTM!

Import changes align with the error handling refactoring and context key usage.

Also applies to: 13-13


67-68: LGTM!

API key extraction from context supports the multi-key channel feature and improves security by avoiding direct header access.


98-105: LGTM!

DoResponse signature and implementation correctly updated to match the new error type and handler parameter order.

relay/channel/xai/text.go (1)

13-13: LGTM!

All changes correctly implement the standardized error handling, parameter ordering, and JSON processing methods.

Also applies to: 38-38, 50-50, 81-81, 86-89, 94-97, 78-78, 101-101

model/channel_cache.go (2)

17-18: LGTM!

The refactoring to store channel IDs instead of pointers improves memory efficiency and supports the cache update functionality.

Also applies to: 25-30, 37-52


215-234: LGTM!

The new CacheGetChannelInfo function properly handles both cache-enabled and disabled scenarios with appropriate status checks.

relay/channel/openai/relay_responses.go (1)

12-12: LGTM!

All changes correctly implement the standardized error handling, parameter ordering, and return value conventions. The use of types.WithOpenAIError for OpenAI-specific errors is appropriate.

Also applies to: 18-18, 25-25, 27-32, 47-47, 50-50, 53-53, 96-96

relay/channel/openai/adaptor.go (1)

25-25: LGTM! Consistent error handling refactor

The changes properly implement the new standardized error handling using *types.NewAPIError and maintain consistency in:

  • Parameter ordering: (c, info, resp)
  • Return value ordering: (usage, err)

This aligns well with the PR's objective of introducing standardized API error handling.

Also applies to: 425-452

service/error.go (1)

82-110: Well-implemented error handler migration

The RelayErrorHandler has been properly updated to use the new error type with appropriate error construction using types.WithOpenAIError for OpenAI-format errors and types.NewErrorWithStatusCode for general errors.

middleware/distributor.go (1)

242-249: Good implementation of group-based routing support

The addition properly handles the /pg/chat/completions endpoint by extracting the Group field from the request and storing it in the context for downstream processing.

relay/channel/xunfei/relay-xunfei.go (1)

129-156: Consistent error handling implementation

The Xunfei handlers have been properly updated to follow the standardized pattern:

  • Return order changed to (usage, error)
  • Error type changed to *types.NewAPIError
  • Appropriate error codes used (ErrorCodeDoRequestFailed, ErrorCodeBadResponseBody)

Also applies to: 159-198

relay/channel/ali/text.go (2)

61-61: Note: Write error checks removed

The error checks for c.Writer.Write have been removed (lines 61 and 204). This appears to be intentional and consistent with other handlers in the codebase, likely because write errors to the response writer are difficult to handle meaningfully at this point.

Also applies to: 204-204


189-196: Proper error type conversion

Good implementation of converting Ali-specific errors to the standardized OpenAI error format using types.WithOpenAIError.

relay/channel/baidu/relay-baidu.go (4)

12-12: LGTM! Import reorganization looks good.

The import statements have been properly reorganized and the new types package import aligns with the unified error handling approach.

Also applies to: 15-15, 19-19


115-138: Good refactoring of the streaming handler.

The streaming logic has been simplified by using helper.StreamScannerHandler, which provides better abstraction and reduces code duplication. The usage tracking within the callback is properly implemented.


140-163: Consistent error handling implementation.

The error handling has been properly updated to use the new types.NewAPIError type with appropriate error codes. The response processing logic remains intact.


165-188: Error handling properly standardized.

The embedding handler follows the same error handling pattern as other handlers, ensuring consistency across the codebase.

relay/channel/dify/relay-dify.go (1)

17-17: Import addition aligns with error handling refactor.

relay/channel/aws/relay-aws.go (4)

11-12: Import organization improves code clarity.

Good use of type aliasing for AWS SDK types and proper import organization.

Also applies to: 15-17, 21-21


71-77: Good simplification of the model ID lookup.

Removing the unnecessary error return makes the function cleaner and more straightforward.


79-128: Improved error handling with proper error propagation.

The handler now properly captures and returns errors from claude.HandleClaudeResponseData, which is an improvement over the previous implementation.


130-196: Clear error handling for streaming responses.

The use of type aliasing and specific error messages for unknown response types improves debugging capabilities.

web/src/components/table/ChannelsTable.js (5)

45-45: Icon imports support multi-key visualization.

Also applies to: 51-51


58-95: Good visual distinction for multi-key channel modes.

The implementation provides clear visual feedback for different multi-key aggregation modes (random vs polling).


110-150: Verify the enabled key count calculation logic.

The calculation enabledKeySize = keySize - Object.keys(channelInfo.multi_key_status_list).length assumes that multi_key_status_list only contains disabled keys.

Please confirm that multi_key_status_list is indeed a map containing only disabled keys, as this affects the accuracy of the enabled count display.


151-179: Clear multi-key status display implementation.

The function provides good visibility into the health of multi-key channels by showing the enabled/total key ratio.


1071-1075: Verify backend handling of enable_all action

I ran a search for the Go handler responsible for the PUT /api/channel/ endpoint but didn’t locate any matching code. We should confirm that the backend correctly interprets an empty multi_key_status_list as “enable all”:

  • Verify the Go handler for /api/channel/ updates channel_info.multi_key_status_list
  • Ensure that sending an empty object clears disabled keys and enables all keys as intended
relay/channel/palm/relay-palm.go (2)

10-10: Import changes align with the refactoring pattern.

Also applies to: 13-13, 15-15


127-162: Proper error handling and response processing.

The handler correctly uses the new error types and response utilities. The usage calculation is properly implemented.

relay/channel/gemini/adaptor.go (2)

15-15: LGTM!

The import addition aligns with the new standardized error handling approach.


171-209: Correct implementation of standardized error handling.

The changes properly implement the new error handling pattern with:

  • Return value order following Go conventions (value first, error second)
  • Consistent parameter ordering (info before resp)
  • Appropriate error code usage
controller/channel-test.go (1)

396-418: Well-implemented error handling with new error types.

The error handling properly utilizes the new error type system with appropriate checks for disabling/enabling channels and comprehensive error information.

controller/channel.go (3)

389-419: Well-implemented Vertex AI key parsing.

The function properly handles JSON array parsing with support for both string and object key formats, includes appropriate error handling, and provides clear error messages.


459-483: Robust validation for Vertex AI configuration.

The validation ensures proper JSON format and requires a "default" region, which is essential for Vertex AI channel functionality.


769-781: Correct handling of multi-key mode updates.

The logic properly preserves existing channel info while updating only the multi-key mode when specified.

relay/channel/tencent/relay-tencent.go (2)

92-133: Correct implementation with proper return value order.

The function correctly returns (usage, error) which is consistent with the Gemini adaptor and follows Go conventions.


135-161: Well-implemented handler with correct error handling.

The function properly implements the new error handling pattern with correct return value order and uses appropriate utility functions.

relay/channel/claude/relay-claude.go (1)

521-530: Well-executed error handling refactor

The migration from dto.OpenAIErrorWithStatusCode to types.NewAPIError is consistently implemented across all handler functions. The use of appropriate error codes like types.ErrorCodeBadResponseBody improves error categorization.

Also applies to: 590-612, 614-622, 652-674

service/channel.go (2)

20-28: Proper multi-key channel support implementation

The DisableChannel and EnableChannel functions have been correctly updated to support multi-key channels by accepting usingKey parameter and using structured ChannelError type. This aligns well with the multi-key channel architecture.

Also applies to: 29-36


38-88: Clean error type migration and keyword matching

The error checking functions properly utilize the new types.NewAPIError type with helper functions like IsChannelError and IsLocalError. The use of AcSearch for automatic disable keywords provides efficient pattern matching.

Also applies to: 90-101

relay/channel/gemini/relay-gemini.go (2)

797-797: Consistent parameter reordering across handlers

All handler functions have been updated with consistent parameter ordering (info before resp) and return value ordering (usage before error). This improves API consistency across the relay channel implementations.

Also applies to: 866-866, 913-913


129-130: Proper JSON operation standardization

The migration from UnmarshalJson/EncodeJson to Unmarshal/Marshal is consistently applied throughout the file. Error handling properly uses types.NewError with appropriate error codes.

Also applies to: 616-619, 868-882, 917-924, 951-954

model/channel.go (3)

51-68: Well-designed multi-key channel data structure

The ChannelInfo struct properly encapsulates multi-key channel functionality with support for different aggregation modes (random/polling). The Value/Scan methods correctly implement database serialization.


79-160: Excellent thread-safe multi-key implementation

The GetNextEnabledKey method properly implements both random and polling key selection modes with thread-safe per-channel locks. The lock management through getChannelPollingLock prevents race conditions in polling mode. The CleanupChannelPollingLocks function helps prevent memory leaks.

Also applies to: 441-472


301-315: Fixed pointer handling in GetChannelById

The function now correctly creates a pointer to Channel and properly checks for nil before returning errors. This prevents potential nil pointer dereferences.

web/src/pages/Channel/EditChannel.js (3)

401-432: Robust Vertex AI file upload implementation

The handleVertexUploadChange function properly handles asynchronous file parsing with good error handling. The use of vertexErroredNames ref to avoid duplicate error messages is a thoughtful UX improvement.


740-765: Comprehensive multi-key aggregation mode UI

The multi-key mode selection UI is well-implemented with:

  • Clear mode options (random vs polling)
  • Important warning about Redis/memory cache requirement for polling mode
  • Proper state management and form integration

497-513: Proper mode handling in form submission

The submit logic correctly determines the submission mode based on batch and multiToSingle states, and includes the multi_key_mode parameter when applicable. The API structure properly separates mode from channel data.

relay/channel/openai/relay-openai.go (4)

109-183: LGTM! Return value order follows Go conventions.

The changes correctly standardize the return value order to (usage, error) following Go idiomatic conventions, and properly integrate the new error handling with types.NewAPIError.


185-241: Parameter reordering and error handling updates look good.

The function correctly implements:

  • Standardized parameter order (info before resp)
  • Unified error handling with types.NewAPIError
  • Consistent JSON processing with common.Marshal/common.Unmarshal
  • Idiomatic return order (usage, error)

243-264: Appropriate removal of error return for TTS handler.

The simplified return signature correctly reflects that errors cannot be meaningfully propagated after response headers are written. The comprehensive comment explains the rationale well.


555-587: Consistent implementation of standardized patterns.

The function correctly implements all the refactoring patterns:

  • Parameter order (info before resp)
  • Return order (usage, error)
  • Error handling with types.NewAPIError
  • JSON processing with common.Unmarshal
controller/relay.go (4)

27-70: Error handling refactoring looks correct.

The function properly adapts to the new types.NewAPIError type, correctly accessing error fields and methods for logging.


274-318: Retry logic correctly adapted to new error types.

The function properly uses types.IsChannelError and types.IsLocalError for error classification, maintaining the original retry logic while working with the new error system.


320-327: Improved channel error processing with structured data.

Good improvement passing channel information as a structured type rather than relying on context extraction, which addresses the concurrency concern mentioned in the comment.


246-272: Caching behavior unaffected by passing context to CacheGetRandomSatisfiedChannel

Verified that CacheGetRandomSatisfiedChannel is defined as

func CacheGetRandomSatisfiedChannel(c *gin.Context, group string, model string, retry int) (*Channel, string, error)

and is called the same way in both middleware/distributor.go and controller/relay.go. No unintended side effects on caching logic were introduced.

Comment thread controller/channel-billing.go Outdated
Comment thread web/src/helpers/api.js
Comment on lines +85 to 87
group: inputs.group,
messages: processedMessages,
group: inputs.group,

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

Remove duplicate property.

There are two identical group: inputs.group properties in the payload object. The duplicate should be removed as it's unnecessary and reduces code quality.

Apply this diff to remove the duplicate:

   const payload = {
     model: inputs.model,
-    group: inputs.group,
     messages: processedMessages,
     group: inputs.group, 
     stream: inputs.stream,
   };
📝 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
group: inputs.group,
messages: processedMessages,
group: inputs.group,
const payload = {
model: inputs.model,
messages: processedMessages,
group: inputs.group,
stream: inputs.stream,
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 86-87: This property value named group is later overwritten by an object member with the same name.

Overwritten with this value.

If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored.
Unsafe fix: Remove this property value named group

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
In web/src/helpers/api.js around lines 85 to 87, there is a duplicate property
`group: inputs.group` in the object. Remove the redundant duplicate so that
`group: inputs.group` appears only once in the object to clean up the code and
avoid confusion.

Comment thread relay/channel/coze/adaptor.go
Comment thread relay/channel/ollama/relay-ollama.go
Comment thread constant/context_key.go
Comment thread relay/channel/cohere/relay-cohere.go Outdated
Comment thread relay/channel/cohere/relay-cohere.go Outdated
Comment thread relay/channel/cohere/relay-cohere.go Outdated
return
}
channel, err := model.GetChannelById(channelId, true)
channel, err := model.CacheGetChannel(channelId)

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.

💡 Verification agent

🧩 Analysis chain

Verify cache consistency for channel retrieval.

The change from model.GetChannelById to model.CacheGetChannel improves performance but requires ensuring the cache is properly maintained when channels are updated or deleted.


🏁 Script executed:

#!/bin/bash
# Description: Verify that channel cache is properly updated on channel modifications

# Check for cache update calls in channel modification functions
echo "Checking for cache updates in channel operations:"
rg -A 5 "UpdateChannel|DeleteChannel|AddChannel" model/channel.go | rg -B 5 -A 5 "cache|Cache"

# Check cache implementation
echo -e "\nChecking cache implementation:"
ast-grep --pattern 'func CacheGetChannel($$$) {
  $$$
}'

Length of output: 1131


Ensure complete cache maintenance for all channel operations

The switch to CacheGetChannel boosts performance but risks stale data unless the cache is kept in sync.
Please update or invalidate the cache in every channel-modifying function:

• In model/channel.go, after creating a channel (e.g. CreateChannel/AddChannel), call the appropriate cache‐set function.
• After deleting channels (e.g. in your DeleteChannel logic), invalidate or remove them from the cache.
• In update paths beyond status changes (the commented // CacheUpdateChannel(channel)), either uncomment and use the cache‐update call or replace with a proper invalidation/update.

Adding or refactoring these cache hooks will ensure CacheGetChannel always returns fresh data.

🤖 Prompt for AI Agents
In controller/channel-test.go at line 315 and related channel-modifying
functions in model/channel.go, ensure cache consistency by updating or
invalidating the cache after any channel changes. Specifically, after creating a
channel, call the cache-set function to add it to the cache; after deleting a
channel, remove or invalidate it from the cache; and for updates beyond status
changes, uncomment or implement cache update calls to keep cached data fresh and
synchronized with the database.

func HandleStreamResponseData(c *gin.Context, info *relaycommon.RelayInfo, claudeInfo *ClaudeResponseInfo, data string, requestMode int) *dto.OpenAIErrorWithStatusCode {
func HandleStreamResponseData(c *gin.Context, info *relaycommon.RelayInfo, claudeInfo *ClaudeResponseInfo, data string, requestMode int) *types.NewAPIError {
var claudeResponse dto.ClaudeResponse
err := common.UnmarshalJsonStr(data, &claudeResponse)

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.

🛠️ Refactor suggestion

Inconsistent JSON unmarshalling method

This line still uses common.UnmarshalJsonStr while other places in the file have been updated to use common.Unmarshal. For consistency, this should also be updated.

-	err := common.UnmarshalJsonStr(data, &claudeResponse)
+	err := common.Unmarshal([]byte(data), &claudeResponse)
📝 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
err := common.UnmarshalJsonStr(data, &claudeResponse)
err := common.Unmarshal([]byte(data), &claudeResponse)
🤖 Prompt for AI Agents
In relay/channel/claude/relay-claude.go at line 523, replace the use of
common.UnmarshalJsonStr with common.Unmarshal to maintain consistency with other
JSON unmarshalling calls in the file. Update the code to call common.Unmarshal
passing the data and claudeResponse pointer accordingly.

@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

♻️ Duplicate comments (1)
controller/channel-billing.go (1)

471-471: Past review issue resolved - balance-based disabling is working

The balance-based channel disabling logic is now active and correctly uses the new structured error type types.NewChannelError. This addresses the previous concern about commented out auto-disable functionality.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50b76f4 and 52a5e58.

📒 Files selected for processing (11)
  • constant/context_key.go (1 hunks)
  • controller/channel-billing.go (4 hunks)
  • middleware/distributor.go (4 hunks)
  • model/channel.go (5 hunks)
  • relay/channel/cohere/adaptor.go (2 hunks)
  • relay/channel/cohere/relay-cohere.go (6 hunks)
  • relay/channel/coze/adaptor.go (2 hunks)
  • relay/channel/coze/relay-coze.go (5 hunks)
  • relay/channel/ollama/relay-ollama.go (3 hunks)
  • service/log_info_generate.go (2 hunks)
  • web/src/components/table/LogsTable.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • relay/channel/coze/adaptor.go
  • relay/channel/coze/relay-coze.go
  • relay/channel/ollama/relay-ollama.go
  • relay/channel/cohere/adaptor.go
  • middleware/distributor.go
  • constant/context_key.go
  • relay/channel/cohere/relay-cohere.go
🧰 Additional context used
🧠 Learnings (1)
controller/channel-billing.go (1)
Learnt from: 9Ninety
PR: QuantumNous/new-api#1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.
🧬 Code Graph Analysis (2)
service/log_info_generate.go (2)
common/gin.go (2)
  • GetContextKeyBool (64-66)
  • GetContextKeyInt (60-62)
constant/context_key.go (2)
  • ContextKeyChannelIsMultiKey (31-31)
  • ContextKeyChannelMultiKeyIndex (32-32)
model/channel.go (9)
constant/multi_key_mode.go (3)
  • MultiKeyMode (3-3)
  • MultiKeyModeRandom (6-6)
  • MultiKeyModePolling (7-7)
common/json.go (2)
  • Marshal (20-22)
  • Unmarshal (8-10)
types/error.go (4)
  • NewAPIError (75-81)
  • NewError (138-146)
  • ErrorCodeChannelNoAvailableKey (48-48)
  • ErrorCodeGetChannelFailed (45-45)
common/constants.go (4)
  • ChannelStatusEnabled (192-192)
  • DebugEnabled (70-70)
  • MemoryCacheEnabled (71-71)
  • ChannelStatusAutoDisabled (194-194)
model/channel_cache.go (3)
  • CacheGetChannelInfo (215-234)
  • CacheGetChannel (198-213)
  • CacheUpdateChannelStatus (236-245)
model/main.go (1)
  • DB (63-63)
common/utils.go (1)
  • GetTimestamp (192-194)
model/ability.go (1)
  • UpdateAbilityStatus (254-256)
common/logger.go (1)
  • SysError (55-58)
🔇 Additional comments (9)
controller/channel-billing.go (3)

419-419: LGTM: Improved performance with cache usage

The switch from model.GetChannelById(id) to model.CacheGetChannel(id) aligns with the caching improvements and provides better performance.


427-433: Appropriate multi-key channel exclusion

Correctly rejects balance queries for multi-key channels since individual keys within a multi-key channel may have different balances, making a single balance value meaningless.


458-460: Logical exclusion of multi-key channels from bulk balance updates

Skipping multi-key channels during bulk balance updates makes sense since these channels require individual key management rather than single balance tracking.

service/log_info_generate.go (1)

33-37: Well-implemented multi-key logging enhancement

The addition of multi-key information to admin logs is properly implemented:

  • Correctly extracts context values using appropriate helper functions
  • Conditionally adds multi-key data only when relevant
  • Maintains consistency with existing admin info structure

This provides valuable visibility into multi-key channel usage in logs.

web/src/components/table/LogsTable.js (1)

359-398: Excellent UI enhancement for multi-key visibility

The multi-key indicator implementation is well-executed:

  • Properly extracts multi-key information from log admin info
  • Conditionally displays the multi-key index tag only when applicable
  • Uses appropriate UI components (Space, Tooltip) for clean layout
  • Maintains existing channel display while adding valuable multi-key context
  • Clear visual distinction with white tag for multi-key index

This provides administrators with clear visibility into which specific key was used for multi-key channels.

model/channel.go (4)

51-68: Well-designed multi-key data structure with proper serialization

The ChannelInfo struct is well-designed with:

  • Clear field naming and purposes
  • Proper JSON serialization support via Value() and Scan() methods
  • Appropriate use of maps for status tracking

The database serialization implementation correctly handles the conversion between Go structs and JSON for database storage.


441-473: Excellent thread-safe polling implementation

The channel polling lock management is well-implemented:

  • Uses sync.Map for concurrent access to per-channel locks
  • LoadOrStore ensures only one lock per channel
  • Cleanup function prevents memory leaks
  • Clear separation of concerns

This provides robust concurrency control for multi-key polling operations.


475-503: Robust multi-key status management

The handlerMultiKeyUpdate function correctly handles multi-key status updates:

  • Proper key index mapping
  • Lazy initialization of status map
  • Automatic channel disabling when all keys are disabled
  • Appropriate status reason tracking

The logic correctly handles both single key and multi-key scenarios.


505-570: Well-refactored channel status update with multi-key support

The UpdateChannelStatus function has been successfully refactored to support multi-key channels:

  • Proper separation of cache and database operations
  • Conditional ability updates using defer pattern
  • Consistent handling of both single and multi-key channels
  • Appropriate error handling and logging

The use of shouldUpdateAbilities flag with defer ensures abilities are updated only when necessary.

Comment thread model/channel.go
Comment on lines +112 to +114
if len(enabledIdx) == 0 {
return keys[0], 0, 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

Potential issue: Fallback to first key may return disabled key

The fallback logic when no enabled keys are found returns keys[0] regardless of its status. This could return a disabled key, which might not be the intended behavior.

Consider modifying the fallback logic to either:

  1. Return an error when no keys are enabled
  2. Check the first key's status before returning it
 if len(enabledIdx) == 0 {
-    return keys[0], 0, nil
+    return "", 0, types.NewError(errors.New("no enabled keys available"), types.ErrorCodeChannelNoAvailableKey)
 }
📝 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
if len(enabledIdx) == 0 {
return keys[0], 0, nil
}
if len(enabledIdx) == 0 {
- return keys[0], 0, nil
+ return "", 0, types.NewError(
+ errors.New("no enabled keys available"),
+ types.ErrorCodeChannelNoAvailableKey,
+ )
}
🤖 Prompt for AI Agents
In model/channel.go around lines 112 to 114, the fallback logic returns keys[0]
even if it is disabled, which may cause unintended behavior. Modify the code to
either return an error when no enabled keys are found or verify that keys[0] is
enabled before returning it. This ensures only enabled keys are returned or an
appropriate error is raised.

Comment thread model/channel.go
Comment on lines +132 to +141
defer func() {
if common.DebugEnabled {
println(fmt.Sprintf("channel %d polling index: %d", channel.Id, channel.ChannelInfo.MultiKeyPollingIndex))
}
if !common.MemoryCacheEnabled {
_ = channel.SaveChannelInfo()
} else {
// CacheUpdateChannel(channel)
}
}()

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.

🛠️ Refactor suggestion

Complex defer logic needs simplification

The defer function contains complex conditional logic that may be difficult to maintain and reason about:

  • Mixed concerns of debugging, caching, and persistence
  • Conditional execution based on cache settings
  • Commented out cache update logic

Consider simplifying this logic by separating concerns:

 defer func() {
     if common.DebugEnabled {
         println(fmt.Sprintf("channel %d polling index: %d", channel.Id, channel.ChannelInfo.MultiKeyPollingIndex))
     }
-    if !common.MemoryCacheEnabled {
-        _ = channel.SaveChannelInfo()
-    } else {
-        // CacheUpdateChannel(channel)
-    }
+    _ = channel.SaveChannelInfo()
 }()
🤖 Prompt for AI Agents
In model/channel.go around lines 132 to 141, the defer function mixes debugging
output, cache checking, and persistence logic, making it complex and hard to
maintain. Refactor by extracting the debug print, cache check, and save/update
operations into separate functions or clearly separated code blocks outside the
defer, then call these simplified functions or blocks within the defer. Remove
commented-out code or implement it properly if needed to keep the defer concise
and focused on a single responsibility.

This was referenced Sep 10, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Oct 26, 2025
@coderabbitai coderabbitai Bot mentioned this pull request May 6, 2026
11 tasks
@coderabbitai coderabbitai Bot mentioned this pull request May 21, 2026
11 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