Skip to content

fix: improve playground endpoint support / resolve issue #4503 - #4727

Closed
Harry326485 wants to merge 4 commits into
QuantumNous:mainfrom
Harry326485:fix/issue-4503
Closed

fix: improve playground endpoint support / resolve issue #4503#4727
Harry326485 wants to merge 4 commits into
QuantumNous:mainfrom
Harry326485:fix/issue-4503

Conversation

@Harry326485

@Harry326485 Harry326485 commented May 10, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

本 PR 改进 Playground / 操练场 在不同接口格式下的请求与响应处理,使其可以按端点分别调用 Chat Completions、Responses、Claude Messages 和 Image Generations,并可依据选用的模型自动设置使用的端点类型。本 PR 为 Image Generations 端点提供了图像生成设置的适配。

🚀 变更类型 / Type of change

  • [ x ] ✨ 新功能 (New feature)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • [ x ] 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • [ x ] 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • [ x ] Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • [ x ] 变更理解: 我已理解这些更改的工作原理及可能影响。
  • [ x ] 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • [ x ] 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • [ x ] 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

image

Summary by CodeRabbit

  • New Features
    • Image generation in Playground with quality/size controls and image-grid display.
    • Multiple Playground endpoints (chat, responses, Claude, image generations) with an endpoint selector and manual override.
  • Improvements
    • Auto-detects best endpoint from model and routes requests/streams per endpoint.
    • Unified payload/response handling and validation (image size/quality) with clearer error feedback.
  • Localization
    • Updated translations and labels for endpoint UI, image controls, and validation across locales.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR adds multi-endpoint playground support: backend routing and relay-format selection, endpoint inference from model names, image-generation parameters and validation, unified payload builders and response normalization, SSE/non-SSE handling, UI endpoint/image controls, and translations.

Changes

Multi-Endpoint Playground Architecture

