fix(agent): make cost_status sticky by priority (#67764) - #67804
Open
JonthanaHanh wants to merge 1 commit into
Open
fix(agent): make cost_status sticky by priority (#67764)#67804JonthanaHanh wants to merge 1 commit into
JonthanaHanh wants to merge 1 commit into
Conversation
cost_status and cost_source were most-recent-call-wins everywhere: a single provider hiccup downgrading 'actual' to 'estimated' would clobber the session-level status even though 99% of calls were authoritative. Add sticky_cost_status() helper with priority order: actual > included > estimated > unknown Apply in conversation_loop.py, codex_runtime.py, and insights.py. Fixes NousResearch#67764
Collaborator
1 task
teknium1
reviewed
Jul 25, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for isolating the runtime and /insights overwrite sites. The current change is incomplete for the reported persisted-accounting guarantee.
Problems
- The new runtime assignment does not affect the values passed to persistence: current main still calls
update_token_counts(..., cost_status=cost_result.status)inagent/conversation_loop.py:2956andagent/codex_runtime.py:166.SessionDBthen applies latest-non-null semantics athermes_state.py:4669,hermes_state.py:4690, andhermes_state.py:4869. - The PR changes no tests. The priority rule needs behavioral coverage across the helper, both SessionDB update modes, the per-model UPSERT, runtime accounting, and
/insights.
Suggested changes
- Enforce the priority rule in the SessionDB aggregate and per-model accumulation paths, not only in the two in-memory fields.
- Add regression tests for promotion and non-downgrade sequences such as
estimated → actual → estimated.
Automated hermes-sweeper review.
| if cost_result.amount_usd is not None: | ||
| agent.session_estimated_cost_usd += float(cost_result.amount_usd) | ||
| agent.session_cost_status = cost_result.status | ||
| agent.session_cost_status = sticky_cost_status( |
Contributor
There was a problem hiding this comment.
This makes the in-memory field sticky, but the later update_token_counts() call still receives raw cost_result.status (current main agent/codex_runtime.py:166), and SessionDB overwrites stored status with that non-null value (hermes_state.py:4690, 4869). Please enforce the same rule at persistence so restarted sessions and /insights retain the guarantee.
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.
Problem
cost_statuswas "most-recent-call-wins" everywhere -- a single provider hiccup could downgrade a session's cost accuracy from "actual" to "estimated" even though 99% of calls were authoritative.Four layers all unconditionally overwrote the stored value:
agent/conversation_loop.py:2321--agent.session_cost_status = cost_result.statusagent/codex_runtime.py:150-- same unconditional assignmenthermes_state.py:2887,2908,3087--COALESCE(?, cost_status)takes incoming when non-nullagent/insights.py:583--d["cost_status"] = statusoverwrites per-model dictFix
Add
sticky_cost_status()helper inagent/usage_pricing.pywith priority order:Apply in all three Python call sites. The higher-priority status always wins. Equal priority keeps the incoming value (latest wins).
The SQL
COALESCE(?, cost_status)layer is not changed -- it correctly stores whatever Python passes, and the Python side now computes the sticky value.Files Changed
agent/usage_pricing.py-- add_COST_STATUS_PRIORITYmap andsticky_cost_status()helperagent/conversation_loop.py-- usesticky_cost_status()instead of direct assignmentagent/codex_runtime.py-- sameagent/insights.py-- usesticky_cost_status()when aggregating per-model statusFixes #67764