Skip to content

v1.0.4#12

Merged
CSCITech merged 10 commits into
mainfrom
cscitech
Jul 9, 2026
Merged

v1.0.4#12
CSCITech merged 10 commits into
mainfrom
cscitech

Conversation

@CSCITech

@CSCITech CSCITech commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

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

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

README files add governance and build guidance; system-settings site settings merge rankings into header-navigation and redirect the old rankings route. Playground model/group loading moves into shared utilities and a hook, while backend OAuth, token, log, and stream ping flows change authorization, async export, and timeout handling.

Changes

README build documentation updates

Layer / File(s) Summary
Source build guidance across README translations
README.md, README.en.md, README.fr.md, README.ja.md, README.zh_CN.md, README.zh_TW.md
Adds governance/performance wording, source-build requirements, and NOTE blocks about Go module downloads in Dockerfile builds; removes the Star History section from README.md.

Rankings merged into header navigation settings

Layer / File(s) Summary
Header navigation form schema and rankings fields
web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
Extends the form schema, defaults, and access-module fields to include rankings settings derived from rankingsConfig.
Save/reset logic and access-module UI for rankings
web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
Persists rankings settings on save, resets both configs, adds a Rankings access-module entry, and includes rankings in the saving state.
Section registry wiring and route redirect
web/default/src/features/system-settings/site/section-registry.tsx, web/default/src/routes/_authenticated/system-settings/site/$section.tsx
Builds HeaderNavigationSection with both configs and redirects the old rankings route to header-navigation.

Playground option loading and selection flow

Layer / File(s) Summary
Model-group selector and group-aware API
controller/user.go, web/default/src/components/model-group-selector.tsx, web/default/src/features/playground/api.ts, web/default/src/features/playground/components/playground-input.tsx
Makes user-model fetching group-aware and rebuilds the selector into a combined model/group popover or drawer with updated disabled handling.
Playground option hook and shared utilities
web/default/src/features/playground/hooks/*, web/default/src/features/playground/lib/*, web/default/src/features/playground/lib/playground-option-utils.test.ts
Adds shared fallback helpers, exports them through barrels, and introduces a hook that loads groups and models, applies fallback or clearing logic, and reports loading and error state.
Playground component integration
web/default/src/features/playground/index.tsx
Replaces in-component query and synchronization logic with the new hook, and updates the playground input to use the consolidated selector disabled state.

Backend authorization and user-model selection

Layer / File(s) Summary
OAuth provider field updates
controller/oauth.go, controller/oauth_test.go
Maps built-in OAuth providers to specific user-update fields, uses field-specific updates for binding, and tests the provider-to-field mapping.
Token group runtime assignability
controller/token.go, controller/token_test.go
Switches token group checks to runtime assignability and updates add/update token tests for runtime auto-route and unavailable groups.
Group-scoped user model lookup
controller/user.go
Returns enabled models for a requested usable group, or an empty list when the group is unavailable.

Log quota async export and stream ping timeout handling

Layer / File(s) Summary
Retry filter readiness and async quota export
model/log.go
Adds retry-marker backfill readiness errors, centralizes retry-column filtering, and routes quota export through an async enqueue path.
Retry and quota export tests
model/log_test.go
Adds helpers and test cases for retry-backfill readiness and queued quota export behavior, including cache reset and Gin context setup.
Stream ping timeout and stop behavior
relay/helper/stream_scanner.go, relay/helper/stream_scanner_test.go
Refactors stream ping deadline handling to use a timeout wrapper, stops the stream on ping failure, and updates tests for timeout-driven shutdown and serial execution.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • MAX-API-Next/MAX-API#2: Both PRs change model/log_test.go around retry-filter test data and assertions.
  • MAX-API-Next/MAX-API#5: Both PRs overlap on model/log.go retry-marker/backfill readiness logic and retry-log filtering behavior.
  • MAX-API-Next/MAX-API#11: Both PRs modify relay/helper/stream_scanner.go ping/write-deadline handling and related tests.

Poem

A rabbit hopped through docs and code,
Merging ranks along the loading road. 🐇
Go modules hum in source-built light,
Old routes hop onward, tidy and right.
The playground twirls with shared new grace,
While logs and pings keep steady pace.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is just a version label and does not describe the changeset in a meaningful way. Replace it with a concise, specific title that summarizes the main change, such as the primary feature or fix included.
Description check ❓ Inconclusive The description is a template and does not provide concrete change details, but it is still related to the PR. Write a short manual summary of what changed, why it changed, and include any relevant validation or issue links.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cscitech

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (1)
web/default/src/features/system-settings/maintenance/header-navigation-section.tsx (1)

120-392: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Consider splitting this component; it now exceeds the ~200-line guideline.

The file is ~392 lines after this change. The accessModules card rendering (Lines 269-316) is a good candidate for extraction into a shared <AccessModuleCard> sub-component, and form schema/submit wiring could move into a dedicated hook, per the module-organization guideline for this feature directory.

As per coding guidelines, "单文件超过约 200 行时应考虑拆分子组件或抽取自定义 Hooks;类型定义可与组件同文件或放在同模块的 types 中。"

🤖 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/system-settings/maintenance/header-navigation-section.tsx`
around lines 120 - 392, The HeaderNavigationSection component is too large and
should be split to fit the module-organization guideline. Extract the repeated
access-module UI in the accessModules map into a reusable AccessModuleCard
sub-component, and move the form setup/reset/submit wiring from
HeaderNavigationSection into a dedicated hook so the main component only
composes the section. Keep the existing behavior intact while reducing the size
of HeaderNavigationSection and preserving references to
useHeaderNavModulesOption, useRankingsModuleOption, and the form handlers.

Source: Coding guidelines

🤖 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 `@README.en.md`:
- Around line 552-554: The NOTE block in README.en.md includes an empty
blockquote line that triggers docs lint, so remove the blank quoted line between
the NOTE text and the following content. Update the markdown around the NOTE
section only, keeping the existing message intact and ensuring the blockquote
has no empty `>` line.

In `@README.fr.md`:
- Around line 481-483: The NOTE block in README.fr.md contains an empty
blockquote line that triggers MD028, so remove the blank quoted line while
keeping the existing note text intact. Update the markdown near the NOTE content
only, preserving the surrounding explanation about Dockerfile, go.mod/go.sum,
and docker build usage.

In `@README.ja.md`:
- Around line 489-491: The NOTE block in README.ja.md contains an empty
blockquote line that triggers the docs lint rule, so remove the blank quoted
line inside the NOTE content. Update the Markdown in the NOTE section to keep
the text contiguous under the existing blockquote syntax, and verify the
rendered note still reads correctly without any standalone `>` line.

In `@README.md`:
- Around line 554-556: The NOTE block in README has an empty quoted line that
triggers the markdown lint rule for blank blockquotes. Remove the standalone
blank “>” line inside the NOTE section and keep the existing note content in the
same block using the README markdown structure.

In `@README.zh_CN.md`:
- Around line 552-554: The NOTE block in README.zh_CN.md contains a blank
blockquote line that triggers MD028, so remove the empty “>” line while keeping
the existing note text intact. Update the Markdown around the note so the
content is a continuous blockquote without any blank quoted lines, preserving
the wording about Dockerfile, go.mod/go.sum, and the rebuild command.

In `@README.zh_TW.md`:
- Around line 552-554: The README.zh_TW.md NOTE block contains an empty
blockquote line that triggers MD028 and breaks linting. Remove the blank `>`
line inside the NOTE callout and keep the existing content contiguous, using the
NOTE section around the Dockerfile/go.mod guidance as the target for the
cleanup.

In
`@web/default/src/features/system-settings/maintenance/header-navigation-section.tsx`:
- Around line 158-167: Wrap the dual persistence flow in
`updateHeaderNavModules` and `updateRankingsModule` with unified error handling
so failures are surfaced consistently. Add a `try/catch` around the submit
handler in `header-navigation-section.tsx`, and on any rejection call the
existing `handleServerError` and/or `toast.error` path instead of letting one
backend write succeed silently while the other fails. Keep the logic around the
form submit/reset flow (`form`, `toFormValues`, `resetToDefault`) unchanged
except for handling errors and preventing partial-save success states.

---

Outside diff comments:
In
`@web/default/src/features/system-settings/maintenance/header-navigation-section.tsx`:
- Around line 120-392: The HeaderNavigationSection component is too large and
should be split to fit the module-organization guideline. Extract the repeated
access-module UI in the accessModules map into a reusable AccessModuleCard
sub-component, and move the form setup/reset/submit wiring from
HeaderNavigationSection into a dedicated hook so the main component only
composes the section. Keep the existing behavior intact while reducing the size
of HeaderNavigationSection and preserving references to
useHeaderNavModulesOption, useRankingsModuleOption, and the form handlers.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 25898ca8-4d4b-4015-817b-c4d65928a2d4

📥 Commits

Reviewing files that changed from the base of the PR and between 5dca8cf and ed1408c.

📒 Files selected for processing (10)
  • README.en.md
  • README.fr.md
  • README.ja.md
  • README.md
  • README.zh_CN.md
  • README.zh_TW.md
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
  • web/default/src/features/system-settings/maintenance/rankings-visibility-section.tsx
  • web/default/src/features/system-settings/site/section-registry.tsx
  • web/default/src/routes/_authenticated/system-settings/site/$section.tsx
💤 Files with no reviewable changes (1)
  • web/default/src/features/system-settings/maintenance/rankings-visibility-section.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
web/default/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/default/AGENTS.md)

web/default/src/**/*.{ts,tsx}: 前端页面文本与组件内文案必须支持 i18n:React 组件中应使用 useTranslation() 取得 t,并通过 t() 渲染用户可见文本;子组件也应自行使用 useTranslation() 保持独立性。
禁止使用两层及以上嵌套三元表达式;复杂逻辑应改用 if-else、提前返回或抽取函数。
控制函数圈复杂度,复杂逻辑应拆成更小的函数;变量与函数命名应有意义并遵循驼峰等常规命名约定。
TypeScript 代码应避免使用 any,优先使用具体类型或 unknown;参数与返回值应显式标注类型;仅类型用途的导入应使用 import type
修改 TypeScript 或 TSX 代码后必须执行类型检查,并修复所有类型错误,不得遗留。
对象非必要不要解构,尤其是组件 props;优先直接使用 props.xxx 以保持代码清晰。
组件应使用函数式组件与 Hooks,遵循单一职责;组件 props 必须有明确类型(接口或类型别名)。
单文件超过约 200 行时应考虑拆分子组件或抽取自定义 Hooks;类型定义可与组件同文件或放在同模块的 types 中。
在 React 中应合理使用 useMemouseCallbackReact.memo,避免在渲染路径中创建新对象或数组;必要时进行代码分割与动态 import
React Query 的数据获取应使用 useQuery、变更应使用 useMutation;每个查询需配置唯一 queryKey,并在成功后对相关查询执行 invalidateQueries;服务端错误应统一交给 handleServerError
Axios 请求应使用项目统一的 api 实例;GET 请求默认去重,特殊请求可显式关闭;认证与通用错误应在拦截器中统一处理。
服务端错误应统一使用 handleServerError,展示层应使用 toast.error 等统一方式;文案需走 i18n;路由级错误应由 errorComponent 承接;表单错误应通过 form.setError 等方式映射到字段。
样式应以 Tailwind 工具类为主,动态类名使用 cn() 合并;非动态场景避免内联样式;响应式采用移动优先与 Tailwind 断点,主题与暗色模式通过 CSS 变量与 dark: 处理。
应使用语义化 HTML、正确关联 label 与输入、保证键盘可操作与合理焦点顺序;必要时添加 ARIA 属性,装饰性图标应使用 aria-hidden="true"
认证与权限应在路由与接口层校验;前后端都应做数据校验(如 Zod);敏感信息不得落前端存储;避免使用 dangerouslySetInnerHTML;跨域与 Cookie 需配合 withCredentials 并按后端要求处理 CSRF。
组件测试应使用 React Testing Library,关注交互与行为,避免测试实现细节;关键流程可补充集成与 E2E 测试。
环境变量应通过 .env 读取,并使用 VITE_ 前缀;代码中不得硬编码密钥。