Layer / File(s) Summary
Backend Routing
middleware/distributor.go, controller/playground.go, router/relay-router.go, relay/constant/relay_mode.go
Generalize /pg/* detection, pass relayFormat into Playground, read model/group from request, set context group, extend path→relay-mode mapping (including /pg/images/generations and /pg/responses).
Image Validation
relay/helper/valid_request.go
Centralized OpenAI image request validation: allowed qualities, size format (axb), reject '×' char, enforce width/height ≤ 3840; called from multipart and JSON branches.
Type Definitions
web/default/src/features/playground/types.ts
Add PlaygroundEndpoint, PlaygroundImage, extend Message with images, add ResponsesRequest/ClaudeMessagesRequest/ImageGenerationRequest, and extend PlaygroundConfig with endpoint override, token/output limits, and image fields.
Endpoint Inference & Labels
web/default/src/features/playground/lib/endpoint.ts, web/classic/src/helpers/api.js
Infer endpoint from model name (image/Claude/GPT patterns); provide UI label/description/url helpers per endpoint.
Payload Builders
web/default/src/features/playground/lib/payload-builder.ts, web/classic/src/helpers/api.js
Add endpoint-specific payload builders (chat-completions, responses, claude-messages, image-generations) and common parameter application (temperature/top_p, max_tokens/max_output_tokens).
Response Normalization
web/default/src/features/playground/lib/response-parser.ts, web/classic/src/hooks/playground/useApiRequest.jsx
Normalize diverse endpoint responses into {content, reasoning?, images?}; provide error normalization (including 504 handling).
API & Streaming Hooks
web/default/src/features/playground/api.ts, web/default/src/features/playground/hooks/use-stream-request.ts, web/classic/src/hooks/playground/useApiRequest.jsx
Introduce sendPlaygroundRequest and per-endpoint ENDPOINT_URL mappings; refactor stream handling to accept endpoint and endpoint-specific SSE parsing; non-stream requests normalized then applied to messages.
UI Message Rendering
web/classic/src/components/playground/MessageContent.jsx, web/default/src/features/playground/components/playground-chat.tsx
Normalize message content shapes, extract images (url or base64), render images grid and fallbacks for missing data.
Input & Settings Controls
web/classic/src/components/playground/SettingsPanel.jsx, web/default/src/features/playground/components/playground-input.tsx, web/default/src/features/playground/lib/validation.ts, web/classic/src/helpers/playgroundValidation.js
Add endpoint dropdown (auto-detected/inferred), conditional image quality and size controls, image-size validation (axb, ≤3840), and quality options.
Page Integration & Hooks
web/classic/src/pages/Playground/index.jsx, web/default/src/features/playground/index.tsx, web/classic/src/hooks/playground/useMessageEdit.jsx
Compute inferred/effective endpoint, thread endpoint through payload builders and sendRequest, validate image size before send, disable streaming for image-generation endpoints, clear endpointOverride on model change.
Constants & Defaults
web/classic/src/constants/playground.constants.js, web/default/src/features/playground/constants.ts
Add PLAYGROUND_ENDPOINTS, expand API_ENDPOINTS with /pg/responses, /pg/messages, /pg/images/generations, and extend DEFAULT_CONFIG with endpointOverride, max_output_tokens, and image defaults.
Internationalization
web/classic/src/i18n/locales/*, web/default/src/i18n/locales/*
Add/adjust translation keys for endpoint auto-detection labels/descriptions, image quality/size UI, validation messages, and generated image labels across multiple locales.
Misc / Supporting
web/classic/src/components/playground/OptimizedComponents.js, web/classic/src/components/playground/configStorage.js, web/default/src/components/ui/select.tsx, library re-exports
Memo comparator expanded to include message.images, removed duplicate local storage key, small select styling change, and new re-exports for endpoint/response-parser modules.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Calcium-Ion
  • seefs001
  • creamlike1024

Poem

🐰 A rabbit hops through playground lanes,

routing endpoints and naming grains.
Images, responses, Claude in view —
tokens set, validations true.
A little hop — the app says “Done!” 🎨

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
web/classic/src/i18n/locales/en.json (1)

2802-2812: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Inconsistent i18n key language and redundant English→English mappings.

Lines 2802-2812 use English keys with English values (e.g., "Image quality": "Image quality"), which is inconsistent with the rest of this file where Chinese keys map to English translations.

Issues:

  1. Redundant entries: In en.json, English key → English value provides no translation and should be avoided. The code should reference these keys directly or use Chinese keys like the rest of the file.

  2. Key language inconsistency: Mixing Chinese and English keys in the same locale file makes maintenance harder and can cause confusion about which pattern to follow.

  3. Potential conflict/duplication:

    • Line 2602: "端点(自动识别)": "Endpoint (auto-detected)"
    • Line 2802: "Endpoint (auto inferred)": "Endpoint (auto inferred)"

    These appear to represent the same concept but with different phrasing ("auto-detected" vs "auto inferred"). If both are used in the codebase, users may see inconsistent terminology.

✏️ Recommended fix: Convert to Chinese keys or remove redundant entries

Option 1 (Recommended): Convert English keys to Chinese to match file convention:

-"Endpoint (auto inferred)": "Endpoint (auto inferred)",
-"Auto inferred": "Auto inferred",
-"Image quality": "Image quality",
-"Image size": "Image size",
-"Quality": "Quality",
-"low": "low",
-"medium": "medium",
-"high": "high",
-"auto": "auto",
-"Size must use axb format with positive integer dimensions": "Size must use axb format with positive integer dimensions",
-"Size width and height must be less than or equal to 3840": "Size width and height must be less than or equal to 3840",
+"自动推断": "Auto inferred",
+"图片质量": "Image quality",
+"图片尺寸": "Image size",
+"质量": "Quality",
+"低": "low",
+"中": "medium",
+"高": "high",
+"自动": "auto",
+"尺寸必须使用axb格式,且为正整数": "Size must use axb format with positive integer dimensions",
+"尺寸宽度和高度必须小于等于3840": "Size width and height must be less than or equal to 3840",

Option 2: If these entries are not actually needed (code uses keys directly), remove them entirely.

Also consider:

  • Reconciling line 2602 ("auto-detected") with line 2802 ("auto inferred") to use consistent terminology
  • Verifying that line 2802 "Endpoint (auto inferred)" isn't a duplicate of line 2602 "端点(自动识别)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/i18n/locales/en.json` around lines 2802 - 2812, Replace any
English-key → English-value entries in en.json with the canonical Chinese keys
used elsewhere (or remove them if unused) so the locale file consistently maps
Chinese keys to English translations; specifically remove or convert redundant
entries like "Endpoint (auto inferred)" to the Chinese key "端点(自动识别)" (or
vice‑versa) and reconcile phrasing so only one canonical key/value exists for
the endpoint concept; review keys shown in the diff (e.g., "聊天应用名称已存在,请使用其他名称",
"聊天设置", "自动分组", "自动刷新", and the conflicting "Endpoint (auto inferred)" vs
"端点(自动识别)") and update or delete duplicates to keep a single consistent mapping.
web/classic/src/components/playground/MessageContent.jsx (1)

321-365: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the normalized assistant text in the array-content path.

This branch rebuilds text from raw message.content, so assistant array payloads can still render <think> blocks inline even though the earlier extraction already moved them into ThinkingContent. Reuse finalDisplayableFinalContent for assistant messages here.

Suggested fix
-            const displayableTextContent = getTextContent(message.content);
+            const displayableTextContent =
+              message.role === 'assistant'
+                ? finalDisplayableFinalContent
+                : getTextContent(message.content);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/components/playground/MessageContent.jsx` around lines 321 -
365, The array-content branch rebuilds text from raw message.content causing
assistant messages to reintroduce <think> blocks; instead, when message.role ===
'assistant' use the already-normalized assistant text
(finalDisplayableFinalContent) rather than getTextContent(message.content).
Update the Array.isArray(message.content) path in MessageContent.jsx to select
finalDisplayableFinalContent for assistant messages (fall back to getTextContent
for others), and pass that variable into MarkdownRenderer and the
displayableTextContent checks so assistant messages use the previously
extracted/normalized text.
web/classic/src/hooks/playground/useMessageEdit.jsx (1)

141-150: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add endpoint to handleEditSave dependencies to avoid stale endpoint routing.

handleEditSave uses endpoint inside the callback but does not track it in the dependency array. After endpoint switches, edit-regenerate requests can be sent to the previous endpoint.

Suggested fix
   }, [
     editingMessageId,
     editValue,
     t,
     inputs,
     parameterEnabled,
+    endpoint,
     sendRequest,
     setMessage,
     saveMessages,
   ]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/hooks/playground/useMessageEdit.jsx` around lines 141 - 150,
The callback handleEditSave captures the current endpoint but the dependency
array (editingMessageId, editValue, t, inputs, parameterEnabled, sendRequest,
setMessage, saveMessages) omits endpoint, causing stale routing after endpoint
changes; update the dependency array where handleEditSave is defined (the
useCallback/useEffect that lists editingMessageId...saveMessages) to include
endpoint so handleEditSave is re-created when endpoint changes, ensuring
edit-regenerate requests are sent to the correct endpoint.
🧹 Nitpick comments (4)
web/default/src/i18n/locales/fr.json (1)

4407-4418: 🏗️ Heavy lift

Unify these new i18n keys under a hierarchical namespace

These additions use literal phrase keys (and one Chinese literal key) instead of semantic hierarchical keys, which will make cross-locale maintenance and key reuse harder. Please migrate these to a consistent namespace (e.g., playground.endpoint.autoInferred, playground.image.quality, playground.image.size.validation.max) and keep key style consistent in this block.

As per coding guidelines, "Use hierarchical and semantically clear translation key names such as dashboard.overview.title and maintain naming consistency".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/i18n/locales/fr.json` around lines 4407 - 4418, The new i18n
entries use literal phrases (and a Chinese key) — replace them with
hierarchical, semantically consistent keys and migrate values in fr.json
accordingly: e.g., map "Endpoint (auto inferred)" ->
"playground.endpoint.autoInferred", "Auto inferred" ->
"playground.endpoint.autoInferredLabel" (or similar), "Image quality" ->
"playground.image.quality", quality options "low"/"medium"/"high"/"auto" ->
"playground.image.quality.options.low|medium|high|auto", "Image size" ->
"playground.image.size", the validation messages ->
"playground.image.size.validation.format" and
"playground.image.size.validation.max", and the Chinese "请选择质量" ->
"playground.image.quality.select"; update fr.json keys to these names, ensure
all code references (components using these keys) are updated to the new keys
and other locale files are kept in sync.
web/default/src/i18n/locales/vi.json (1)

4418-4418: 🏗️ Heavy lift

Use a consistent semantic key instead of a Chinese sentence key.

Line 4418 introduces "请选择质量" as a translation key, which breaks naming consistency in this locale file and makes cross-locale maintenance harder. Prefer a stable semantic key (or the same source-key style used by the rest of this feature across locales), then map this Vietnamese text as the value.

As per coding guidelines, "Use hierarchical and semantically clear translation key names such as dashboard.overview.title and maintain naming consistency".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/i18n/locales/vi.json` at line 4418, Replace the
Chinese-sentence translation key "请选择质量" with a semantic, hierarchical key
(e.g., "quality.select" or "video.quality.select") and update the value to the
Vietnamese text "Vui lòng chọn chất lượng"; locate and rename the key in the
vi.json entry and ensure any code or other locale files that reference "请选择质量"
(search for that exact string) are updated to use the new semantic key
("quality.select" or chosen variant) so all locales remain consistent.
web/default/src/i18n/locales/en.json (1)

4418-4418: ⚡ Quick win

Use a semantic i18n key instead of source-language text

"请选择质量" as the key breaks key naming consistency and makes locale synchronization harder. Prefer a stable semantic key (e.g., playground.image.quality.required) and keep language-specific text in values per locale.

As per coding guidelines: "Use hierarchical and semantically clear translation key names such as dashboard.overview.title and maintain naming consistency".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/i18n/locales/en.json` at line 4418, Replace the
source-language i18n key "请选择质量" with a semantic hierarchical key (for example
playground.image.quality.required) in en.json and update the corresponding value
to "Please select quality"; also propagate that new key to all other locale
files and update any code references that read the old key ("请选择质量") so they use
playground.image.quality.required instead to maintain naming consistency and
enable proper locale sync.
web/default/src/features/playground/lib/payload-builder.ts (1)

36-38: ⚡ Quick win

Add explicit return types for new helper functions

Please annotate return types for getProcessedMessages and applyCommonTextParameters to match the repo’s TS rule and keep signatures stable during refactors.

Suggested fix
-function getProcessedMessages(messages: Message[]) {
+function getProcessedMessages(messages: Message[]): ReturnType<typeof messages.filter> {
   return messages.filter(isValidMessage).map(formatMessageForAPI)
 }
@@
 function applyCommonTextParameters(
   payload: Record<string, unknown>,
   config: PlaygroundConfig,
   parameterEnabled: ParameterEnabled,
   maxTokenKey: 'max_tokens' | 'max_output_tokens'
-) {
+): void {

As per coding guidelines, "web/default/**/*.{ts,tsx} ... explicitly annotate parameter and return value types".

