Skip to content

Add Codex multi-limit support#4

Merged
wavever merged 2 commits into
wavever:mainfrom
lkliu7:codex-spark
Jun 25, 2026
Merged

Add Codex multi-limit support#4
wavever merged 2 commits into
wavever:mainfrom
lkliu7:codex-spark

Conversation

@lkliu7

@lkliu7 lkliu7 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Pro subscriptions have separate limits for GPT-5.3-Codex-Spark; updated to ping and monitor this limit.

Changes

  • Add Codex models config support so multiple Codex models can be pinged on each reset
  • Read model-specific Codex usage from additional_rate_limits when available
  • Show configured Codex models in status and bg status
  • Update English and Chinese README/config examples for multi-model Codex setup

@wavever wavever left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for this, @lkliu7 — really solid work. It builds cleanly, go vet is quiet, all tests pass (including the two new ones), both READMEs are updated, and the Trigger refactor into triggerOne/buildCodexArgs is nice. The modelmodels config is a good, backward-compatible addition.

I'd like one change before merging, plus a couple of optional nits.

Please fix: empty model no longer falls back to Codex's default

On main, an empty model means "let Codex pick its own default model" — Trigger only appends -m when c.cfg.Model != "". That behavior is still documented (README and the default config comment: "Empty = use the Codex default model").

With this PR, CodexModels() hardcodes a fallback:

if cfg.Model != "" { return []string{cfg.Model} }
return []string{"gpt-5.4-mini"}

so model = "" now always injects -m gpt-5.4-mini. That silently breaks the documented escape hatch and removes the only way for users whose plan doesn't include gpt-5.4-mini to fall back to Codex's default model. (The PR also drops the "Empty = ..." note from the embedded defaultTOML comment while the README still implies it.)

Could you either:

  • preserve a way to express "no -m" (e.g. let an empty model entry skip the flag in buildCodexArgs), or
  • if forcing gpt-5.4-mini is intentional, update all the docs (README EN/zh + config comment) to drop the "Empty = Codex default" promise consistently?

Optional nits (not blocking)

  1. Model matching in pickAdditionalWindows — the bidirectional strings.Contains(n, m) || strings.Contains(m, n) plus the hardcoded spark special-case can mis-match (e.g. gpt-5.4 matching a gpt-5.4-codex limit). It works for today's data since additional_rate_limits is small, but matching on the exact limit_name/id would be more robust and let you drop the spark special-case.
  2. status.go re-loads config inside the loop (config.Load() per Codex provider, error ignored), and the per-model expansion logic is duplicated with bg.go. The Codex provider already knows its models via effectiveModels(); exposing that would avoid the re-read and the duplication.

For context (no action needed): the scheduler still tracks only the primary 5h window, so every configured model is pinged when that window resets — a model with an independent reset time isn't scheduled separately. That matches the PR's stated goal, just noting it so the limitation is documented.

Thanks again — happy to merge once the empty-model case is sorted out.

@lkliu7

lkliu7 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

I rebuilt the feature by treating GPT-5.3-Codex-Spark as if it were its own provider, while reusing Codex auth, CLI transport, hooks, and usage endpoint plumbing. Still disabled by default, but possible quality-of-life features for later: on the first ping, if a pro subscription is detected, ask the user if they want spark enabled; auto-archive ping conversations.

@wavever wavever left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for the thorough rework, @lkliu7 — this is a much cleaner design. All my earlier points are addressed:

  • Empty-model escape hatch restoredNewCodex keeps the original behavior (no -m when model is empty), so "Empty = use the Codex default model" still holds. Spark defaults its own model to gpt-5.3-codex-spark.
  • Robust limit matchingnormalizeCodexLimitName does an exact normalized match against additional_rate_limits[].limit_name, dropping the fragile bidirectional Contains/spark special-case.
  • No status/bg duplication — Spark is a first-class provider, so it flows through the existing status/bg status rendering and gets independently scheduled on its own 5h window.
  • Safe by default — disabled out of the box (with a test asserting it), so existing users don't get an extra quota-consuming ping on upgrade.

Build, go vet, and the full test suite all pass locally, and the new tests cover the spark window selection, the missing-limit error path, dry-run model, and provider selection. Merging now.

@wavever wavever merged commit fee12c3 into wavever:main Jun 25, 2026
@lkliu7 lkliu7 deleted the codex-spark branch June 25, 2026 04:44
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