Mirror codex out-of-credits to the channel#77
Merged
Conversation
When a codex agent runs out of credits, the turn ends with
task_complete{last_agent_message:null} and the preceding token_count
carries rate_limits.credits.has_credits=false. The bridge previously
mirrored only the received prompt, so the channel sat on a bare
"Received user message" with no explanation of why nothing came back.
Detect that state and post an explicit out-of-credits warning (with plan
+ balance and the top-up URL) so the silence is visible.
…resh Codex was launched with canResume=false, so every reconcile (box reboot, spot resume, manual restart) started a brand-new codex session and dropped the agent's accumulated context. Codex mints its own session id, but it can resume the most recent session for the launch cwd, and the global bypass flags work when placed before the `resume` subcommand (verified against a running process). Detect a prior session via the newest rollout under the cwd and resume with `--no-alt-screen ... resume --last` so paste still works and the context survives a restart.
The codex mirror posted the received prompt, every agent message, and every exec command as separate root messages, so the channel filled with tool-call noise at top level. Post the received prompt as a thread root and reply with the turn's activity underneath, so each prompt collapses into one thread. client.post now returns the message ts and accepts a thread_ts.
Threading only worked for Codex because the bridge posts both the received prompt and the agent's turns there. For Claude the daemon posts the received prompt (announce) while the bridge posts the assistant turns, so the bridge had no parent ts and every tool call landed at the channel root. Share the turn's thread-root ts through a small per-agent file: the announce (Claude) and the bridge's user post (Codex) record it, and the bridge threads the assistant turns under it. Unifies both runtimes on one mechanism.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
task_complete{last_agent_message: null}whose precedingtoken_countreportsrate_limits.credits.has_credits == false. The message includes the plan, balance, and the top-up URL.formatCodexRolloutLinesmirrors any codex agent, not just the PR reviewer.Why
The codex pr-reviewer hit its usage limit and the channel showed three "Received user message" lines with no follow-up, so there was no way to tell from Slack that it was stuck on credits. The usage-limit text only renders in the codex TUI, never in the rollout, but the credits state is in the structured
token_countevent, so we can surface it cleanly.Test plan
formatCodexRolloutLinesposts an out-of-credits warning when a turn produces no output and credits are exhaustednode --testsuite green