Also applies to: 50-62

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/playground/lib/payload-builder.ts` around lines 36 -
38, Add explicit return type annotations for the new helpers: annotate
getProcessedMessages as returning an array of the formatted-API message type
(use Array<ReturnType<typeof formatMessageForAPI>> for stability) and annotate
applyCommonTextParameters with its explicit return type (string) so both
function signatures are fully typed and comply with the repo rule; update the
function declarations for getProcessedMessages and applyCommonTextParameters to
include these return types.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controller/playground.go`:
- Around line 50-53: The code directly assigns playgroundRequest.Group to
usingGroup without authorization; instead retrieve the authenticated user's
authorized groups from the request context (the same token/claims source used
elsewhere), verify playgroundRequest.Group is contained in that authorized group
list, and only set usingGroup = playgroundRequest.Group when the check passes;
if the group is not authorized either leave usingGroup as the token-derived
value or return an authorization error (403). Use the existing context helpers
(e.g., common.GetContextKeyString / the token/claims key used for user groups)
and the playgroundRequest.Group and constant.ContextKeyUsingGroup symbols to
locate and implement this validation.

In `@relay/common/relay_info.go`:
- Around line 413-417: GenRelayInfoImage currently overwrites the path-derived
RelayMode set by genBaseRelayInfo(), causing endpoints like /v1/edits and
/v1/images/edits to be misclassified; remove the line that assigns
info.RelayMode = relayconstant.RelayModeImagesGenerations in GenRelayInfoImage
so the RelayMode from genBaseRelayInfo() is preserved and routing/billing remain
correct.

In `@relay/helper/valid_request.go`:
- Around line 171-172: The Atoi calls for matches[1] and matches[2] ignore
errors causing invalid dimensions (0) to bypass the <=3840 check; update the
parsing in the validation logic (where width, height are produced from
strconv.Atoi on matches) to check and handle errors: if strconv.Atoi returns an
error or produces non-positive values, return a validation error/reject the
request; additionally ensure you validate that parsed width and height are
within the allowed range (1..3840) before proceeding. Use the same variable
names (width, height) and the existing validation code path so bad Atoi results
cannot slip through.

In `@web/classic/src/helpers/playgroundValidation.js`:
- Around line 7-10: The size validation currently uses a case-sensitive regex
/^([1-9]\d*)x([1-9]\d*)$/ which rejects inputs like "1024X1024"; update the
pattern used where match is assigned (the regex applied to trimmedSize) to
accept either lowercase or uppercase 'x' (for example by using a character class
[xX] or a case-insensitive flag) so "1024X1024" passes the same axb positive
integer check and keep the existing error message unchanged.

In `@web/classic/src/i18n/locales/zh.json`:
- Line 1782: The translation uses the awkward phrase "图片记忆" in the value string
"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。"; update that sentence to use "图片数据"
instead (e.g., "服务器不会保存图片数据") so the message reads naturally and accurately
warns that image data won't be persisted; modify the translation value for that
JSON entry accordingly.

In `@web/default/src/features/playground/components/playground-chat.tsx`:
- Around line 264-285: The img alt text in the PlaygroundChat component is
hardcoded; update it to use i18n by calling useTranslation().t() instead of the
literal string—e.g., ensure the component imports and invokes useTranslation
(const { t } = useTranslation()) and replace alt={`Generated image ${imageIndex
+ 1}`} with alt={t('playground.generatedImage', { number: imageIndex + 1 })} (or
similar translation key), and add the corresponding translation key in your
locale files; apply this change where message.images is mapped and for the img
element inside the map so all user-facing image alt text is localized.