Files:

  • web/default/src/routes/_authenticated/system-settings/site/$section.tsx
  • web/default/src/features/system-settings/site/section-registry.tsx
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
web/default/src/routes/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/default/AGENTS.md)

路由应使用 TanStack Router,并通过 createFileRoute 定义;搜索参数应使用 Zod schema + validateSearch 校验;认证与重定向应放在 beforeLoad 中;导航应优先使用 useNavigateLink,避免直接操作 window.location

Files:

  • web/default/src/routes/_authenticated/system-settings/site/$section.tsx
web/default/src/features/**

📄 CodeRabbit inference engine (web/default/AGENTS.md)

功能模块应放在 src/features/<feature>/,并按需包含 components/lib/hooks/api.tstypes.tsconstants.ts 等;通用组件应放在 src/components/,通用工具与类型应放在 src/lib/

Files:

  • web/default/src/features/system-settings/site/section-registry.tsx
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
🪛 LanguageTool
README.fr.md

[typographical] ~416-~416: Caractère d’apostrophe incorrect.
Context: ... de dépendances ou de sécurité, exécuter go mod download, go mod verify, puis reconstruire | ...

(APOS_INCORRECT)


[typographical] ~416-~416: Caractère d’apostrophe incorrect.
Context: ...de sécurité, exécuter go mod download, go mod verify, puis reconstruire | ### Variables d'e...

(APOS_INCORRECT)


[typographical] ~481-~481: Il manque une espace après le point.
Context: ...-t cscitechtop/max-api:latest . ``` > [!NOTE] > Dockerfile télécharge les modules ...

(ESPACE_APRES_POINT)


[typographical] ~482-~482: Caractère d’apostrophe incorrect.
Context: ... go.mod et go.sum ensemble, exécutez go mod download && go mod verify, puis reconstruisez le binaire ou l'ima...

(APOS_INCORRECT)


[typographical] ~482-~482: Une espace est requise.
Context: ...truisez le binaire ou l'image ; utilisez docker build --pull --no-cache -t cscitechtop/max-api:latest . lorsque les images de base doi...

(DEUX_POINTS_ESPACE)


[style] ~482-~482: Cette structure peut être modifiée afin de devenir plus percutante.
Context: ...op/max-api:latest .` lorsque les images de base doivent être rafraîchies. > [!TIP] > L...

(DE_BASE3)

README.zh_CN.md

[typographical] ~479-~479: Caractère d’apostrophe incorrect.
Context: ... 使用仓库 go.mod 声明的 Go 版本(当前 Go 1.25.1+)和 go.sum;依赖或安全更新后运行 go mod download、`go mod ve...

(APOS_INCORRECT)


[typographical] ~479-~479: Caractère d’apostrophe incorrect.
Context: ...o 版本(当前 Go 1.25.1+)和 go.sum;依赖或安全更新后运行 go mod downloadgo mod verify 并重新构建 | ### 推荐环境变量 <d...

(APOS_INCORRECT)


[typographical] ~552-~552: Il manque une espace après le point.
Context: ...-t cscitechtop/max-api:latest . ``` > [!NOTE] > Dockerfile 会在镜像构建中下载 Go 模块。宿主机直接构建...

(ESPACE_APRES_POINT)


[typographical] ~553-~553: Caractère d’apostrophe incorrect.
Context: .../ 安全更新后,请保持 go.modgo.sum 成对提交,先运行 go mod download && go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build ...

(APOS_INCORRECT)


[typographical] ~553-~553: Une espace est requise.
Context: ... go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 docker build --pull --no-cache -t cscitechtop/max-api:latest .`。 > [!TIP] > 前端使用 Bun workspac...

(DEUX_POINTS_ESPACE)

README.zh_TW.md

[uncategorized] ~553-~553: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...go mod download && go mod verify,再重新構建二進制或鏡像;需要刷新基礎鏡像時可使用 `docker build --pull -...

(wa5)

README.md

[typographical] ~481-~481: Caractère d’apostrophe incorrect.
Context: ... 使用仓库 go.mod 声明的 Go 版本(当前 Go 1.25.1+)和 go.sum;依赖或安全更新后运行 go mod download、`go mod ve...

(APOS_INCORRECT)


[typographical] ~481-~481: Caractère d’apostrophe incorrect.
Context: ...o 版本(当前 Go 1.25.1+)和 go.sum;依赖或安全更新后运行 go mod downloadgo mod verify 并重新构建 | ### 推荐环境变量 <d...

(APOS_INCORRECT)


[typographical] ~554-~554: Il manque une espace après le point.
Context: ...-t cscitechtop/max-api:latest . ``` > [!NOTE] > Dockerfile 会在镜像构建中下载 Go 模块。宿主机直接构建...

(ESPACE_APRES_POINT)


[typographical] ~555-~555: Caractère d’apostrophe incorrect.
Context: .../ 安全更新后,请保持 go.modgo.sum 成对提交,先运行 go mod download && go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build ...

(APOS_INCORRECT)


[typographical] ~555-~555: Une espace est requise.
Context: ... go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 docker build --pull --no-cache -t cscitechtop/max-api:latest .`。 > [!TIP] > 前端使用 Bun workspac...

(DEUX_POINTS_ESPACE)

🪛 markdownlint-cli2 (0.22.1)
README.fr.md

[warning] 483-483: Blank line inside blockquote

(MD028, no-blanks-blockquote)

README.ja.md

[warning] 491-491: Blank line inside blockquote

(MD028, no-blanks-blockquote)

README.zh_CN.md

[warning] 554-554: Blank line inside blockquote

(MD028, no-blanks-blockquote)

README.en.md

[warning] 554-554: Blank line inside blockquote

(MD028, no-blanks-blockquote)

README.zh_TW.md

[warning] 554-554: Blank line inside blockquote

(MD028, no-blanks-blockquote)

README.md

[warning] 556-556: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🔇 Additional comments (13)
README.en.md (1)

479-479: LGTM!

README.md (1)

479-479: LGTM!

README.fr.md (1)

416-416: LGTM!

README.ja.md (1)

416-416: LGTM!

README.zh_CN.md (1)

479-479: LGTM!

README.zh_TW.md (1)

479-479: LGTM!

web/default/src/features/system-settings/maintenance/header-navigation-section.tsx (4)

45-65: LGTM!


69-118: LGTM!


197-230: LGTM!


239-239: LGTM!

web/default/src/features/system-settings/site/section-registry.tsx (2)

28-28: LGTM!


64-79: LGTM! The rankingsConfig derivation correctly mirrors useRankingsModuleOption's fallback logic using the shared parseHeaderNavAccessModule/parseHeaderNavModules helpers.

web/default/src/routes/_authenticated/system-settings/site/$section.tsx (1)

29-36: LGTM! Redirect is correctly placed in beforeLoad and targets a valid registered section id.

Comment thread README.en.md
Comment on lines +552 to +554
> [!NOTE]
> `Dockerfile` downloads Go modules during the image build. For host builds or dependency/security updates, keep `go.mod` and `go.sum` committed together, run `go mod download && go mod verify`, then rebuild the binary or image; use `docker build --pull --no-cache -t cscitechtop/max-api:latest .` when base images need to be refreshed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the empty quoted line in the NOTE block.

The blank > line trips MD028 (no-blanks-blockquote) and will fail docs lint.

Suggested fix
 > [!NOTE]
->
 > `Dockerfile` downloads Go modules during the image build. For host builds or dependency/security updates, keep `go.mod` and `go.sum` committed together, run `go mod download && go mod verify`, then rebuild the binary or image; use `docker build --pull --no-cache -t cscitechtop/max-api:latest .` when base images need to be refreshed.
📝 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
> [!NOTE]
> `Dockerfile` downloads Go modules during the image build. For host builds or dependency/security updates, keep `go.mod` and `go.sum` committed together, run `go mod download && go mod verify`, then rebuild the binary or image; use `docker build --pull --no-cache -t cscitechtop/max-api:latest .` when base images need to be refreshed.
> [!NOTE]
> `Dockerfile` downloads Go modules during the image build. For host builds or dependency/security updates, keep `go.mod` and `go.sum` committed together, run `go mod download && go mod verify`, then rebuild the binary or image; use `docker build --pull --no-cache -t cscitechtop/max-api:latest .` when base images need to be refreshed.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 554-554: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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 `@README.en.md` around lines 552 - 554, The NOTE block in README.en.md includes
an empty blockquote line that triggers docs lint, so remove the blank quoted
line between the NOTE text and the following content. Update the markdown around
the NOTE section only, keeping the existing message intact and ensuring the
blockquote has no empty `>` line.

Source: Linters/SAST tools

Comment thread README.fr.md
Comment on lines +481 to +483
> [!NOTE]
> `Dockerfile` télécharge les modules Go pendant la construction de l'image. Pour une construction locale ou après une mise à jour de dépendances / sécurité, conservez `go.mod` et `go.sum` ensemble, exécutez `go mod download && go mod verify`, puis reconstruisez le binaire ou l'image ; utilisez `docker build --pull --no-cache -t cscitechtop/max-api:latest .` lorsque les images de base doivent être rafraîchies.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Supprimez la ligne vide citée dans le bloc NOTE.

La ligne > vide déclenche MD028 (no-blanks-blockquote) et fera échouer le lint des docs.

Correctif suggéré
 > [!NOTE]
->
 > `Dockerfile` télécharge les modules Go pendant la construction de l'image. Pour une construction locale ou après une mise à jour de dépendances / sécurité, conservez `go.mod` et `go.sum` ensemble, exécutez `go mod download && go mod verify`, puis reconstruisez le binaire ou l'image ; utilisez `docker build --pull --no-cache -t cscitechtop/max-api:latest .` lorsque les images de base doivent être rafraîchies.
📝 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
> [!NOTE]
> `Dockerfile` télécharge les modules Go pendant la construction de l'image. Pour une construction locale ou après une mise à jour de dépendances / sécurité, conservez `go.mod` et `go.sum` ensemble, exécutez `go mod download && go mod verify`, puis reconstruisez le binaire ou l'image ; utilisez `docker build --pull --no-cache -t cscitechtop/max-api:latest .` lorsque les images de base doivent être rafraîchies.
> [!NOTE]
> `Dockerfile` télécharge les modules Go pendant la construction de l'image. Pour une construction locale ou après une mise à jour de dépendances / sécurité, conservez `go.mod` et `go.sum` ensemble, exécutez `go mod download && go mod verify`, puis reconstruisez le binaire ou l'image ; utilisez `docker build --pull --no-cache -t cscitechtop/max-api:latest .` lorsque les images de base doivent être rafraîchies.
🧰 Tools
🪛 LanguageTool

[typographical] ~481-~481: Il manque une espace après le point.
Context: ...-t cscitechtop/max-api:latest . ``` > [!NOTE] > Dockerfile télécharge les modules ...

(ESPACE_APRES_POINT)


[typographical] ~482-~482: Caractère d’apostrophe incorrect.
Context: ... go.mod et go.sum ensemble, exécutez go mod download && go mod verify, puis reconstruisez le binaire ou l'ima...

(APOS_INCORRECT)


[typographical] ~482-~482: Une espace est requise.
Context: ...truisez le binaire ou l'image ; utilisez docker build --pull --no-cache -t cscitechtop/max-api:latest . lorsque les images de base doi...

(DEUX_POINTS_ESPACE)


[style] ~482-~482: Cette structure peut être modifiée afin de devenir plus percutante.
Context: ...op/max-api:latest .` lorsque les images de base doivent être rafraîchies. > [!TIP] > L...

(DE_BASE3)

🪛 markdownlint-cli2 (0.22.1)

[warning] 483-483: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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 `@README.fr.md` around lines 481 - 483, The NOTE block in README.fr.md contains
an empty blockquote line that triggers MD028, so remove the blank quoted line
while keeping the existing note text intact. Update the markdown near the NOTE
content only, preserving the surrounding explanation about Dockerfile,
go.mod/go.sum, and docker build usage.

Source: Linters/SAST tools

Comment thread README.ja.md
Comment on lines +489 to +491
> [!NOTE]
> `Dockerfile` はイメージビルド中に Go モジュールをダウンロードします。ホストで直接ビルドする場合、または依存関係 / セキュリティ更新後は、`go.mod` と `go.sum` を必ず一緒にコミットし、`go mod download && go mod verify` を実行してからバイナリまたはイメージを再ビルドしてください。ベースイメージを更新する必要がある場合は `docker build --pull --no-cache -t cscitechtop/max-api:latest .` を使用します。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

NOTE ブロック内の空の引用行を हटしてください。

空の > 行が MD028 (no-blanks-blockquote) に引っかかり、docs lint が失敗します。

修正案
 > [!NOTE]
->
 > `Dockerfile` はイメージビルド中に Go モジュールをダウンロードします。ホストで直接ビルドする場合、または依存関係 / セキュリティ更新後は、`go.mod` と `go.sum` を必ず一緒にコミットし、`go mod download && go mod verify` を実行してからバイナリまたはイメージを再ビルドしてください。ベースイメージを更新する必要がある場合は `docker build --pull --no-cache -t cscitechtop/max-api:latest .` を使用します。
📝 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
> [!NOTE]
> `Dockerfile` はイメージビルド中に Go モジュールをダウンロードします。ホストで直接ビルドする場合、または依存関係 / セキュリティ更新後は、`go.mod``go.sum` を必ず一緒にコミットし、`go mod download && go mod verify` を実行してからバイナリまたはイメージを再ビルドしてください。ベースイメージを更新する必要がある場合は `docker build --pull --no-cache -t cscitechtop/max-api:latest .` を使用します。
> [!NOTE]
> `Dockerfile` はイメージビルド中に Go モジュールをダウンロードします。ホストで直接ビルドする場合、または依存関係 / セキュリティ更新後は、`go.mod``go.sum` を必ず一緒にコミットし、`go mod download && go mod verify` を実行してからバイナリまたはイメージを再ビルドしてください。ベースイメージを更新する必要がある場合は `docker build --pull --no-cache -t cscitechtop/max-api:latest .` を使用します。
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 491-491: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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 `@README.ja.md` around lines 489 - 491, The NOTE block in README.ja.md contains
an empty blockquote line that triggers the docs lint rule, so remove the blank
quoted line inside the NOTE content. Update the Markdown in the NOTE section to
keep the text contiguous under the existing blockquote syntax, and verify the
rendered note still reads correctly without any standalone `>` line.

Source: Linters/SAST tools

Comment thread README.md
Comment on lines +554 to +556
> [!NOTE]
> `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod` 与 `go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the empty quoted line in the NOTE block.

The blank > line trips MD028 (no-blanks-blockquote) and will fail docs lint.

Suggested fix
 > [!NOTE]
->
 > `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod` 与 `go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`。
📝 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
> [!NOTE]
> `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod``go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`
> [!NOTE]
> `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod``go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`
🧰 Tools
🪛 LanguageTool

[typographical] ~554-~554: Il manque une espace après le point.
Context: ...-t cscitechtop/max-api:latest . ``` > [!NOTE] > Dockerfile 会在镜像构建中下载 Go 模块。宿主机直接构建...

(ESPACE_APRES_POINT)


[typographical] ~555-~555: Caractère d’apostrophe incorrect.
Context: .../ 安全更新后,请保持 go.modgo.sum 成对提交,先运行 go mod download && go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build ...

(APOS_INCORRECT)


[typographical] ~555-~555: Une espace est requise.
Context: ... go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 docker build --pull --no-cache -t cscitechtop/max-api:latest .`。 > [!TIP] > 前端使用 Bun workspac...

(DEUX_POINTS_ESPACE)

🪛 markdownlint-cli2 (0.22.1)

[warning] 556-556: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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 `@README.md` around lines 554 - 556, The NOTE block in README has an empty
quoted line that triggers the markdown lint rule for blank blockquotes. Remove
the standalone blank “>” line inside the NOTE section and keep the existing note
content in the same block using the README markdown structure.

Source: Linters/SAST tools

Comment thread README.zh_CN.md
Comment on lines +552 to +554
> [!NOTE]
> `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod` 与 `go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

删除 NOTE 块里的空引用行。

空的 > 行会触发 MD028(no-blanks-blockquote),导致文档 lint 失败。

建议修复
 > [!NOTE]
->
 > `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod` 与 `go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`。
📝 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
> [!NOTE]
> `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod``go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`
> [!NOTE]
> `Dockerfile` 会在镜像构建中下载 Go 模块。宿主机直接构建或依赖 / 安全更新后,请保持 `go.mod``go.sum` 成对提交,先运行 `go mod download && go mod verify`,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`
🧰 Tools
🪛 LanguageTool

[typographical] ~552-~552: Il manque une espace après le point.
Context: ...-t cscitechtop/max-api:latest . ``` > [!NOTE] > Dockerfile 会在镜像构建中下载 Go 模块。宿主机直接构建...

(ESPACE_APRES_POINT)


[typographical] ~553-~553: Caractère d’apostrophe incorrect.
Context: .../ 安全更新后,请保持 go.modgo.sum 成对提交,先运行 go mod download && go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 `docker build ...

(APOS_INCORRECT)


[typographical] ~553-~553: Une espace est requise.
Context: ... go mod verify,再重新构建二进制或镜像;需要刷新基础镜像时可使用 docker build --pull --no-cache -t cscitechtop/max-api:latest .`。 > [!TIP] > 前端使用 Bun workspac...

(DEUX_POINTS_ESPACE)

🪛 markdownlint-cli2 (0.22.1)

[warning] 554-554: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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 `@README.zh_CN.md` around lines 552 - 554, The NOTE block in README.zh_CN.md
contains a blank blockquote line that triggers MD028, so remove the empty “>”
line while keeping the existing note text intact. Update the Markdown around the
note so the content is a continuous blockquote without any blank quoted lines,
preserving the wording about Dockerfile, go.mod/go.sum, and the rebuild command.

Source: Linters/SAST tools

Comment thread README.zh_TW.md
Comment on lines +552 to +554
> [!NOTE]
> `Dockerfile` 會在鏡像構建中下載 Go 模塊。宿主機直接構建或依賴 / 安全更新後,請保持 `go.mod` 與 `go.sum` 成對提交,先運行 `go mod download && go mod verify`,再重新構建二進制或鏡像;需要刷新基礎鏡像時可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

移除 NOTE 區塊中的空引用行。

空的 > 行會觸發 MD028(no-blanks-blockquote),讓文件 lint 失敗。

建議修正
 > [!NOTE]
->
 > `Dockerfile` 會在鏡像構建中下載 Go 模塊。宿主機直接構建或依賴 / 安全更新後,請保持 `go.mod` 與 `go.sum` 成對提交,先運行 `go mod download && go mod verify`,再重新構建二進制或鏡像;需要刷新基礎鏡像時可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`。
📝 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
> [!NOTE]
> `Dockerfile` 會在鏡像構建中下載 Go 模塊。宿主機直接構建或依賴 / 安全更新後,請保持 `go.mod``go.sum` 成對提交,先運行 `go mod download && go mod verify`,再重新構建二進制或鏡像;需要刷新基礎鏡像時可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`
> [!NOTE]
> `Dockerfile` 會在鏡像構建中下載 Go 模塊。宿主機直接構建或依賴 / 安全更新後,請保持 `go.mod``go.sum` 成對提交,先運行 `go mod download && go mod verify`,再重新構建二進制或鏡像;需要刷新基礎鏡像時可使用 `docker build --pull --no-cache -t cscitechtop/max-api:latest .`
🧰 Tools
🪛 LanguageTool

[uncategorized] ~553-~553: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...go mod download && go mod verify,再重新構建二進制或鏡像;需要刷新基礎鏡像時可使用 `docker build --pull -...

(wa5)

🪛 markdownlint-cli2 (0.22.1)

[warning] 554-554: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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 `@README.zh_TW.md` around lines 552 - 554, The README.zh_TW.md NOTE block
contains an empty blockquote line that triggers MD028 and breaks linting. Remove
the blank `>` line inside the NOTE callout and keep the existing content
contiguous, using the NOTE section around the Dockerfile/go.mod guidance as the
target for the cleanup.

Source: Linters/SAST tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@web/default/src/features/playground/lib/playground-option-utils.test.ts`:
- Around line 19-69: Add unit coverage in playground-option-utils.test.ts for
the exported getOptionLoadErrorMessage helper and the empty-string currentModel
branch in shouldClearModelForGroup. Use the existing playground-option-utils
test suite to verify getOptionLoadErrorMessage returns the expected message for
the relevant inputs, and add a case where shouldClearModelForGroup receives an
empty currentModel and returns true. Keep the tests grouped with the other
assertions for getModelFallback, getGroupFallback, and shouldClearModelForGroup
so the behavior of each utility is covered by name.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: dbb3cf0e-9ed0-4607-82df-6560e280d52e

📥 Commits

Reviewing files that changed from the base of the PR and between ed1408c and fc164ab.

📒 Files selected for processing (17)
  • README.en.md
  • README.fr.md
  • README.ja.md
  • README.md
  • README.zh_CN.md
  • README.zh_TW.md
  • controller/user.go
  • web/default/src/components/model-group-selector.tsx
  • web/default/src/features/playground/api.ts
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/hooks/index.ts
  • web/default/src/features/playground/hooks/use-playground-options.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/lib/index.ts
  • web/default/src/features/playground/lib/playground-option-utils.test.ts
  • web/default/src/features/playground/lib/playground-option-utils.ts
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
web/default/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/default/AGENTS.md)

web/default/src/**/*.{ts,tsx}: 前端页面文本与组件内文案必须支持 i18n:React 组件中应使用 useTranslation() 取得 t,并通过 t() 渲染用户可见文本;子组件也应自行使用 useTranslation() 保持独立性。
禁止使用两层及以上嵌套三元表达式;复杂逻辑应改用 if-else、提前返回或抽取函数。
控制函数圈复杂度,复杂逻辑应拆成更小的函数;变量与函数命名应有意义并遵循驼峰等常规命名约定。
TypeScript 代码应避免使用 any,优先使用具体类型或 unknown;参数与返回值应显式标注类型;仅类型用途的导入应使用 import type
修改 TypeScript 或 TSX 代码后必须执行类型检查,并修复所有类型错误,不得遗留。
对象非必要不要解构,尤其是组件 props;优先直接使用 props.xxx 以保持代码清晰。
组件应使用函数式组件与 Hooks,遵循单一职责;组件 props 必须有明确类型(接口或类型别名)。
单文件超过约 200 行时应考虑拆分子组件或抽取自定义 Hooks;类型定义可与组件同文件或放在同模块的 types 中。
在 React 中应合理使用 useMemouseCallbackReact.memo,避免在渲染路径中创建新对象或数组;必要时进行代码分割与动态 import
React Query 的数据获取应使用 useQuery、变更应使用 useMutation;每个查询需配置唯一 queryKey,并在成功后对相关查询执行 invalidateQueries;服务端错误应统一交给 handleServerError
Axios 请求应使用项目统一的 api 实例;GET 请求默认去重,特殊请求可显式关闭;认证与通用错误应在拦截器中统一处理。
服务端错误应统一使用 handleServerError,展示层应使用 toast.error 等统一方式;文案需走 i18n;路由级错误应由 errorComponent 承接;表单错误应通过 form.setError 等方式映射到字段。
样式应以 Tailwind 工具类为主,动态类名使用 cn() 合并;非动态场景避免内联样式;响应式采用移动优先与 Tailwind 断点,主题与暗色模式通过 CSS 变量与 dark: 处理。
应使用语义化 HTML、正确关联 label 与输入、保证键盘可操作与合理焦点顺序;必要时添加 ARIA 属性,装饰性图标应使用 aria-hidden="true"
认证与权限应在路由与接口层校验;前后端都应做数据校验(如 Zod);敏感信息不得落前端存储;避免使用 dangerouslySetInnerHTML;跨域与 Cookie 需配合 withCredentials 并按后端要求处理 CSRF。
组件测试应使用 React Testing Library,关注交互与行为,避免测试实现细节;关键流程可补充集成与 E2E 测试。
环境变量应通过 .env 读取,并使用 VITE_ 前缀;代码中不得硬编码密钥。

