Repository navigation
Conversation
AgentState.set_billing_cache had no production caller, so on_session_start always read an empty cache and update_from_billing never ran: relay recall_top_k, extraction_interval, max_facts_per_extraction, max_candidate_pool, the >80% quota warning and the update notice were all dead. - The eager account register caches the client.status() response it already fetches (no extra request on the first session). - Once the cached copy passes its 2h TTL, on_session_start makes one refresh bounded by 5 s. Failure or timeout keeps current settings and never blocks the session; no refresh after a failed eager register in the same session. - A write refused for quota (403) invalidates the cache so the next session re-fetches and warns. - Env overrides still beat server values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
The relay serves max_candidate_pool=2000, which Hermes has never used. Keep today's 250 until a large-vault measurement; env overrides are not capped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax
This branch has not been deployed
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.
Draft: do not merge. Client merges are on hold until the audit sync. This PR also turns on server values that have never applied before, and two of them need a decision first (see "Decide before merge").
Refs #663 (billing cache never populated).
Bug
AgentState.set_billing_cachehas no production caller, andon_session_startonly readsstate.get_cached_billing(), which is alwaysNone. Soupdate_from_billingnever runs, and none of these apply in Hermes today:recall_top_k,extraction_interval,max_facts_per_extractionandmax_candidate_poolfeatures.latest_stable_python)The Python client also had no 403 cache invalidation at all.
Fix
_eager_account_registeralready callsclient.status()once per configure. It now caches that response (BillingStatus→ the dict shapeupdate_from_billingreads), so the first session of a process makes no extra request.BILLING_CACHE_TTL),on_session_startmakes one refresh capped at 5 s (_BILLING_REFRESH_TIMEOUT_S). On a timeout or error it logs at DEBUG and keeps the current settings (the built-in defaults on a fresh process). It never raises and never blocks the session. If the eager register failed in the same session, no refresh is attempted, so a down relay costs one request per session, not two.state.invalidate_billing_cache(). The next session then re-fetches and shows the warning instead of waiting out the TTL.TOTALRECLAW_RECALL_TOP_K,TOTALRECLAW_EXTRACT_INTERVAL,TOTALRECLAW_MAX_FACTS_PER_EXTRACTION,CANDIDATE_POOL_MAX_FREE/_PRO). That logic is unchanged.get_recall_top_k's docstring listed the precedence in the wrong order. It now reads env > server > default, which is what the code does.What switches on: server values vs today's defaults
Queried 2026-11-04 with a throwaway account (random auth key, not derived from a phrase), free tier, full
featuresobject:recall_top_kextraction_intervalmax_facts_per_extractionmax_candidate_poolMAX_SERVER_CANDIDATE_POOL, Pedro 2026-11-04). Lifting the cap waits on a large-vault measurement, internal tracker #696. Env overrides are not capped.free_writes_used / free_writes_limit> 0.8)latest_stable_python)TOTALRECLAW_DISABLE_UPDATE_NOTICE=1turns it off.min_extract_interval(5),custom_extract_interval(false),llm_dedup(true),ingest_*,enclave_enabledmin_extract_interval5 >extraction_interval3 on the relay; Python ignores the min, so nothing changes, but the relay config looks inconsistent.reads_quota_modeisobservewith noreads_limitin both environments, so the larger candidate pool cannot trip a read quota today.Decide before merge
Decided 2026-11-04: capped at 250 (commit 59c38f2). The relay value applies only below 250;max_candidate_pool250 → 2000 for Hermes.CANDIDATE_POOL_MAX_FREE/_PROstill override it uncapped. Measurement tracked internally (feat(hermes): restore built-in memory once after upgrade; log "no changes" consistently #696), after the next real ChatGPT/Gemini export test.StagingResolved 2026-11-04: stagingrecall_top_k = 8.RECALL_TOP_Kremoved and redeployed; both relays serve 16.Tests
New
tests/test_hermes_billing_cache_fill.py(11 tests, all driving the realon_session_startwith a stubbed client):8 of the 11 fail on
origin/mainand all pass with the fix.Full suite:
python -m pytest tests/ -q -n 8(HOME pointed at a temp dir): 2764 passed, 15 skipped, 1 xfailed.🤖 Generated with Claude Code
https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax