Skip to content

feat: add channel auto reset usage option - #6030

Closed
exherb wants to merge 1 commit into
QuantumNous:mainfrom
exherb:feat/codex-auto-reset-usage
Closed

feat: add channel auto reset usage option#6030
exherb wants to merge 1 commit into
QuantumNous:mainfrom
exherb:feat/codex-auto-reset-usage

Conversation

@exherb

@exherb exherb commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。
  • This PR was AI-assisted because the current git user is not among the repository's recurring core authors.

📝 变更描述 / Description

在渠道额外设置 ChannelOtherSettings 中新增通用配置 auto_reset_usage_enabled。渠道编辑抽屉只对 ChatGPT Subscription (Codex,type 57) 展示 Auto reset usage 开关;其他渠道保存时会移除该字段,尚未实现自动重置的适配器不受影响。

启用后,Codex adapter 仅在首次上游请求返回 429 时进入自动重置流程。流程会在受限 context 内读取 WHAM usage 和 reset credits,确认周额度已耗尽且 available_count > 0 后才调用 consume;只有响应确认 windows_reset > 0,才复用请求体重试一次。资格不足、调用失败、超时或结果未确认时均保留原始 429

同一进程使用 singleflight 合并请求;Redis 可用时再使用按渠道地址和账号隔离的 SET NX 锁,锁 TTL 为 15 分钟,避免并发或紧随其后的请求重复消耗 reset credit。Redis 未启用或锁调用失败时退化为进程内 singleflight。

🚀 变更类型 / Type of change

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

🔗 关联任务 / Related Issue

  • None

✅ 提交前检查项 / Checklist

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

📸 运行证明 / Proof of Work

go test -race ./relay/channel/codex
# ok github.com/QuantumNous/new-api/relay/channel/codex

go vet ./relay/channel/codex
# passed

bun run typecheck
# tsgo -b

bunx oxlint -c .oxlintrc.json \
  src/features/channels/components/drawers/channel-mutate-drawer.tsx \
  src/features/channels/lib/channel-form.ts \
  src/features/channels/lib/channel-form-errors.ts \
  src/features/channels/types.ts
# passed

bun run i18n:sync
# missing/extras/untranslated counts are 0 for all locales

bun run build
# built successfully

Summary by CodeRabbit

  • New Features

    • Added an optional Auto Reset Usage setting for supported Codex channels.
    • When rate-limited, the system can use one available reset credit and retry the request once.
    • Added configuration support and localized labels/instructions across supported languages.
  • Bug Fixes

    • Improved handling of concurrent and repeated rate-limit resets to prevent duplicate reset attempts.
  • Tests

    • Added coverage for retry behavior, eligibility checks, timeouts, concurrency, and failure scenarios.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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

Adds coordinated Codex 429 recovery that consumes reset credit and retries buffered requests once. The channel setting is wired through backend and frontend forms, exposed for Codex channels, tested across local and Redis coordination paths, and localized in seven languages.

Changes

Codex Auto Reset Usage