Files:

  • web/default/src/features/playground/hooks/index.ts
  • web/default/src/features/playground/lib/index.ts
  • web/default/src/features/playground/lib/playground-option-utils.test.ts
  • web/default/src/features/playground/lib/playground-option-utils.ts
  • web/default/src/features/playground/hooks/use-playground-options.ts
  • web/default/src/features/playground/api.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/components/model-group-selector.tsx
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
web/default/src/features/**

📄 CodeRabbit inference engine (web/default/AGENTS.md)

功能模块应放在 src/features/<feature>/,并按需包含 components/lib/hooks/api.tstypes.tsconstants.ts 等;通用组件应放在 src/components/,通用工具与类型应放在 src/lib/

Files:

  • web/default/src/features/playground/hooks/index.ts
  • web/default/src/features/playground/lib/index.ts
  • web/default/src/features/playground/lib/playground-option-utils.test.ts
  • web/default/src/features/playground/lib/playground-option-utils.ts
  • web/default/src/features/playground/hooks/use-playground-options.ts
  • web/default/src/features/playground/api.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
web/default/src/features/**/lib/**/*.ts

📄 CodeRabbit inference engine (web/default/AGENTS.md)

表单应使用 React Hook Form + Zod:在功能模块的 lib/ 下定义 schema,并用 z.infer 导出表单类型;useForm 应配合 @hookform/resolvers/zod 进行校验。