In `@web/default/src/features/playground/components/playground-input.tsx`:
- Around line 181-245: The Select controls (endpoint Select and image quality
Select) and the image size Input lack programmatic labels and the image size
error isn't associated to the input; update the JSX around the Select components
(the Select, SelectTrigger/SelectValue blocks used for endpoint and image
quality) and the Input (value={imageSize}, onChange={onImageSizeChange}) to
include accessible labels: add a visually rendered <label> for each field or
create stable id attributes (e.g., endpoint-select-id, image-quality-select-id,
image-size-input-id) and set aria-labelledby on the matching
SelectTrigger/Select and aria-describedby on the Input to point to an error
message element when imageSizeError is present; ensure the error span that
renders {t(imageSizeError)} has that id so screen readers will announce the
error.

In `@web/default/src/features/playground/lib/endpoint.ts`:
- Around line 38-61: Replace hardcoded English strings in getEndpointLabel and
getEndpointDescription with i18n lookups: import { t } from 'i18next' and use
t('playground.endpoint.label.responses') /
t('playground.endpoint.description.responses') (and analogous keys for
'claude-messages', 'image-generations', and default) instead of literal text;
ensure keys are named consistently for both label and description and reference
the PlaygroundEndpoint type in the switch branches so translation keys map
exactly to each case, then add those keys to the locale resource files.

