Gate benign `account/rateLimits/updated` telemetry behind `notifications.rate_limit_telemetry`
Summary
codex app-server emits an account/rateLimits/updated JSON-RPC notification on every EventMsg::TokenCount (one per turn), even when the snapshot reports rate_limit_reached_type: None, no exhausted credits, and identical numbers to the previous turn. For parent harnesses driving codex app-server over stdio per session — which is the only case where these notifications are actionable — the result is one telemetry event per turn that has to be filtered out by inspecting the snapshot shape.
A real downstream filter that this would make redundant:
function rateLimitsSnapshotIsBenignTelemetryOnly(rateLimits) {
if (rateLimits.rate_limit_reached_type) return false;
if (rateLimits.exceeded === true) return false;
const remaining = rateLimits.remaining;
if (typeof remaining === "number" && remaining < 0) return false;
return true;
}
The codex TUI itself does want these (it tracks live percent display, plan changes, credits balance, threshold-based switch prompts, etc.), so the fix can't be "stop emitting". It needs to be a per-deployment opt-out.
Proposed solution
Add a new [notifications] section in config.toml:
[notifications]
rate_limit_telemetry = false # suppress account/rateLimits/updated when no limit is reached
Default is true (preserves the historical "emit on every turn" behavior the codex TUI relies on). When set to false, account/rateLimits/updated notifications whose snapshot carries rate_limit_reached_type: None are suppressed. Snapshots that do report a real rate-limit event are always emitted regardless, so the TUI's threshold prompts and limit-reached UI keep working.
The gate lives in a new helper type ServerNotificationsConfig with a should_emit_rate_limits(&snapshot) -> bool method, plumbed into handle_token_count_event via ListenerTaskContext. This keeps the policy decoupled from the per-event handler and makes the contribution surface easy to extend with future [notifications] knobs.
Default-flip alternative
The original motivating description ("don't emit benign rate-limit telemetry; gate behind notifications.rate_limit_telemetry") could be read as "default off, gate true re-enables firehose". I went the safer way (default true, opt-out via false) because the codex TUI's on_rate_limit_snapshot consumer relies on per-turn updates for the live percent and credits balance displays — flipping the default would silently break those readouts until the user actually hit a limit. Easy to flip the default later if the team prefers the more aggressive semantic.
Reference implementation
A working implementation with tests lives on the team-wcv fork:
- Branch: https://github.com/team-wcv/codex/tree/feat/rate-limit-telemetry-gate
- Diff: https://github.com/team-wcv/codex/compare/main...feat/rate-limit-telemetry-gate
Touches:
codex-rs/config/src/config_toml.rs—NotificationsToml+pub notifications: Option<NotificationsToml>onConfigToml.codex-rs/core/src/config/mod.rs— resolves into a flatConfig::notifications_rate_limit_telemetry: bool(defaulttrue).codex-rs/core/config.schema.json— regenerated viajust write-config-schema.codex-rs/app-server/src/server_notifications_config.rs— new module withServerNotificationsConfig+should_emit_rate_limits+ arate_limit_telemetry_disabled()test helper.codex-rs/app-server/src/request_processors/thread_lifecycle.rs+thread_processor.rs+turn_processor.rs— plumbServerNotificationsConfigthroughListenerTaskContext.codex-rs/app-server/src/bespoke_event_handling.rs— pass throughapply_bespoke_event_handling->handle_token_count_eventand gate theAccountRateLimitsUpdatedemission. Two new tests cover the benign-suppression and limit-reached-passthrough paths.
cargo test -p codex-app-server --lib → 223 passed, 0 failed (including 2 new). cargo test -p codex-config -p codex-core is green. just fix -p codex-app-server reports clean. Schema regen + fmt applied.
Per docs/contributing.md
External contributions are by invitation only, so this is filed as an enhancement request with reference implementation attached. Happy to open the PR against this repo if the approach is acceptable.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