Files:

  • web/default/src/features/playground/lib/index.ts
  • web/default/src/features/playground/lib/playground-option-utils.test.ts
  • web/default/src/features/playground/lib/playground-option-utils.ts
web/default/src/**/*.test.ts

📄 CodeRabbit inference engine (web/default/AGENTS.md)

工具函数与纯逻辑应优先编写单元测试;测试文件应命名为 *.test.ts

Files:

  • web/default/src/features/playground/lib/playground-option-utils.test.ts
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: In Go business code, all JSON marshal/unmarshal operations must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) and must not directly call encoding/json for actual encode/decode work.
All database code must be compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+; prefer GORM abstractions over raw SQL, avoid direct AUTO_INCREMENT/SERIAL, use commonGroupCol/commonKeyCol and commonTrueVal/commonFalseVal for DB-specific SQL, branch with common.UsingPostgreSQL/common.UsingSQLite/common.UsingMySQL, avoid unsupported DB-specific functions/operators without fallback, and make migrations work across all three databases.
When implementing a new relay channel, confirm whether the provider supports StreamOptions; if it does, add that channel to streamSupportedChannels.
For request structs parsed from client JSON and re-marshaled to upstream providers, optional scalar fields must use pointer types with omitempty so explicit zero/false values are preserved instead of dropped.
When working on tiered/dynamic billing expression code, read pkg/billingexpr/expr.md first and follow its documented expression language, architecture, token normalization, quota conversion, and versioning patterns.