In `@web/default/src/features/playground/lib/payload-builder.ts`:
- Around line 154-160: The Claude payload unconditionally overwrites max_tokens,
bypassing the parameter toggle; update the code around applyCommonTextParameters
and the payload.max_tokens assignment so that payload.max_tokens is only set
when parameterEnabled.max_tokens is true (or when the toggle logic in
applyCommonTextParameters indicates it should be applied). Locate the block that
calls applyCommonTextParameters(payload..., config, parameterEnabled,
'max_tokens') and replace the unconditional payload.max_tokens =
config.max_tokens with a conditional assignment that respects
parameterEnabled.max_tokens (or defers to applyCommonTextParameters' result) so
Claude follows the same toggle behavior as other endpoints.

In `@web/default/src/features/playground/lib/response-parser.ts`:
- Around line 168-190: Replace hardcoded English messages in response-parser.ts
with i18n keys: import { t } from 'i18next' at the top, then update the status
=== 504 branch to return t('errors.gatewayTimeout') (or similar key) instead of
the hardcoded timeout string; update the typeof responseData === 'string' branch
to use a translation key like t('errors.httpError', { status, statusText:
err?.response?.statusText }) or t('errors.requestError') as fallback; and update
the final return message fallback to use t('errors.requestError') and map
responseData?.error?.code as before. Ensure keys are descriptive (e.g.,
errors.gatewayTimeout, errors.httpError, errors.requestError) so translators can
provide localized strings.

In `@web/default/src/features/playground/lib/validation.ts`:
- Around line 7-20: The helper validateImageSize currently returns raw English
strings; change it to perform translation inside the module by importing { t }
from 'i18next' and replacing the literal messages with translated strings (e.g.
t('playground.validation.sizeFormat') and t('playground.validation.sizeMax')) so
callers receive localized text; update validateImageSize (and any places using
IMAGE_SIZE_PATTERN) to call t(...) for the "axb format" error and the "max 3840"
error and return those results instead of raw English.

In `@web/default/src/i18n/locales/ja.json`:
- Around line 4406-4418: The JSON uses UI text strings as keys (e.g., "Zoom",
"Image quality", "Size must use axb format with positive integer dimensions",
"请选择质量") which violates the i18n key policy; replace these flat UI-text keys
with hierarchical semantic keys (for example playground.endpoint.autoInferred,
playground.image.zoom, playground.image.quality,
playground.image.size.formatError, playground.image.size.limitError,
playground.image.quality.select) keeping the current Japanese translations as
the values; update any code references to these keys (search for usages of
"Zoom", "Image quality", the size error messages, and "请选择质量") so the app
queries the new keys; ensure naming is consistent with existing namespaces
(playground.endpoint.* and playground.image.*).
- Line 4418: The key "请选择质量" in ja.json is a Chinese source key and should be
replaced with the semantic key used for quality prompts across locales (e.g.,
the existing quality namespace such as "please_select_quality" or
"quality.select"); locate the equivalent key in other locale files
(en.json/zh.json) to confirm the canonical key name, replace the Chinese key in
ja.json with that semantic key and keep the value "品質を選択してください", and then run a
quick grep over locales to ensure all locales use the same key name for this
message.

In `@web/default/src/i18n/locales/ru.json`:
- Around line 4407-4418: Rename the literal translation keys to hierarchical
semantic keys and update all usages: replace "Endpoint (auto inferred)" →
"playground.endpoint.autoInferredLabel", "Auto inferred" →
"playground.endpoint.autoInferred", "Image quality" →
"playground.image.quality", "Image size" → "playground.image.size", the quality
options "low"/"medium"/"high"/"auto" should be namespaced under
"playground.image.quality.options", and "请选择质量" →
"playground.image.quality.select"; apply these key changes across all locale
JSONs under the locales directories and update the t() invocations inside the
Playground input component (the component named playground-input and its t(...)
calls for endpoint, auto inferred, image quality, image size and the quality
selector) to use the new semantic keys.

In `@web/default/src/i18n/locales/vi.json`:
- Line 4406: The vi locale entry for the key "Zoom" is still in English; update
the value for the "Zoom" key in the vi JSON locale to the Vietnamese translation
(e.g., "Phóng to" or "Thu phóng"), ensuring valid JSON string quoting and no
trailing commas so the line becomes: "Zoom": "Phóng to".

In `@web/default/src/i18n/locales/zh.json`:
- Line 4418: The translation entry uses a Chinese string "请选择质量" as the i18n key
which breaks the English-key convention; replace the key with a
language-neutral, semantic English key (e.g., "select_quality" or
"quality.select") and keep the value as the Chinese text "请选择质量", then update
any other locale files and code references that use the old key to use the new
key ("select_quality" / "quality.select") to maintain consistency across
locales.

---

Outside diff comments:
In `@web/classic/src/components/playground/MessageContent.jsx`:
- Around line 321-365: The array-content branch rebuilds text from raw
message.content causing assistant messages to reintroduce <think> blocks;
instead, when message.role === 'assistant' use the already-normalized assistant
text (finalDisplayableFinalContent) rather than getTextContent(message.content).
Update the Array.isArray(message.content) path in MessageContent.jsx to select
finalDisplayableFinalContent for assistant messages (fall back to getTextContent
for others), and pass that variable into MarkdownRenderer and the
displayableTextContent checks so assistant messages use the previously
extracted/normalized text.

In `@web/classic/src/hooks/playground/useMessageEdit.jsx`:
- Around line 141-150: The callback handleEditSave captures the current endpoint
but the dependency array (editingMessageId, editValue, t, inputs,
parameterEnabled, sendRequest, setMessage, saveMessages) omits endpoint, causing
stale routing after endpoint changes; update the dependency array where
handleEditSave is defined (the useCallback/useEffect that lists
editingMessageId...saveMessages) to include endpoint so handleEditSave is
re-created when endpoint changes, ensuring edit-regenerate requests are sent to
the correct endpoint.

In `@web/classic/src/i18n/locales/en.json`:
- Around line 2802-2812: Replace any English-key → English-value entries in
en.json with the canonical Chinese keys used elsewhere (or remove them if
unused) so the locale file consistently maps Chinese keys to English
translations; specifically remove or convert redundant entries like "Endpoint
(auto inferred)" to the Chinese key "端点(自动识别)" (or vice‑versa) and reconcile
phrasing so only one canonical key/value exists for the endpoint concept; review
keys shown in the diff (e.g., "聊天应用名称已存在,请使用其他名称", "聊天设置", "自动分组", "自动刷新", and
the conflicting "Endpoint (auto inferred)" vs "端点(自动识别)") and update or delete
duplicates to keep a single consistent mapping.

---

Nitpick comments:
In `@web/default/src/features/playground/lib/payload-builder.ts`:
- Around line 36-38: Add explicit return type annotations for the new helpers:
annotate getProcessedMessages as returning an array of the formatted-API message
type (use Array<ReturnType<typeof formatMessageForAPI>> for stability) and
annotate applyCommonTextParameters with its explicit return type (string) so
both function signatures are fully typed and comply with the repo rule; update
the function declarations for getProcessedMessages and applyCommonTextParameters
to include these return types.

In `@web/default/src/i18n/locales/en.json`:
- Line 4418: Replace the source-language i18n key "请选择质量" with a semantic
hierarchical key (for example playground.image.quality.required) in en.json and
update the corresponding value to "Please select quality"; also propagate that
new key to all other locale files and update any code references that read the
old key ("请选择质量") so they use playground.image.quality.required instead to
maintain naming consistency and enable proper locale sync.

In `@web/default/src/i18n/locales/fr.json`:
- Around line 4407-4418: The new i18n entries use literal phrases (and a Chinese
key) — replace them with hierarchical, semantically consistent keys and migrate
values in fr.json accordingly: e.g., map "Endpoint (auto inferred)" ->
"playground.endpoint.autoInferred", "Auto inferred" ->
"playground.endpoint.autoInferredLabel" (or similar), "Image quality" ->
"playground.image.quality", quality options "low"/"medium"/"high"/"auto" ->
"playground.image.quality.options.low|medium|high|auto", "Image size" ->
"playground.image.size", the validation messages ->
"playground.image.size.validation.format" and
"playground.image.size.validation.max", and the Chinese "请选择质量" ->
"playground.image.quality.select"; update fr.json keys to these names, ensure
all code references (components using these keys) are updated to the new keys
and other locale files are kept in sync.

In `@web/default/src/i18n/locales/vi.json`:
- Line 4418: Replace the Chinese-sentence translation key "请选择质量" with a
semantic, hierarchical key (e.g., "quality.select" or "video.quality.select")
and update the value to the Vietnamese text "Vui lòng chọn chất lượng"; locate
and rename the key in the vi.json entry and ensure any code or other locale
files that reference "请选择质量" (search for that exact string) are updated to use
the new semantic key ("quality.select" or chosen variant) so all locales remain
consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: df81c936-e104-402c-a605-054ebd9ee72d

📥 Commits

Reviewing files that changed from the base of the PR and between 543cc64 and bde173f.

📒 Files selected for processing (44)
  • controller/playground.go
  • middleware/distributor.go
  • relay/common/relay_info.go
  • relay/constant/relay_mode.go
  • relay/helper/valid_request.go
  • router/relay-router.go
  • web/classic/src/components/playground/MessageContent.jsx
  • web/classic/src/components/playground/OptimizedComponents.js
  • web/classic/src/components/playground/SettingsPanel.jsx
  • web/classic/src/components/playground/configStorage.js
  • web/classic/src/constants/playground.constants.js
  • web/classic/src/helpers/api.js
  • web/classic/src/helpers/playgroundValidation.js
  • web/classic/src/hooks/playground/useApiRequest.jsx
  • web/classic/src/hooks/playground/useMessageEdit.jsx
  • web/classic/src/i18n/locales/en.json
  • web/classic/src/i18n/locales/fr.json
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/vi.json
  • web/classic/src/i18n/locales/zh-CN.json
  • web/classic/src/i18n/locales/zh-TW.json
  • web/classic/src/i18n/locales/zh.json
  • web/classic/src/pages/Playground/index.jsx
  • web/default/src/components/ui/select.tsx
  • web/default/src/features/playground/api.ts
  • web/default/src/features/playground/components/playground-chat.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/constants.ts
  • web/default/src/features/playground/hooks/use-chat-handler.ts
  • web/default/src/features/playground/hooks/use-stream-request.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/lib/endpoint.ts
  • web/default/src/features/playground/lib/index.ts
  • web/default/src/features/playground/lib/payload-builder.ts
  • web/default/src/features/playground/lib/response-parser.ts
  • web/default/src/features/playground/lib/validation.ts
  • web/default/src/features/playground/types.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
💤 Files with no reviewable changes (1)
  • web/classic/src/components/playground/configStorage.js

Comment thread controller/playground.go
Comment thread relay/common/relay_info.go
Comment thread relay/helper/valid_request.go Outdated
Comment thread web/classic/src/helpers/playgroundValidation.js Outdated
Comment thread web/classic/src/i18n/locales/zh.json Outdated
"端点": "端点",
"端点(自动识别)": "端点(自动识别)",
"你知道你正在做什么吗?确定要继续吗?": "你知道你正在做什么吗?确定要继续吗?",
"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。": "图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Verify translation accuracy: "图片记忆" seems semantically unusual.

The phrase "图片记忆" (image memory) in line 1782 appears awkward in this context. Since the message warns users that images won't be persistently saved by the server, consider using "图片数据" (image data) instead:

-"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。": "图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。",
+"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片数据。": "图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片数据。",
📝 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
"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。": "图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆",
"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片数据。": "图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片数据",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/i18n/locales/zh.json` at line 1782, The translation uses the
awkward phrase "图片记忆" in the value string
"图片不会被持久化保存。如有需要,请立即下载生成的图片,服务器不会保存图片记忆。"; update that sentence to use "图片数据"
instead (e.g., "服务器不会保存图片数据") so the message reads naturally and accurately
warns that image data won't be persisted; modify the translation value for that
JSON entry accordingly.

Comment thread web/default/src/i18n/locales/ja.json Outdated
Comment thread web/default/src/i18n/locales/ja.json Outdated
Comment thread web/default/src/i18n/locales/ru.json Outdated
Comment thread web/default/src/i18n/locales/vi.json Outdated
"Zhipu": "Zhipu",
"Zhipu V4": "Zhipu V4",
"Zoom": "Zoom"
"Zoom": "Zoom",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate Zoom for Vietnamese locale.

Line 4406 keeps the English value ("Zoom"), which creates a visible mixed-language UI in vi.

💡 Suggested patch
-    "Zoom": "Zoom",
+    "Zoom": "Thu phóng",
📝 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
"Zoom": "Zoom",
"Zoom": "Thu phóng",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/i18n/locales/vi.json` at line 4406, The vi locale entry for
the key "Zoom" is still in English; update the value for the "Zoom" key in the
vi JSON locale to the Vietnamese translation (e.g., "Phóng to" or "Thu phóng"),
ensuring valid JSON string quoting and no trailing commas so the line becomes:
"Zoom": "Phóng to".

Comment thread web/default/src/i18n/locales/zh.json Outdated

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/classic/src/i18n/locales/en.json`:
- Around line 3800-3801: Replace the inconsistent phrase "auto inferred" with
the standardized term "auto-detected" across the locale entries that currently
read "Endpoint (auto inferred)" and "Auto inferred"; update the corresponding
translation keys/values (e.g., the strings "Endpoint (auto inferred)" and "Auto
inferred") so they match the existing "auto-detected" usage found elsewhere
(e.g., the entry at the other occurrence using "auto-detected"), ensuring both
key and value text are consistent.

In `@web/classic/src/i18n/locales/vi.json`:
- Line 4188: Remove the duplicate JSON key "阶梯计费(未匹配到对应阶梯)" from the vi.json
locale file (keep the original occurrence and delete the later duplicate
introduced in the diff), then validate the JSON to ensure no duplicate keys
remain and that the file parses correctly.

In `@web/default/src/i18n/locales/fr.json`:
- Line 4420: The translation string for the key "errors.httpError" currently
concatenates placeholders "{{status}}{{statusText}}" causing outputs like
"404Not Found"; update the value for errors.httpError to include a separator
(e.g., a space or a dash) between the placeholders so it renders as "404 Not
Found" or "404 - Not Found" while keeping the same placeholders.

In `@web/default/src/i18n/locales/ru.json`:
- Line 4420: The translation string for the key "errors.httpError" concatenates
status and statusText without a separator; update the value for
"errors.httpError" (in ru.json) to insert a separator (e.g., a space, colon, or
" — ") between {{status}} and {{statusText}} so rendered output becomes "500
Internal Server Error" or "500: Internal Server Error" instead of "500Internal
Server Error".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a5cb156a-953f-4c87-9349-52c93c3bee16

📥 Commits

Reviewing files that changed from the base of the PR and between bde173f and bdc0acd.

📒 Files selected for processing (24)
  • controller/playground.go
  • relay/helper/valid_request.go
  • web/classic/src/helpers/playgroundValidation.js
  • web/classic/src/i18n/locales/en.json
  • web/classic/src/i18n/locales/fr.json
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/vi.json
  • web/classic/src/i18n/locales/zh-CN.json
  • web/classic/src/i18n/locales/zh-TW.json
  • web/classic/src/i18n/locales/zh.json
  • web/default/src/features/playground/components/playground-chat.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/lib/endpoint.ts
  • web/default/src/features/playground/lib/payload-builder.ts
  • web/default/src/features/playground/lib/response-parser.ts
  • web/default/src/features/playground/lib/validation.ts
  • web/default/src/features/playground/types.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
✅ Files skipped from review due to trivial changes (2)
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/fr.json
🚧 Files skipped from review as they are similar to previous changes (11)
  • web/default/src/i18n/locales/vi.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/zh.json
  • relay/helper/valid_request.go
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/lib/endpoint.ts
  • web/default/src/features/playground/components/playground-chat.tsx
  • web/default/src/features/playground/types.ts
  • web/default/src/features/playground/lib/response-parser.ts
  • controller/playground.go
  • web/default/src/features/playground/lib/payload-builder.ts

Comment thread web/classic/src/i18n/locales/en.json Outdated
"默认补全倍率": "Tỷ lệ hoàn thành mặc định",
"阶梯计费(表达式解析失败)": "Thanh toán theo bậc (không phân tích được biểu thức)",
"阶梯计费(未匹配到对应阶梯)": "Thanh toán theo bậc (không tìm thấy bậc phù hợp)"
"阶梯计费(未匹配到对应阶梯)": "Thanh toán theo bậc (không tìm thấy bậc phù hợp)",

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 | 🔴 Critical | ⚡ Quick win

Remove duplicate translation key.

This key 阶梯计费(未匹配到对应阶梯) already exists at line 2817 with an identical translation. In JSON, duplicate keys are invalid - only the last occurrence will be retained. Please remove this duplicate entry.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/i18n/locales/vi.json` at line 4188, Remove the duplicate JSON
key "阶梯计费(未匹配到对应阶梯)" from the vi.json locale file (keep the original occurrence
and delete the later duplicate introduced in the diff), then validate the JSON
to ensure no duplicate keys remain and that the file parses correctly.

Comment thread web/default/src/i18n/locales/fr.json Outdated
Comment thread web/default/src/i18n/locales/ru.json Outdated
@Calcium-Ion

Copy link
Copy Markdown
Member

Thanks for the contribution. This PR is too large and mixes multiple unrelated changes, so we cannot review it reliably or validate regressions in one pass.

Please split it into smaller focused PRs, each covering one feature or one bug fix, with a clear description, related issue if applicable, and focused test/verification notes.

Closing this PR for now. We can review the smaller follow-up PRs separately.

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.

support image generation in playground

2 participants