feat: add log filter autocomplete and tab completion#3419
feat: add log filter autocomplete and tab completion#3419MisonL wants to merge 9 commits intoQuantumNous:mainfrom
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds per-user suggestion rate-limit config and middleware; implements autocomplete suggestion endpoints (log/task/midjourney) with model/query helpers and frontend autocomplete component; introduces responses-stream "bootstrap recovery" state, probing, and retry/wait logic across middleware, relay, helper, service, and tests; docs and i18n updates included. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Distributor as Middleware: Distributor
participant Service as Service: BootstrapRecovery
participant Relay as Controller: Relay
participant DB as Database: ChannelStore
Client->>Distributor: POST /v1/responses (stream=true)
Distributor->>Service: EnsureResponsesBootstrapRecoveryState(c, isStream)
Service->>DB: Check for available channel
alt Channel available
Distributor->>Relay: Forward request
Relay->>Client: Stream response payloads
else No channel available
loop until deadline or channel found
Distributor->>Service: NextResponsesBootstrapWait(now)
Service-->>Distributor: waitDuration, sendPing
alt sendPing
Distributor->>Client: SSE ": PING"
end
Distributor->>DB: Retry channel query
end
alt Channel found
Distributor->>Relay: Forward request
Relay->>Client: Stream response payloads
else Deadline reached
Distributor->>Client: SSE event: error
end
end
opt Relay encounters pre-payload error
Relay->>Service: CanContinueResponsesBootstrapRecovery(error)
alt can continue
Relay->>Service: NextResponsesBootstrapWait(now)
Relay->>Relay: Retry attempt(s)
else cannot continue
Relay->>Client: SSE event: error
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
middleware/distributor.go (1)
132-145:⚠️ Potential issue | 🟡 MinorStop canceled bootstrap waits instead of converting them into 503/model-not-found errors.
Lines 370-372 can now return
context.Canceled/context.DeadlineExceeded, but Lines 132-145 wrap those into the generic “get channel failed” 503 path. On client disconnects or request timeouts, that turns a canceled stream into a misleading channel-selection error.Suggested fix
import ( + "context" "errors" "fmt" @@ if channel == nil { channel, selectGroup, err = getChannelWithBootstrapGrace(c, modelRequest.Model, usingGroup, bootstrapState) if err != nil { + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return + } showGroup := usingGroup if usingGroup == "auto" {Also applies to: 370-372
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@middleware/distributor.go` around lines 132 - 145, The error handling in the getChannelWithBootstrapGrace call (used in middleware/distributor.go) treats context.Canceled and context.DeadlineExceeded the same as other channel lookup failures and returns a 503/model-not-found via abortWithOpenAiMessage; instead detect if err == context.Canceled or err == context.DeadlineExceeded (or errors.Is(err, context.Canceled)/errors.Is(err, context.DeadlineExceeded)) after getChannelWithBootstrapGrace returns and short-circuit by stopping any bootstrap waits and returning early (e.g., abort the request without converting to a 503 model-not-found error or propagate the cancellation appropriately), leaving only genuine channel lookup errors to hit the existing abortWithOpenAiMessage path.
🧹 Nitpick comments (2)
middleware/distributor_bootstrap_integration_test.go (1)
141-175: Consider adding tolerance for timing assertions in CI.The test asserts
elapsed >= 100*time.Millisecondwhich is reasonable, but timing-based tests can be flaky under CI load. The current approach is acceptable for integration tests, but if flakiness occurs, consider increasing tolerances or using condition-based waits.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@middleware/distributor_bootstrap_integration_test.go` around lines 141 - 175, The timing assertion in TestDistributeResponsesBootstrapRecoversBeforeGraceDeadline is brittle; replace the strict require.GreaterOrEqual(t, elapsed, 100*time.Millisecond) with a tolerant check or condition-based wait: either lower the required minimum to a safe-tolerance (e.g., require.GreaterOrEqual(t, elapsed, 80*time.Millisecond)) or remove the elapsed assertion and instead use a condition-based wait (e.g., require.Eventually/assert.Eventually) that polls for the expected stream output in recorder.Body (": PING" / `data: {"status":"ok"}`) within a generous timeout; update the assertion around elapsed or switch to polling so TestDistributeResponsesBootstrapRecoversBeforeGraceDeadline and the variables elapsed, recorder.Body, and handlerCalled are robust under CI load.web/src/components/common/ui/FilterAutoComplete.jsx (1)
130-150: Document internal Semi UI API dependency for Tab selection.The code uses
component?.state?.focusIndexandcomponent?.foundation?.handleSelectto enable Tab-key selection of the currently focused option. Semi UI's public API (value prop + onChange callback) does not expose this functionality—there is no public method to access which dropdown item is currently focused or to trigger selection programmatically. Add a comment explaining this is a necessary workaround for a Semi UI API limitation to clarify the implementation choice for future maintainers:// Semi UI AutoComplete does not expose a public API to programmatically select // the currently focused dropdown item. We use internal APIs (state.focusIndex and // foundation.handleSelect) as a workaround to support Tab-key selection. // This may break in future Semi UI versions; consider following up on Semi's public API.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/common/ui/FilterAutoComplete.jsx` around lines 130 - 150, Add an inline comment above the handleTabSelect logic explaining that this code relies on Semi UI internal APIs because Semi's public AutoComplete API doesn't expose the focused item or a programmatic select; reference the specific internals used (autoCompleteRef -> component?.state?.focusIndex and component?.foundation?.handleSelect) and note this is a workaround that may break in future Semi UI versions and should be revisited if Semi exposes a public API (keep comment near handleTabSelect and the options usage).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@relay/helper/common.go`:
- Around line 125-134: In OpenAIErrorEvent,
service.MarkResponsesBootstrapPayloadStarted(c) is called before serializing the
payload so a failed common.Marshal could leave bootstrap marked; move the call
to after jsonData is created successfully (i.e., after the
common.Marshal(payload) returns without error) so
MarkResponsesBootstrapPayloadStarted(c) is invoked only when marshaling succeeds
and the event can actually be emitted; adjust surrounding error handling in
OpenAIErrorEvent accordingly.
In `@web/src/components/common/ui/FilterAutoComplete.jsx`:
- Around line 102-108: The hardcoded Chinese rate-limit message should be
internationalized: import and call useTranslation() inside the
FilterAutoComplete component to get t, then replace the literal string passed to
showError with a t() lookup (e.g. t('errors.rateLimit') or a suitable key like
t('filter.rateLimitNotice')), keeping the existing rate-limit guard that uses
lastRateLimitNoticeAtRef and showError; ensure the translation key is used
consistently where the message appears so all user-facing strings are provided
via t().
In `@web/src/components/table/task-logs/TaskLogsFilters.jsx`:
- Around line 51-56: The autocomplete toggle currently defaults to true before
status loads; change the logic in TaskLogsFilters so autocompleteEnabled reads
the explicit server toggle only when statusState.status exists (e.g., use a
check against statusState?.status and return false otherwise), keeping the
existing suggestionEndpoint/isAdminUser logic intact; update the reference to
statusState and the autocompleteEnabled assignment inside the component to fail
closed until status loads.
In `@web/src/i18n/locales/en.json`:
- Around line 3341-3352: The new English entries were added after the closing of
the "translation" object so the keys (e.g., "启用 Responses 流启动恢复", "仅在
/v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)", etc.) will not be looked up
by t(...) in the default namespace; move all these new key/value pairs into the
existing "translation" object in en.json (i.e., place them before the closing
brace of "translation"), ensure proper commas and JSON validity, and run a quick
i18n lookup or linter to confirm t('启用 Responses 流启动恢复') resolves to the new
English string.
In `@web/src/i18n/locales/fr.json`:
- Around line 3304-3315: The new locale entries (e.g. "启用 Responses 流启动恢复", "仅在
/v1/responses 流式请求首包前生效,用于短时故障恢复。" etc.) were added after the closing of the
"translation" object and thus won't be resolved by t('...'); move these keys
back under the existing "translation" namespace (or reopen/extend the
"translation" object) so they become part of the translation map, ensuring the
JSON braces are balanced and no duplicate keys are introduced; locate the
"translation" object and append these entries inside it (or merge them) and
validate the JSON.
In `@web/src/i18n/locales/ja.json`:
- Around line 3285-3297: The new translation entries (e.g., "启用 Responses
流启动恢复", "仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)", etc.) were added
at the JSON root instead of inside the "translation" namespace; move all these
keys and their English values into the existing "translation": { ... } object
(i.e., cut the block starting with "启用 Responses 流启动恢复" through the final
explanatory sentence and paste it before the closing brace of the "translation"
object) so i18next can resolve them and preserve the flat Chinese-key structure
required by the frontend guidelines.
In `@web/src/i18n/locales/ru.json`:
- Around line 3318-3329: The new Russian entries were accidentally placed after
the closing brace of the active "translation" object, so move the keys ("启用
Responses 流启动恢复", "仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)",
"在该时间窗口内持续探测可用渠道,超时后返回真实错误。", "渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。", "SSE 保活间隔(秒)",
"在等待恢复期间发送 : PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如
[401,403,429,500,502,503,504]。", "Responses 流启动恢复仅作用于 /v1/responses
的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping 保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。") back inside
the existing "translation" object in ru.json, remove the stray closing brace
that separated them, ensure commas and JSON structure remain valid, and run the
JSON linter/type-check to confirm the keys are now resolvable via t('...') in
the default namespace.
In `@web/src/i18n/locales/vi.json`:
- Around line 3855-3866: The new translation keys (e.g., "启用 Responses 流启动恢复",
"仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。", etc.) were added after the closing of
the existing translation object; move these entries into the existing
"translation" object block (ensure there's a comma after the previous last entry
and remove the extraneous closing brace that currently separates them) so they
reside in the same locale namespace as the rest of the file.
In `@web/src/i18n/locales/zh-CN.json`:
- Around line 2960-2971: The new Chinese translation entries are placed at the
top level instead of under the "translation" namespace; move these keys (e.g.,
"启用 Responses 流启动恢复", "仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)",
"在该时间窗口内持续探测可用渠道,超时后返回真实错误。", "渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。", "SSE 保活间隔(秒)",
"在等待恢复期间发送 : PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如
[401,403,429,500,502,503,504]。", "Responses 流启动恢复仅作用于 /v1/responses
的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping 保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。") into the
existing "translation" object so they live in the same namespace as other
strings; ensure the file remains a flat JSON object (Chinese source strings as
keys) and remove any duplicated keys at top level after moving.
In `@web/src/i18n/locales/zh-TW.json`:
- Around line 2969-2980: The new i18n entries (e.g. "启用 Responses 流启动恢复", "仅在
/v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)", "在该时间窗口内持续探测可用渠道,超时后返回真实错误。",
"渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。", "SSE 保活间隔(秒)", "在等待恢复期间发送 :
PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如 [401,403,429,500,502,503,504]。",
"Responses 流启动恢复仅作用于 /v1/responses 的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping
保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。") were added outside the top-level
"translation" object; move these keys back inside the existing "translation"
object in web/src/i18n/locales/zh-TW.json, preserving the flat JSON format
(Chinese source strings as keys) and existing key/value strings, then validate
the JSON so namespace lookup resolves them normally.
---
Outside diff comments:
In `@middleware/distributor.go`:
- Around line 132-145: The error handling in the getChannelWithBootstrapGrace
call (used in middleware/distributor.go) treats context.Canceled and
context.DeadlineExceeded the same as other channel lookup failures and returns a
503/model-not-found via abortWithOpenAiMessage; instead detect if err ==
context.Canceled or err == context.DeadlineExceeded (or errors.Is(err,
context.Canceled)/errors.Is(err, context.DeadlineExceeded)) after
getChannelWithBootstrapGrace returns and short-circuit by stopping any bootstrap
waits and returning early (e.g., abort the request without converting to a 503
model-not-found error or propagate the cancellation appropriately), leaving only
genuine channel lookup errors to hit the existing abortWithOpenAiMessage path.
---
Nitpick comments:
In `@middleware/distributor_bootstrap_integration_test.go`:
- Around line 141-175: The timing assertion in
TestDistributeResponsesBootstrapRecoversBeforeGraceDeadline is brittle; replace
the strict require.GreaterOrEqual(t, elapsed, 100*time.Millisecond) with a
tolerant check or condition-based wait: either lower the required minimum to a
safe-tolerance (e.g., require.GreaterOrEqual(t, elapsed, 80*time.Millisecond))
or remove the elapsed assertion and instead use a condition-based wait (e.g.,
require.Eventually/assert.Eventually) that polls for the expected stream output
in recorder.Body (": PING" / `data: {"status":"ok"}`) within a generous timeout;
update the assertion around elapsed or switch to polling so
TestDistributeResponsesBootstrapRecoversBeforeGraceDeadline and the variables
elapsed, recorder.Body, and handlerCalled are robust under CI load.
In `@web/src/components/common/ui/FilterAutoComplete.jsx`:
- Around line 130-150: Add an inline comment above the handleTabSelect logic
explaining that this code relies on Semi UI internal APIs because Semi's public
AutoComplete API doesn't expose the focused item or a programmatic select;
reference the specific internals used (autoCompleteRef ->
component?.state?.focusIndex and component?.foundation?.handleSelect) and note
this is a workaround that may break in future Semi UI versions and should be
revisited if Semi exposes a public API (keep comment near handleTabSelect and
the options usage).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3bfae986-a31a-4b59-b059-8c833c64b857
📒 Files selected for processing (44)
common/constants.gocommon/init.goconstant/context_key.gocontroller/log_suggestion.gocontroller/log_suggestion_test.gocontroller/midjourney_suggestion.gocontroller/misc.gocontroller/relay.gocontroller/suggestion_query.gocontroller/task_suggestion.godocs/installation/responses-stream-bootstrap-recovery.mddocs/reviews/CR-LOG-FILTER-AUTOCOMPLETE-2026-03-24.mdmiddleware/distributor.gomiddleware/distributor_bootstrap_integration_test.gomiddleware/rate-limit.gomiddleware/rate_limit_test.gomiddleware/utils.gomiddleware/utils_test.gomodel/log_suggestion.gomodel/midjourney.gomodel/midjourney_suggestion.gomodel/suggestion_common.gomodel/task_suggestion.gorelay/helper/common.gorelay/helper/stream_scanner.gorelay/helper/stream_scanner_test.gorouter/api-router.goservice/responses_bootstrap_recovery.goservice/responses_bootstrap_recovery_test.gosetting/operation_setting/general_setting.goweb/src/components/common/ui/FilterAutoComplete.jsxweb/src/components/settings/OperationSetting.jsxweb/src/components/table/mj-logs/MjLogsFilters.jsxweb/src/components/table/task-logs/TaskLogsFilters.jsxweb/src/components/table/usage-logs/UsageLogsFilters.jsxweb/src/i18n/locales/en.jsonweb/src/i18n/locales/fr.jsonweb/src/i18n/locales/ja.jsonweb/src/i18n/locales/ru.jsonweb/src/i18n/locales/vi.jsonweb/src/i18n/locales/zh-CN.jsonweb/src/i18n/locales/zh-TW.jsonweb/src/pages/Setting/Operation/SettingsGeneral.jsxweb/src/pages/Setting/Operation/SettingsLog.jsx
CodeRabbit follow-up fixes补充推送了一组针对最新 CodeRabbit 评论的修复:
已验证:
commit: |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
web/src/i18n/locales/ja.json (1)
3285-3296: Localize newja.jsonvalues to Japanese instead of English fallbacks.Line 3285–3296 adds the correct keys, but their values are English. In Japanese UI this will show mixed-language text (including the autocomplete rate-limit message). Please replace these new values with Japanese translations for consistency.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/i18n/locales/ja.json` around lines 3285 - 3296, The newly added entries in ja.json currently have English values; replace each English fallback value with the corresponding Japanese translation for the provided keys (e.g. "启用 Responses 流启动恢复", "仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)", "在该时间窗口内持续探测可用渠道,超时后返回真实错误。", "渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。", "SSE 保活间隔(秒)", "在等待恢复期间发送 : PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如 [401,403,429,500,502,503,504]。", "Responses 流启动恢复仅作用于 /v1/responses 的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping 保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。", "联想请求过于频繁,请稍后重试")—translate each English value into natural Japanese and replace the English strings so ja.json contains Japanese text for those keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@web/src/i18n/locales/ja.json`:
- Around line 3285-3296: The newly added entries in ja.json currently have
English values; replace each English fallback value with the corresponding
Japanese translation for the provided keys (e.g. "启用 Responses 流启动恢复", "仅在
/v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)", "在该时间窗口内持续探测可用渠道,超时后返回真实错误。",
"渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。", "SSE 保活间隔(秒)", "在等待恢复期间发送 :
PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如 [401,403,429,500,502,503,504]。",
"Responses 流启动恢复仅作用于 /v1/responses 的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping
保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。", "联想请求过于频繁,请稍后重试")—translate each English
value into natural Japanese and replace the English strings so ja.json contains
Japanese text for those keys.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 89da9810-79ef-4e8e-b37e-c0883cccbc65
📒 Files selected for processing (12)
relay/helper/common.goweb/src/components/common/ui/FilterAutoComplete.jsxweb/src/components/table/mj-logs/MjLogsFilters.jsxweb/src/components/table/task-logs/TaskLogsFilters.jsxweb/src/components/table/usage-logs/UsageLogsFilters.jsxweb/src/i18n/locales/en.jsonweb/src/i18n/locales/fr.jsonweb/src/i18n/locales/ja.jsonweb/src/i18n/locales/ru.jsonweb/src/i18n/locales/vi.jsonweb/src/i18n/locales/zh-CN.jsonweb/src/i18n/locales/zh-TW.json
✅ Files skipped from review due to trivial changes (3)
- web/src/i18n/locales/vi.json
- web/src/i18n/locales/zh-TW.json
- web/src/i18n/locales/fr.json
🚧 Files skipped from review as they are similar to previous changes (4)
- relay/helper/common.go
- web/src/i18n/locales/ru.json
- web/src/i18n/locales/en.json
- web/src/components/common/ui/FilterAutoComplete.jsx
There was a problem hiding this comment.
🧹 Nitpick comments (1)
web/src/i18n/locales/ja.json (1)
3293-3304: Prefer Japanese translations for newja.jsonvalues.Line 3293–Line 3304 currently use English values, so the Japanese UI will show mixed-language labels/messages in settings and autocomplete errors. Please localize these new values to Japanese for consistency.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/i18n/locales/ja.json` around lines 3293 - 3304, The listed JSON entries currently have English values; replace the English strings for these keys with appropriate Japanese translations: "启用 Responses 流启动恢复", "仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。", "启动恢复等待窗口(秒)", "在该时间窗口内持续探测可用渠道,超时后返回真实错误。", "渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。", "SSE 保活间隔(秒)", "在等待恢复期间发送 : PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如 [401,403,429,500,502,503,504]。", "Responses 流启动恢复仅作用于 /v1/responses 的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping 保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。", and "联想请求过于频繁,请稍后重试" — update each value to natural Japanese so the ja.json locale is fully localized.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@web/src/i18n/locales/ja.json`:
- Around line 3293-3304: The listed JSON entries currently have English values;
replace the English strings for these keys with appropriate Japanese
translations: "启用 Responses 流启动恢复", "仅在 /v1/responses 流式请求首包前生效,用于短时故障恢复。",
"启动恢复等待窗口(秒)", "在该时间窗口内持续探测可用渠道,超时后返回真实错误。", "渠道探测间隔(毫秒)", "每次重新探测可用渠道之间的等待时间。",
"SSE 保活间隔(秒)", "在等待恢复期间发送 : PING,帮助客户端保持连接。", "可触发启动恢复的状态码", "填写 JSON 数组,例如
[401,403,429,500,502,503,504]。", "Responses 流启动恢复仅作用于 /v1/responses
的流式请求首包前阶段。它会在短时渠道故障时通过 SSE ping 保持连接,并在恢复后继续返回真实内容;首包发出后不会跨渠道续传。", and
"联想请求过于频繁,请稍后重试" — update each value to natural Japanese so the ja.json locale
is fully localized.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 11eab327-4655-4394-a647-cd608e5b0824
📒 Files selected for processing (7)
middleware/distributor.goweb/src/i18n/locales/en.jsonweb/src/i18n/locales/fr.jsonweb/src/i18n/locales/ja.jsonweb/src/i18n/locales/ru.jsonweb/src/i18n/locales/vi.jsonweb/src/i18n/locales/zh-TW.json
✅ Files skipped from review due to trivial changes (3)
- web/src/i18n/locales/fr.json
- web/src/i18n/locales/vi.json
- web/src/i18n/locales/ru.json
🚧 Files skipped from review as they are similar to previous changes (2)
- web/src/i18n/locales/zh-TW.json
- web/src/i18n/locales/en.json
4fb9028 to
26781b4
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
web/src/components/common/ui/FilterAutoComplete.jsx (1)
137-151: Avoid coupling Tab completion to Semi UI internals.Reading
component.state.focusIndexand callingcomponent.foundation.handleSelect(...)ties this behavior to private instance internals instead of a stable component contract. That is brittle across Semi UI updates and harder to maintain than owning the highlighted option in this component.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/common/ui/FilterAutoComplete.jsx` around lines 137 - 151, The code currently reads autoCompleteRef.current.state.focusIndex and calls component.foundation.handleSelect(...), which couples behavior to Semi UI internals; instead own the highlighted option and invoke the public selection API/prop. Replace direct access to component.state and component.foundation.handleSelect by tracking a local highlightedIndex (e.g., in state) that you update via the AutoComplete's public highlight/hover callbacks (or onHighlightChange), compute selectedOption from that highlightedIndex, and call the AutoComplete's public selection handler (prop like onSelect/onChange) or simulate a user selection via the component's documented public method rather than calling component.foundation.handleSelect; remove reads of autoCompleteRef.current.state.focusIndex and calls to component.foundation.handleSelect and use selectedIndex from your own highlightedIndex.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/common/ui/FilterAutoComplete.jsx`:
- Around line 72-77: Cached suggestions are applied from
cacheRef.current.get(requestKey) without advancing requestIdRef, so older
in-flight responses can later overwrite the cached options; when serving a cache
hit in the block that sets setOptions(cachedOptions) and setLoading(false), also
advance/increment requestIdRef.current (matching the mechanism used for new
requests) so any pending responses with the previous requestId are
ignored—update the cached-path in FilterAutoComplete.jsx to increment
requestIdRef (or set a new current request id) before returning.
In `@web/src/components/table/usage-logs/UsageLogsFilters.jsx`:
- Around line 137-145: The placeholder prop currently uses t('Request ID') which
violates the project's i18n convention; update the FilterAutoComplete
placeholder to call t with the Chinese source-string key used in the locales
(e.g. replace t('Request ID') with the matching Chinese key such as t('请求 ID')
or the exact Chinese string present in web/src/i18n/locales/*.json), ensuring
FilterAutoComplete, placeholder and useTranslation() usage remain unchanged.
---
Nitpick comments:
In `@web/src/components/common/ui/FilterAutoComplete.jsx`:
- Around line 137-151: The code currently reads
autoCompleteRef.current.state.focusIndex and calls
component.foundation.handleSelect(...), which couples behavior to Semi UI
internals; instead own the highlighted option and invoke the public selection
API/prop. Replace direct access to component.state and
component.foundation.handleSelect by tracking a local highlightedIndex (e.g., in
state) that you update via the AutoComplete's public highlight/hover callbacks
(or onHighlightChange), compute selectedOption from that highlightedIndex, and
call the AutoComplete's public selection handler (prop like onSelect/onChange)
or simulate a user selection via the component's documented public method rather
than calling component.foundation.handleSelect; remove reads of
autoCompleteRef.current.state.focusIndex and calls to
component.foundation.handleSelect and use selectedIndex from your own
highlightedIndex.
🪄 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: 3ff7aac1-27dd-495e-a743-d4d915c9304a
📒 Files selected for processing (44)
common/constants.gocommon/init.goconstant/context_key.gocontroller/log_suggestion.gocontroller/log_suggestion_test.gocontroller/midjourney_suggestion.gocontroller/misc.gocontroller/relay.gocontroller/suggestion_query.gocontroller/task_suggestion.godocs/installation/responses-stream-bootstrap-recovery.mddocs/reviews/CR-LOG-FILTER-AUTOCOMPLETE-2026-03-24.mdmiddleware/distributor.gomiddleware/distributor_bootstrap_integration_test.gomiddleware/rate-limit.gomiddleware/rate_limit_test.gomiddleware/utils.gomiddleware/utils_test.gomodel/log_suggestion.gomodel/midjourney.gomodel/midjourney_suggestion.gomodel/suggestion_common.gomodel/task_suggestion.gorelay/helper/common.gorelay/helper/stream_scanner.gorelay/helper/stream_scanner_test.gorouter/api-router.goservice/responses_bootstrap_recovery.goservice/responses_bootstrap_recovery_test.gosetting/operation_setting/general_setting.goweb/src/components/common/ui/FilterAutoComplete.jsxweb/src/components/settings/OperationSetting.jsxweb/src/components/table/mj-logs/MjLogsFilters.jsxweb/src/components/table/task-logs/TaskLogsFilters.jsxweb/src/components/table/usage-logs/UsageLogsFilters.jsxweb/src/i18n/locales/en.jsonweb/src/i18n/locales/fr.jsonweb/src/i18n/locales/ja.jsonweb/src/i18n/locales/ru.jsonweb/src/i18n/locales/vi.jsonweb/src/i18n/locales/zh-CN.jsonweb/src/i18n/locales/zh-TW.jsonweb/src/pages/Setting/Operation/SettingsGeneral.jsxweb/src/pages/Setting/Operation/SettingsLog.jsx
✅ Files skipped from review due to trivial changes (14)
- model/midjourney.go
- relay/helper/stream_scanner_test.go
- docs/installation/responses-stream-bootstrap-recovery.md
- web/src/components/settings/OperationSetting.jsx
- controller/log_suggestion_test.go
- web/src/i18n/locales/ru.json
- web/src/i18n/locales/zh-CN.json
- web/src/i18n/locales/vi.json
- web/src/i18n/locales/fr.json
- service/responses_bootstrap_recovery_test.go
- model/suggestion_common.go
- web/src/components/table/mj-logs/MjLogsFilters.jsx
- model/log_suggestion.go
- web/src/i18n/locales/ja.json
🚧 Files skipped from review as they are similar to previous changes (14)
- constant/context_key.go
- web/src/pages/Setting/Operation/SettingsLog.jsx
- common/init.go
- controller/misc.go
- controller/suggestion_query.go
- middleware/utils_test.go
- middleware/utils.go
- common/constants.go
- setting/operation_setting/general_setting.go
- controller/task_suggestion.go
- model/task_suggestion.go
- model/midjourney_suggestion.go
- web/src/i18n/locales/zh-TW.json
- web/src/i18n/locales/en.json
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
web/src/components/common/ui/FilterAutoComplete.jsx (2)
173-175: Cancel queued fetches on clear.Line 174 invalidates started requests, but a debounced call that has not fired yet is still pending. If Semi's clear interaction does not emit a replacement
onChange(''), stale suggestions can repopulate after the field is cleared.♻️ Proposed fix
onClear={() => { + fetchSuggestions.cancel(); resetOptions(); }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/common/ui/FilterAutoComplete.jsx` around lines 173 - 175, The clear handler currently calls resetOptions() but doesn't cancel a pending debounced request, so a queued debounced fetch can still fire and repopulate suggestions; update the onClear handler (the onClear callback that calls resetOptions()) to also cancel any pending debounced loader (e.g. call debouncedLoadOptions.cancel() or clearTimeout for the timer used by the debouncer) and abort any in-flight fetch (e.g. call abortController.abort() used by loadOptions/fetchSuggestions) to ensure cleared state is not overwritten by stale results.
138-152: Avoid Semi UI private internals for Tab completion.Lines 139-152 depend on
state.focusIndexandfoundation.handleSelect(). If Semi changes either internal, the guard at Line 148 turns Tab completion into a silent no-op. A controlled highlighted-index/value path would be safer here.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/common/ui/FilterAutoComplete.jsx` around lines 138 - 152, The code is reaching into Semi AutoComplete private internals (autoCompleteRef.current.state.focusIndex and .foundation.handleSelect) which can break; instead manage a controlled highlighted index/value and use the component's public callbacks to perform selection. Replace the internals usage in FilterAutoComplete by keeping a local highlightedIndex state (e.g. highlightedIndex), wire it to the AutoComplete via its public props (the control prop for highlighted index or value and the onHighlight/onFocus/onChange/onSelect callbacks the component exposes), compute selectedOption from options[highlightedIndex], and invoke the public selection callback (e.g. the AutoComplete onSelect or onChange prop passed into FilterAutoComplete) rather than calling foundation.handleSelect; ensure you initialize highlightedIndex safely and update it from the component's public highlight/change events so Tab completion never relies on private .state or .foundation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/i18n/locales/zh-CN.json`:
- Around line 2971-2972: The JSON in zh-CN locale has a missing comma after the
"联想请求过于频繁,请稍后重试" entry which causes parse errors; add the trailing comma after
the "联想请求过于频繁,请稍后重试" key/value pair so the subsequent "请求 ID" entry is valid,
then run the i18n CLI checks (bun run i18n:extract, bun run i18n:sync, bun run
i18n:lint) to verify and lint the locale file; specifically update the entries
for "联想请求过于频繁,请稍后重试" and "请求 ID".
In `@web/src/i18n/locales/zh-TW.json`:
- Around line 2988-2989: The JSON in zh-TW locale has a missing comma between
the entries "联想请求过于频繁,请稍后重试" and "请求 ID"; open web/src/i18n/locales/zh-TW.json
and add the missing comma after the value for "联想请求过于频繁,请稍后重试" so the object is
valid JSON, then run the i18n tooling (bun run i18n:lint and bun run i18n:sync /
bun run i18n:extract as needed) to ensure the zh-TW bundle is valid and
synchronized.
---
Nitpick comments:
In `@web/src/components/common/ui/FilterAutoComplete.jsx`:
- Around line 173-175: The clear handler currently calls resetOptions() but
doesn't cancel a pending debounced request, so a queued debounced fetch can
still fire and repopulate suggestions; update the onClear handler (the onClear
callback that calls resetOptions()) to also cancel any pending debounced loader
(e.g. call debouncedLoadOptions.cancel() or clearTimeout for the timer used by
the debouncer) and abort any in-flight fetch (e.g. call abortController.abort()
used by loadOptions/fetchSuggestions) to ensure cleared state is not overwritten
by stale results.
- Around line 138-152: The code is reaching into Semi AutoComplete private
internals (autoCompleteRef.current.state.focusIndex and
.foundation.handleSelect) which can break; instead manage a controlled
highlighted index/value and use the component's public callbacks to perform
selection. Replace the internals usage in FilterAutoComplete by keeping a local
highlightedIndex state (e.g. highlightedIndex), wire it to the AutoComplete via
its public props (the control prop for highlighted index or value and the
onHighlight/onFocus/onChange/onSelect callbacks the component exposes), compute
selectedOption from options[highlightedIndex], and invoke the public selection
callback (e.g. the AutoComplete onSelect or onChange prop passed into
FilterAutoComplete) rather than calling foundation.handleSelect; ensure you
initialize highlightedIndex safely and update it from the component's public
highlight/change events so Tab completion never relies on private .state or
.foundation.
🪄 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: 626209ab-a7ce-4f12-8cbb-fabd240991d4
📒 Files selected for processing (8)
web/src/components/common/ui/FilterAutoComplete.jsxweb/src/components/table/usage-logs/UsageLogsFilters.jsxweb/src/i18n/locales/en.jsonweb/src/i18n/locales/fr.jsonweb/src/i18n/locales/ja.jsonweb/src/i18n/locales/ru.jsonweb/src/i18n/locales/zh-CN.jsonweb/src/i18n/locales/zh-TW.json
✅ Files skipped from review due to trivial changes (2)
- web/src/i18n/locales/fr.json
- web/src/i18n/locales/en.json
🚧 Files skipped from review as they are similar to previous changes (2)
- web/src/i18n/locales/ja.json
- web/src/i18n/locales/ru.json
d7070a6 to
2c74274
Compare
📝 变更描述 / Description
general_setting.log_filter_autocomplete_enabled,并将开关放到“日志设置”区域。Tab键按当前高亮项或首项完成补全。responses bootstrap recovery已独立保留在 Improve responses stream startup recovery during temporary channel outages #3392。🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
✅ 提交前检查项 / Checklist
📸 运行证明 / Proof of Work
go test ./controller ./model ./router ./middleware -count=1PATH=/Volumes/Work/code/new-api/web/node_modules/.bin:$PATH eslint src/components/common/ui/FilterAutoComplete.jsx src/components/table/usage-logs/UsageLogsFilters.jsx src/components/table/task-logs/TaskLogsFilters.jsx src/components/table/mj-logs/MjLogsFilters.jsx src/pages/Setting/Operation/SettingsLog.jsx src/components/settings/OperationSetting.jsxgit diff --checkdocs/reviews/CR-LOG-FILTER-AUTOCOMPLETE-2026-03-24.md