**/*.go: All JSON marshal/unmarshal operations in Go business code must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) instead of directly importing or calling encoding/json for actual marshal/unmarshal work.
All database code in Go must remain compatible with SQLite, MySQL >= 5.7.8, and PostgreSQL >= 9.6; prefer GORM abstractions, avoid raw SQL unless necessary, use the shared DB helper variables for reserved words and boolean literals, branch with the common.UsingPostgreSQL / common.UsingSQLite / common.UsingMySQL flags when need...

Files:

  • controller/user.go
🪛 LanguageTool
README.zh_TW.md

[uncategorized] ~55-~55: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...發器,而是面向 AI-ready 應用和 Agent 工作負載的可營運網關:在統一模型協議與供應商差異的同時,把突發流量、長流式響應、大請求體、多節點緩存、成本審計和...

(wa5)

README.fr.md

[style] ~47-~47: Cette locution, généralement suivie par « mais aussi », peut être allégée afin d’améliorer la lisibilité de votre texte.
Context: ...de modèles. En pratique, MAX API n'est pas seulement un proxy de requêtes. C'est une passere...

(NON_SEULEMENT)


[typographical] ~47-~47: Le préfixe « multi » est généralement associé au terme qu’il précède.
Context: ...streaming, gros corps de requête, cache multi-nœud, audit des coûts et observabilité des p...

(PAS_DE_TRAIT_UNION)


[typographical] ~80-~80: Le préfixe « multi » est généralement associé au terme qu’il précède.
Context: ... gracieux pour les déploiements mono ou multi-nœuds. - **Couche d'exploitation et d'audit o...

(PAS_DE_TRAIT_UNION)


[typographical] ~197-~197: Le préfixe « multi » est généralement associé au terme qu’il précède.
Context: ... | |------|------| | Cache et extension multi-nœud | Déploiement mono-nœud avec cache mémo...

(PAS_DE_TRAIT_UNION)


[typographical] ~197-~197: Le préfixe « multi » est généralement associé au terme qu’il précède.
Context: ...ploiement mono-nœud avec cache mémoire, multi-nœud avec Redis ; les caches utilisateur, je...

(PAS_DE_TRAIT_UNION)


[typographical] ~197-~197: Caractère d’apostrophe incorrect.
Context: ...es lectures répétées en base, tandis que SESSION_SECRET, CRYPTO_SECRET et NODE_NAME gardent...

(APOS_INCORRECT)


[typographical] ~199-~199: Caractère d’apostrophe incorrect.
Context: ...oire | | Streaming et grandes requêtes | STREAMING_TIMEOUT, STREAM_SCANNER_MAX_BUFFER_MB, `MAX_R...

(APOS_INCORRECT)


[typographical] ~199-~199: Caractère d’apostrophe incorrect.
Context: ... grandes requêtes | STREAMING_TIMEOUT, STREAM_SCANNER_MAX_BUFFER_MB, MAX_REQUEST_BODY_MB, `MAX_FILE_DOWNL...

(APOS_INCORRECT)


[typographical] ~199-~199: Caractère d’apostrophe incorrect.
Context: ...IMEOUT, STREAM_SCANNER_MAX_BUFFER_MB, MAX_REQUEST_BODY_MB, MAX_FILE_DOWNLOAD_MB` contrôlent long...

(APOS_INCORRECT)


[typographical] ~200-~200: Caractère d’apostrophe incorrect.
Context: ...ants | | Réglage des connexions relais | RELAY_TIMEOUT, RELAY_IDLE_CONN_TIMEOUT, `RELAY_MAX_...

(APOS_INCORRECT)


[typographical] ~200-~200: Caractère d’apostrophe incorrect.
Context: ...des connexions relais | RELAY_TIMEOUT, RELAY_IDLE_CONN_TIMEOUT, RELAY_MAX_IDLE_CONNS et `RELAY_MAX_I...

(APOS_INCORRECT)


[style] ~222-~222: Ce verbe peut être considéré comme familier dans un contexte formel.
Context: ...erformance et extension | L'application gère timeouts, limites, pools de connexions ...

(VERBES_FAMILIERS_PREMIUM)

README.en.md

[grammar] ~201-~201: Ensure spelling is correct
Context: ...ments. ### Performance and Scalability Governance | Capability | Description | |------|---...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (21)
README.en.md (1)

55-56: LGTM!

Also applies to: 88-88, 201-211, 230-230, 494-494, 567-569

README.fr.md (1)

47-48: LGTM!

Also applies to: 80-80, 193-203, 222-222, 431-431, 496-498

README.ja.md (1)

47-48: LGTM!

Also applies to: 80-80, 193-203, 222-222, 431-431, 496-498

README.md (1)

55-56: LGTM!

Also applies to: 88-88, 201-211, 230-230, 494-494, 567-569, 717-718

README.zh_CN.md (1)

55-56: LGTM!

Also applies to: 88-88, 201-211, 230-230, 494-494, 567-569

README.zh_TW.md (1)

55-56: LGTM!

Also applies to: 88-88, 201-211, 230-230, 494-494, 567-569

web/default/src/features/system-settings/maintenance/header-navigation-section.tsx (3)

35-35: Prior critical issue (partial-save on dual persistence) correctly resolved.

The try/catch wrapping Promise.all for updateHeaderNavModules and updateRankingsModule, with handleServerError on failure, correctly addresses the previously flagged partial-save/unhandled-rejection issue. This matches RHF's documented guidance that handleSubmit won't swallow onSubmit errors, so wrapping async calls in try/catch is the right approach.

Also applies to: 140-170


204-237: LGTM!

Also applies to: 246-246


121-131: LGTM!

controller/user.go (1)

612-629: LGTM!

web/default/src/components/model-group-selector.tsx (2)

579-773: LGTM!


711-728: 🎯 Functional Correctness

cmdk 1.1.1 does not lowercase onSelect values, so this handler is fine. The callback receives the item’s case-sensitive value, so handleModelChange(model.value) is not needed here.

			> Likely an incorrect or invalid review comment.
web/default/src/features/playground/api.ts (1)

43-46: LGTM!

web/default/src/features/playground/components/playground-input.tsx (1)

107-107: LGTM!

Also applies to: 232-232

web/default/src/features/playground/index.tsx (1)

59-73: LGTM!

web/default/src/features/playground/lib/playground-option-utils.ts (2)

60-65: Note: if use-playground-options.ts is updated to route errors through the project's centralized handleServerError (see comment on that file), this helper's manual message extraction may become redundant.


21-58: LGTM on getModelFallback/getGroupFallback — logic matches the tests and correctly guards against empty lists before indexing models[0]/groups[0].

web/default/src/features/playground/hooks/index.ts (1)

23-23: LGTM!

web/default/src/features/playground/hooks/use-playground-options.ts (2)

43-49: LGTM on the hook's fallback/clearing wiring itself — the group→model reset effect (Line 94-96), fallback effects (Line 98-123) and derived return (Line 125-128) are logically consistent with playground-option-utils.ts and don't risk infinite update loops (fallback values are always chosen from the freshly fetched list, so a subsequent render finds a match and stops updating).


72-92: 🗄️ Data Integrity & Integration

No change needed The playground option loaders intentionally build a specific fallback message before calling toast.error; handleServerError doesn’t accept a custom context message, so routing these effects through it would lose the groups/models-specific text.

			> Likely an incorrect or invalid review comment.
web/default/src/features/playground/lib/index.ts (1)

23-23: LGTM!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
controller/oauth.go (1)

122-136: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle the raw email-collision sentinel here
findOrCreateOAuthUser can still return model.ErrEmailAlreadyTaken directly from the insert path if the email becomes unavailable between the precheck and the transaction. That bypasses the *OAuthEmailAlreadyTakenError case and falls back to the generic error response. Add an errors.Is(err, model.ErrEmailAlreadyTaken) branch here, or wrap that sentinel before returning.

🤖 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 `@controller/oauth.go` around lines 122 - 136, The OAuth user error handling in
the findOrCreateOAuthUser flow is missing the raw email-collision sentinel, so
model.ErrEmailAlreadyTaken can fall through to the generic ApiError path. Update
the error switch in the OAuth callback handler to recognize errors.Is(err,
model.ErrEmailAlreadyTaken) alongside the existing *OAuthEmailAlreadyTakenError
case, or ensure findOrCreateOAuthUser wraps that sentinel consistently before
returning, so the user gets the email-already-taken response instead of a
generic failure.
🤖 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 `@model/log.go`:
- Around line 191-199: Keep quota-data enqueue flush-safe by ensuring
enqueueLogQuotaData does not defer the final LogQuotaData write past shutdown.
Update the logic around logQuotaDataAsyncRunner and enqueueLogQuotaData so
quota_data is persisted synchronously or otherwise guaranteed to run before the
flush/exit path completes, and make sure the final quota increments can’t be
dropped on shutdown.

In `@relay/helper/stream_scanner.go`:
- Around line 60-74: The timeout handling in pingDataWithTimeout can return
while streamPingData is still writing, which leaves the writer lock effectively
uncoordinated and allows concurrent writes to c.Writer. Update
pingDataWithTimeout/streamPingData so the ping write stays fully synchronized
until completion, or ensure the goroutine cannot continue touching the response
writer after a timeout. Use the existing pingDataWithTimeout and streamPingData
symbols to keep the critical section around the SSE write intact.

---

Outside diff comments:
In `@controller/oauth.go`:
- Around line 122-136: The OAuth user error handling in the
findOrCreateOAuthUser flow is missing the raw email-collision sentinel, so
model.ErrEmailAlreadyTaken can fall through to the generic ApiError path. Update
the error switch in the OAuth callback handler to recognize errors.Is(err,
model.ErrEmailAlreadyTaken) alongside the existing *OAuthEmailAlreadyTakenError
case, or ensure findOrCreateOAuthUser wraps that sentinel consistently before
returning, so the user gets the email-already-taken response instead of a
generic failure.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 9d311ad8-e2ad-4ad6-a59f-cfbede66871d

📥 Commits

Reviewing files that changed from the base of the PR and between 0348806 and 2475c83.

📒 Files selected for processing (8)
  • controller/oauth.go
  • controller/oauth_test.go
  • controller/token.go
  • controller/token_test.go
  • model/log.go
  • model/log_test.go
  • relay/helper/stream_scanner.go
  • relay/helper/stream_scanner_test.go
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: In Go business code, all JSON marshal/unmarshal operations must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) and must not directly call encoding/json for actual encode/decode work.
All database code must be compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+; prefer GORM abstractions over raw SQL, avoid direct AUTO_INCREMENT/SERIAL, use commonGroupCol/commonKeyCol and commonTrueVal/commonFalseVal for DB-specific SQL, branch with common.UsingPostgreSQL/common.UsingSQLite/common.UsingMySQL, avoid unsupported DB-specific functions/operators without fallback, and make migrations work across all three databases.
When implementing a new relay channel, confirm whether the provider supports StreamOptions; if it does, add that channel to streamSupportedChannels.
For request structs parsed from client JSON and re-marshaled to upstream providers, optional scalar fields must use pointer types with omitempty so explicit zero/false values are preserved instead of dropped.
When working on tiered/dynamic billing expression code, read pkg/billingexpr/expr.md first and follow its documented expression language, architecture, token normalization, quota conversion, and versioning patterns.

**/*.go: All JSON marshal/unmarshal operations in Go business code must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) instead of directly importing or calling encoding/json for actual marshal/unmarshal work.
All database code in Go must remain compatible with SQLite, MySQL >= 5.7.8, and PostgreSQL >= 9.6; prefer GORM abstractions, avoid raw SQL unless necessary, use the shared DB helper variables for reserved words and boolean literals, branch with the common.UsingPostgreSQL / common.UsingSQLite / common.UsingMySQL flags when need...

Files:

  • controller/token.go
  • controller/oauth_test.go
  • relay/helper/stream_scanner.go
  • controller/oauth.go
  • controller/token_test.go
  • relay/helper/stream_scanner_test.go
  • model/log.go
  • model/log_test.go
🔇 Additional comments (13)
controller/oauth.go (2)

23-37: Clean provider-to-field mapping.

Straightforward switch mapping each built-in provider type to its model.UserUpdateField; matches the corresponding fields in model/user.go (UserUpdateFieldGitHubId, UserUpdateFieldDiscordId, UserUpdateFieldOidcId, UserUpdateFieldLinuxDOId).


194-209: 🎯 Functional Correctness

No additional built-in OAuth providers need handling here. The built-in set is limited to GitHub, Discord, OIDC, and Linux DO, and each maps to a field in oauthProviderUserUpdateField; the new unsupported-provider error path should not be reachable for current built-ins.

			> Likely an incorrect or invalid review comment.
controller/oauth_test.go (1)

10-33: LGTM!

controller/token.go (1)

35-49: Runtime-permission check swap looks correct.

Swapping CanUseTokenGroup for CanUseTokenGroupRuntime (which calls canUseTokenGroup(..., runtime-enabled=false) per service/group.go:51-53) aligns with the PR's goal of allowing runtime auto-route assignment while keeping the rest of the validation (trimming, fallback to user_group, error response) unchanged.