Layer / File(s) Summary
Codex retry and reset orchestration
dto/channel_settings.go, relay/channel/codex/adaptor.go
Adds the auto-reset setting and implements buffered 429 retry with reset-credit consumption.
Eligibility and distributed reset state
relay/channel/codex/adaptor.go
Adds usage and credit eligibility checks, snapshots, generations, cooldowns, Redis locking, polling, and reset markers.
Auto-reset behavior validation
relay/channel/codex/adaptor_test.go
Covers retry gating, timeouts, concurrency, cancellation, Redis coordination, cooldowns, snapshot failures, and reset publication failures.
Channel form setting integration
web/default/src/features/channels/types.ts, web/default/src/features/channels/lib/*
Adds the setting to frontend types, validation, defaults, serialization, and advanced-field handling.
Channel drawer control
web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
Adds sensitive-setting handling and a Codex-only advanced settings switch.
Localized auto-reset text
web/default/src/i18n/locales/{en,fr,ja,ru,vi,zh-TW,zh}.json
Adds the option label and rate-limit retry instruction translations.
Test dependency wiring
go.mod
Adds miniredis and reorganizes related module declarations.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Adaptor
  participant CodexUpstream
  participant ResetCoordinator
  participant ResetCreditService

  Client->>Adaptor: Send request
  Adaptor->>CodexUpstream: Forward buffered request
  CodexUpstream-->>Adaptor: 429 Too Many Requests
  Adaptor->>ResetCoordinator: Coordinate reset by snapshot
  ResetCoordinator->>ResetCreditService: Check eligibility and consume credit
  ResetCreditService-->>ResetCoordinator: Reset result
  ResetCoordinator-->>Adaptor: Reset success
  Adaptor->>CodexUpstream: Retry request once
  CodexUpstream-->>Adaptor: Return response
  Adaptor-->>Client: Return final response
Loading

Possibly related PRs

Suggested reviewers: seefs001

Poem

A rabbit sees a 429 appear,
Spends one reset credit without fear.
The request hops back through the gate,
Once more it tries—then meets its fate.
Seven tongues now sing along. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding an auto reset usage option at the channel level.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
relay/channel/codex/adaptor_test.go (1)

22-89: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider covering the failure/disabled branches too.

This test only exercises the happy path (429 → credit consumed → retry succeeds). The PR also introduces two other behaviorally distinct branches: reset-credit consumption failing (should return the original 429 without a second call) and CodexAutoResetUsage disabled (should skip buffering and call DoApiRequest directly once). Both are real contract branches worth locking in.

Want me to draft these two additional test cases?

🤖 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 `@relay/channel/codex/adaptor_test.go` around lines 22 - 89, Add two tests
around Adaptor.DoRequest to cover the new branches in
TestCodexAutoResetUsageRetriesAfterRateLimit’s flow: one where the
/backend-api/wham/rate-limit-reset-credits/consume call fails and the response
request should return the original 429 without retrying, and one where
ChannelOtherSettings.CodexAutoResetUsage is false and DoRequest should bypass
buffering/reset logic and call DoApiRequest once directly. Use the existing
Codex adaptor setup, httptest upstream server, and shared symbols like Adaptor,
DoRequest, and DoApiRequest to keep the cases easy to locate.
🤖 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.

Nitpick comments:
In `@relay/channel/codex/adaptor_test.go`:
- Around line 22-89: Add two tests around Adaptor.DoRequest to cover the new
branches in TestCodexAutoResetUsageRetriesAfterRateLimit’s flow: one where the
/backend-api/wham/rate-limit-reset-credits/consume call fails and the response
request should return the original 429 without retrying, and one where
ChannelOtherSettings.CodexAutoResetUsage is false and DoRequest should bypass
buffering/reset logic and call DoApiRequest once directly. Use the existing
Codex adaptor setup, httptest upstream server, and shared symbols like Adaptor,
DoRequest, and DoApiRequest to keep the cases easy to locate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 66109299-58ea-405e-bb33-ccb8ac234b78

📥 Commits

Reviewing files that changed from the base of the PR and between 8739c05 and 864b8bb.

📒 Files selected for processing (14)
  • dto/channel_settings.go
  • relay/channel/codex/adaptor.go
  • relay/channel/codex/adaptor_test.go
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/features/channels/lib/channel-form-errors.ts
  • web/default/src/features/channels/lib/channel-form.ts
  • web/default/src/features/channels/types.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh-TW.json
  • web/default/src/i18n/locales/zh.json

@exherb exherb changed the title feat: add Codex auto reset usage option feat: add Codex auto reset usage routing option Jul 9, 2026
@exherb
exherb force-pushed the feat/codex-auto-reset-usage branch from 2ed310c to bf4272e Compare July 9, 2026 06:40
@exherb exherb changed the title feat: add Codex auto reset usage routing option feat: add auto reset usage routing option Jul 9, 2026
@exherb

exherb commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@seefs001 有空帮忙 review 下?🙏

@seefs001

seefs001 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

这个功能可以加,但是我倾向于仅针对codex单渠道类型的单个渠道级别的配置,codex渠道仅供个人使用所以不会有很多账号,用户可以手动配置是否允许某个账号自动重置。

@exherb

exherb commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

好的,了解,我挪到渠道配置里

@exherb
exherb force-pushed the feat/codex-auto-reset-usage branch 2 times, most recently from f2ad4b2 to 1495f01 Compare July 9, 2026 13:31
@exherb exherb changed the title feat: add auto reset usage routing option feat: add channel auto reset usage option Jul 9, 2026
@exherb
exherb force-pushed the feat/codex-auto-reset-usage branch from 1495f01 to 8f62600 Compare July 9, 2026 13:35
@exherb

exherb commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@seefs001 改完啦

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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/channels/components/drawers/channel-mutate-drawer.tsx (1)

4466-4565: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Move auto_reset_usage_enabled into Channel Extra Settings.
It’s currently nested under the MODEL_FETCHABLE_TYPES-gated “Upstream Model Detection Settings” block, so type 57 never shows this switch even though extraSettingsConfigured already treats it as part of “Channel Extra Settings.” Move it alongside disable_task_polling_sleep so the nav item and the actual control line up.

🤖 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/channels/components/drawers/channel-mutate-drawer.tsx`
around lines 4466 - 4565, The auto_reset_usage_enabled toggle is incorrectly
placed inside the MODEL_FETCHABLE_TYPES-gated Upstream Model Detection Settings
section, which hides it for type 57 and mismatches the Channel Extra Settings
nav. Move the FormField for auto_reset_usage_enabled out of the upstream model
block in channel-mutate-drawer.tsx and render it with the other extra settings,
alongside disable_task_polling_sleep, so extraSettingsConfigured and the visible
control stay aligned.
🧹 Nitpick comments (1)
web/default/src/features/channels/lib/channel-form.ts (1)

563-588: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider consolidating the new type-57 branch with the existing one.

The auto_reset_usage_enabled set/delete logic (lines 583-588) duplicates the same formData.type === 57 condition already checked at line 563 for disable_store/allow_safety_identifier/etc. Merging it into that existing block would avoid a second identical type check.

♻️ Suggested consolidation
   if (formData.type === 1 || formData.type === 57) {
     settingsObj.disable_store = formData.disable_store === true
     settingsObj.allow_safety_identifier =
       formData.allow_safety_identifier === true
     settingsObj.allow_include_obfuscation =
       formData.allow_include_obfuscation === true
     settingsObj.allow_inference_geo = formData.allow_inference_geo === true
+    if (formData.type === 57) {
+      settingsObj.auto_reset_usage_enabled =
+        formData.auto_reset_usage_enabled === true
+    }
   } else {
     if ('disable_store' in settingsObj) delete settingsObj.disable_store
     ...
+    if ('auto_reset_usage_enabled' in settingsObj) {
+      delete settingsObj.auto_reset_usage_enabled
+    }
   }
-
-  if (formData.type === 57) {
-    settingsObj.auto_reset_usage_enabled =
-      formData.auto_reset_usage_enabled === true
-  } else if ('auto_reset_usage_enabled' in settingsObj) {
-    delete settingsObj.auto_reset_usage_enabled
-  }
🤖 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/channels/lib/channel-form.ts` around lines 563 -
588, Consolidate the duplicated type-57 handling in channel-form’s settings
update logic: the `auto_reset_usage_enabled` set/delete branch should be folded
into the existing `formData.type === 1 || formData.type === 57` block instead of
checking `formData.type === 57` again. Update the `settingsObj` mutation logic
in that section so all type-57-specific fields are handled together and the
fallback deletion path remains in the `else` branch.
🤖 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.

Outside diff comments:
In
`@web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx`:
- Around line 4466-4565: The auto_reset_usage_enabled toggle is incorrectly
placed inside the MODEL_FETCHABLE_TYPES-gated Upstream Model Detection Settings
section, which hides it for type 57 and mismatches the Channel Extra Settings
nav. Move the FormField for auto_reset_usage_enabled out of the upstream model
block in channel-mutate-drawer.tsx and render it with the other extra settings,
alongside disable_task_polling_sleep, so extraSettingsConfigured and the visible
control stay aligned.

---

Nitpick comments:
In `@web/default/src/features/channels/lib/channel-form.ts`:
- Around line 563-588: Consolidate the duplicated type-57 handling in
channel-form’s settings update logic: the `auto_reset_usage_enabled` set/delete
branch should be folded into the existing `formData.type === 1 || formData.type
=== 57` block instead of checking `formData.type === 57` again. Update the
`settingsObj` mutation logic in that section so all type-57-specific fields are
handled together and the fallback deletion path remains in the `else` branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b2f265c-6a9b-4af7-aa77-98568be8321b

📥 Commits

Reviewing files that changed from the base of the PR and between bf4272e and 8f62600.

📒 Files selected for processing (14)
  • dto/channel_settings.go
  • relay/channel/codex/adaptor.go
  • relay/channel/codex/adaptor_test.go
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/features/channels/lib/channel-form-errors.ts
  • web/default/src/features/channels/lib/channel-form.ts
  • web/default/src/features/channels/types.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh-TW.json
  • web/default/src/i18n/locales/zh.json
✅ Files skipped from review due to trivial changes (10)
  • web/default/src/features/channels/types.ts
  • web/default/src/i18n/locales/fr.json
  • dto/channel_settings.go
  • web/default/src/features/channels/lib/channel-form-errors.ts
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/zh.json
  • web/default/src/i18n/locales/zh-TW.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/en.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • relay/channel/codex/adaptor_test.go
  • relay/channel/codex/adaptor.go

@exherb

exherb commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

@seefs001 再帮忙看看还有啥问题吧?

@seefs001

Copy link
Copy Markdown
Collaborator

缺少一些关键的部分

不能只看429,需要看还有没有重置次数,需要看周额度是否被用完,调用时需要有ctx timeout管控,需要做并发管控。

ui展示也是有问题的,看代码是展示不出来设置项的。

@exherb
exherb force-pushed the feat/codex-auto-reset-usage branch from 8f62600 to 27fd63f Compare July 15, 2026 01:42
@exherb

exherb commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

缺少一些关键的部分

不能只看429,需要看还有没有重置次数,需要看周额度是否被用完,调用时需要有ctx timeout管控,需要做并发管控。

ui展示也是有问题的,看代码是展示不出来设置项的。

@seefs001 幸苦再抽空给看看

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
relay/channel/codex/adaptor.go (1)

172-207: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Avoid the Redis lookup on the non-429 path relay/channel/codex/adaptor.go:189,503-517

codexAutoResetSnapshot does a Redis GET before every auto-reset-enabled request, even when the upstream call succeeds and never needs a retry. A local fast path/cache here would remove that round trip from the hot path.

🤖 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 `@relay/channel/codex/adaptor.go` around lines 172 - 207, The auto-reset flow
performs the Redis-backed codexAutoResetSnapshot lookup before knowing whether a
retry is needed. Defer or locally cache that snapshot so the initial
channel.DoApiRequest path avoids the Redis GET, while still obtaining the
correct snapshot before consumeCodexResetCredit when the response is HTTP 429
and preserving existing retry behavior.
relay/channel/codex/adaptor_test.go (3)

676-704: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Exact TTL equality is timing-sensitive.

assert.Equal(t, codexAutoResetLockTTL, redisServer.TTL(lockHook.lockKey)) (line 701) compares the lock's remaining TTL to the full lock-TTL constant. miniredis.TTL() returns the actual remaining duration computed from real elapsed time since the SET ... PX call, so any scheduling delay between acquiring the lock and this read can make the assertion intermittently fail. Prefer bounding it instead of exact equality.

♻️ Proposed fix
-	assert.Equal(t, codexAutoResetLockTTL, redisServer.TTL(lockHook.lockKey))
+	ttl := redisServer.TTL(lockHook.lockKey)
+	assert.Greater(t, ttl, time.Duration(0))
+	assert.LessOrEqual(t, ttl, codexAutoResetLockTTL)

Please confirm miniredis' TTL() resolution/precision behavior to validate this flakiness risk.

🤖 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 `@relay/channel/codex/adaptor_test.go` around lines 676 - 704, Replace the
exact TTL assertion in the runCodexAutoReset test with a bounded check that
accepts a slightly reduced remaining TTL while still verifying the lock was
created with the expected codexAutoResetLockTTL. Keep the existing lock-key
lookup and subsequent state assertions unchanged.

332-377: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Wall-clock assertion risks CI flakiness.

assert.Less(t, time.Since(started), 250*time.Millisecond) (line 373) pins pass/fail to real elapsed time, which is the kind of timing-dependent test the repo guideline calls out to avoid — it can fail under CI load unrelated to any real regression. The functional assertions already present (usageCalls == 1, resetCalls == 0) capture the actual timeout behavior; consider dropping or substantially loosening the duration check.

♻️ Proposed fix
-	assert.Less(t, time.Since(started), 250*time.Millisecond)
 	assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode)
 	assert.Equal(t, int32(1), usageCalls.Load())
 	assert.Zero(t, resetCalls.Load())

As per coding guidelines: "avoid coverage-only, implementation-detail, duplicate, fake fuzz/stress, timing, and log-only tests."

🤖 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 `@relay/channel/codex/adaptor_test.go` around lines 332 - 377, Remove the
wall-clock assertion on time.Since(started) from TestAutoResetUsageHasTimeout,
since it introduces CI-dependent flakiness and duplicates the functional timeout
checks. Keep the existing usageCalls, resetCalls, and response-status assertions
that verify the intended behavior.

Source: Coding guidelines


379-448: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Blocking channel receives have no timeout guard.

Several concurrency tests block on unbuffered channels with no deadline: <-bothInitial (lines 404, 410), <-secondInitial/<-resetComplete (lines 475, 481), <-continueUsage (line 586), <-consumeStarted/<-lockHook.secondAttempt (lines 700, 706). If the coordination behavior under test regresses (e.g. the leader never reaches the expected call), these tests hang until the whole go test binary times out instead of failing fast with a clear message, stalling CI. Wrapping these waits in a select with a short timer (or require.Eventually) would fail quickly with a clear diagnostic on regression.

Also applies to: 450-527, 562-644, 646-723

🤖 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 `@relay/channel/codex/adaptor_test.go` around lines 379 - 448, Update the
affected concurrency tests, including
TestAutoResetUsageCoalescesConcurrentResets and the scenarios around
secondInitial, resetComplete, continueUsage, consumeStarted, and
lockHook.secondAttempt, so every blocking channel receive has a bounded timeout
or require.Eventually assertion. Preserve the existing synchronization behavior
while failing promptly with a clear test diagnostic when the expected signal is
never delivered.
🤖 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 `@relay/channel/codex/adaptor.go`:
- Around line 296-299: Update the ineligibility/error branch around
checkCodexAutoResetEligibility to record the same local and Codex cooldown used
by the reset-failure paths before returning. Preserve the existing
codexAutoResetResult values and eligibilityErr, and apply this behavior to the
corresponding branch noted around the later eligibility check as well.

In `@web/default/src/i18n/locales/zh-TW.json`:
- Line 4881: Update the Traditional Chinese translation for the rate-limit
reset-credit message in the locale entry so its scope explicitly means the
behavior applies only to supported channels, using wording equivalent to
“僅對受支援的渠道生效” while preserving the rest of the translation.

---

Nitpick comments:
In `@relay/channel/codex/adaptor_test.go`:
- Around line 676-704: Replace the exact TTL assertion in the runCodexAutoReset
test with a bounded check that accepts a slightly reduced remaining TTL while
still verifying the lock was created with the expected codexAutoResetLockTTL.
Keep the existing lock-key lookup and subsequent state assertions unchanged.
- Around line 332-377: Remove the wall-clock assertion on time.Since(started)
from TestAutoResetUsageHasTimeout, since it introduces CI-dependent flakiness
and duplicates the functional timeout checks. Keep the existing usageCalls,
resetCalls, and response-status assertions that verify the intended behavior.
- Around line 379-448: Update the affected concurrency tests, including
TestAutoResetUsageCoalescesConcurrentResets and the scenarios around
secondInitial, resetComplete, continueUsage, consumeStarted, and
lockHook.secondAttempt, so every blocking channel receive has a bounded timeout
or require.Eventually assertion. Preserve the existing synchronization behavior
while failing promptly with a clear test diagnostic when the expected signal is
never delivered.

In `@relay/channel/codex/adaptor.go`:
- Around line 172-207: The auto-reset flow performs the Redis-backed
codexAutoResetSnapshot lookup before knowing whether a retry is needed. Defer or
locally cache that snapshot so the initial channel.DoApiRequest path avoids the
Redis GET, while still obtaining the correct snapshot before
consumeCodexResetCredit when the response is HTTP 429 and preserving existing
retry behavior.
🪄 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: 1d481ef0-5efb-4e14-a307-3bf7a12681ed

📥 Commits

Reviewing files that changed from the base of the PR and between 8f62600 and 27fd63f.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (15)
  • dto/channel_settings.go
  • go.mod
  • relay/channel/codex/adaptor.go
  • relay/channel/codex/adaptor_test.go
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/features/channels/lib/channel-form-errors.ts
  • web/default/src/features/channels/lib/channel-form.ts
  • web/default/src/features/channels/types.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh-TW.json
  • web/default/src/i18n/locales/zh.json
🚧 Files skipped from review as they are similar to previous changes (10)
  • web/default/src/features/channels/types.ts
  • web/default/src/features/channels/lib/channel-form-errors.ts
  • dto/channel_settings.go
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
  • web/default/src/features/channels/lib/channel-form.ts
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx

Comment thread relay/channel/codex/adaptor.go Outdated
Comment thread web/default/src/i18n/locales/zh-TW.json Outdated
@exherb
exherb force-pushed the feat/codex-auto-reset-usage branch from 27fd63f to ea458c6 Compare July 16, 2026 12:01
@exherb
exherb force-pushed the feat/codex-auto-reset-usage branch from ea458c6 to ef49d01 Compare July 20, 2026 09:59
@exherb

exherb commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

@seefs001 抽空帮忙再看看,感谢。

@exherb

exherb commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@Calcium-Ion 有空看下这个 pull request 么?

@exherb

exherb commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

太难了,先关闭了 @seefs001

@exherb exherb closed this Aug 28, 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.

2 participants