controller/token_test.go (4)

525-560: Test correctly validates the new runtime auto-route success path and persisted group.

Confirms AddToken now succeeds for a hidden/non-user-selectable auto route and persists Group == "auto:internal".


553-556: 📐 Maintainability & Code Quality | 💤 Low value

Fragile assumption: db.First(&stored) without a filter.

Relies on exactly one token row existing in the test DB at this point (no WHERE clause). If setupTokenControllerTestDB is ever shared/reused across cases or a prior insert leaks in, this would silently fetch the wrong row instead of failing clearly. Consider filtering by name or the just-known key.


562-602: Good negative-path coverage for unavailable group.

TestAddTokenRejectsUnavailableGroup correctly asserts failure, message content, and that no token row was persisted.


640-718: Update-path tests mirror the Add-path coverage well.

Success case reloads and checks persisted Group; failure case confirms the token's group remains unchanged ("default") after a rejected update.

model/log.go (2)

156-166: LGTM!


14-14: LGTM!

Also applies to: 95-96, 168-177, 188-189, 593-593, 656-656

model/log_test.go (1)

30-58: LGTM!

Also applies to: 305-305, 349-403, 722-799, 821-821

relay/helper/stream_scanner.go (1)

31-34: LGTM!

Also applies to: 49-58

relay/helper/stream_scanner_test.go (1)

391-392: LGTM!

Also applies to: 443-444, 496-572, 797-798

Comment thread model/log.go Outdated
Comment thread relay/helper/stream_scanner.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@main.go`:
- Around line 237-245: The shutdown path in main.go uses a single timeout budget
for both model.WaitPendingLogQuotaData and model.SaveQuotaDataCache, which makes
it hard to tell whether the delay is in draining pending quota logs or in saving
the cache. Update the logic around runWithTimeout and saveTimeout so each phase
is tracked separately or at least the timeout/error message clearly identifies
which step timed out. Keep the fix localized to the DataExportEnabled block and
the SysError reporting.

In `@model/log.go`:
- Around line 192-209: `WaitPendingLogQuotaData()` can race with new
`enqueueLogQuotaData()` calls during shutdown because producers like
`controller.UpdateTaskBulk` and `service.TaskPollingLoop` may still invoke
`RecordTaskBillingLog` after draining begins. Add a shutdown/stop gate around
`enqueueLogQuotaData` (or its callers) so no new `logQuotaDataAsyncWG.Add(1)`
happens once shutdown starts, and ensure `WaitPendingLogQuotaData` is only
reached after all quota-log producers are signaled to stop.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: b8f0bdbc-a4c2-492d-b1ce-48ff32ddda13

📥 Commits

Reviewing files that changed from the base of the PR and between 2475c83 and 46c5d3d.

📒 Files selected for processing (5)
  • main.go
  • model/log.go
  • model/log_test.go
  • relay/helper/stream_scanner.go
  • relay/helper/stream_scanner_test.go
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: In Go business code, all JSON marshal/unmarshal operations must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) and must not directly call encoding/json for actual encode/decode work.
All database code must be compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+; prefer GORM abstractions over raw SQL, avoid direct AUTO_INCREMENT/SERIAL, use commonGroupCol/commonKeyCol and commonTrueVal/commonFalseVal for DB-specific SQL, branch with common.UsingPostgreSQL/common.UsingSQLite/common.UsingMySQL, avoid unsupported DB-specific functions/operators without fallback, and make migrations work across all three databases.
When implementing a new relay channel, confirm whether the provider supports StreamOptions; if it does, add that channel to streamSupportedChannels.
For request structs parsed from client JSON and re-marshaled to upstream providers, optional scalar fields must use pointer types with omitempty so explicit zero/false values are preserved instead of dropped.
When working on tiered/dynamic billing expression code, read pkg/billingexpr/expr.md first and follow its documented expression language, architecture, token normalization, quota conversion, and versioning patterns.

**/*.go: All JSON marshal/unmarshal operations in Go business code must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) instead of directly importing or calling encoding/json for actual marshal/unmarshal work.
All database code in Go must remain compatible with SQLite, MySQL >= 5.7.8, and PostgreSQL >= 9.6; prefer GORM abstractions, avoid raw SQL unless necessary, use the shared DB helper variables for reserved words and boolean literals, branch with the common.UsingPostgreSQL / common.UsingSQLite / common.UsingMySQL flags when need...

Files:

  • main.go
  • relay/helper/stream_scanner_test.go
  • relay/helper/stream_scanner.go
  • model/log_test.go
  • model/log.go
🔇 Additional comments (5)
relay/helper/stream_scanner.go (1)

60-64: LGTM!

relay/helper/stream_scanner_test.go (2)

391-392: LGTM!

Also applies to: 443-444, 809-810


566-566: 🩺 Stability & Availability

Safe as-is: info.StreamStatus is initialized before the streaming goroutines start.

			> Likely an incorrect or invalid review comment.
model/log.go (1)

96-97: LGTM!

Also applies to: 157-190, 603-603, 666-666

model/log_test.go (1)

383-402: LGTM!

Also applies to: 801-844

Comment thread main.go
Comment thread model/log.go
@CSCITech
CSCITech merged commit cb3ae82 into main Jul 9, 2026
3 checks passed
This was referenced Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant