Skip to content

Separate pooled credential runtime state from persisted credentials#5187

Open
kshitijk4poor wants to merge 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix-credential-selector-completeness
Open

Separate pooled credential runtime state from persisted credentials#5187
kshitijk4poor wants to merge 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix-credential-selector-completeness

Conversation

@kshitijk4poor

@kshitijk4poor kshitijk4poor commented Apr 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR separates pooled credential runtime state from pooled credential definitions.

Hermes currently persists temporary execution state like cooldowns and recent exhaustion directly on the credential records themselves. This branch introduces a dedicated credential_pool_runtime store in auth.json so Hermes can treat those as transient operational facts instead of durable credential identity.

What this does

  • adds credential_pool_runtime as the home for pooled credential runtime state
  • keeps credential_pool focused on durable credential definitions only
  • migrates legacy inline cooldown/error fields from credential_pool entries into runtime state automatically on read
  • stores provider cooldown metadata preserved by current main in the runtime layer instead of writing it back into the credential definition

Why the runtime split matters

A pooled credential has two different kinds of data:

  1. Durable definition
  • label, id, source
  • token and refresh data
  • base URL and provider metadata
  1. Transient runtime state
  • exhausted or healthy
  • last error
  • retry/reset time
  • recent usage state

Before this split, Hermes mixed those together. That makes temporary rate limits look like part of the saved credential itself.

This change makes Hermes distinguish between:

  • what a credential is
  • what happened to it recently

Bugs this helps prevent

  • stale exhaustion state persisting as if it were part of the real credential record
  • recovery logic having to rewrite credential definitions just to clear temporary cooldowns
  • valid credentials being treated as permanently dirty because temporary runtime state was stored inline
  • fragile future scheduler/selector work caused by mixing identity/configuration with execution-time status
  • manual auth-store cleanup for older inline cooldown fields

Scope note

Current upstream/main already includes the earlier work for:

  • preserving provider reset windows like resets_at
  • safe id/label-based auth removal
  • improved auth cooldown display

This branch was cleaned up and rebased so it now carries only the remaining runtime-state split.

Verification

  • uv run python -m pytest tests/test_auth_commands.py tests/test_credential_pool.py tests/test_run_agent.py tests/test_credential_pool_routing.py -q
  • uv run python -m py_compile agent/credential_pool.py hermes_cli/auth.py run_agent.py tests/test_auth_commands.py tests/test_credential_pool.py
  • HERMES_HOME=<tmp> uv run hermes -w auth list openai-codex
  • HERMES_HOME=<tmp> uv run hermes -w auth remove openai-codex personal-account

Notes

  • Rebasing against latest upstream/main removed redundant code that had already merged upstream.
  • Full repository pytest was not run in this pass.

This keeps pooled credential cooldown and error tracking in a dedicated runtime store instead of persisting it inline with durable credential definitions. Hermes now migrates legacy inline state on read, preserves provider reset hints for accurate cooldown windows, and leaves the already-merged label-targeting and reset-window UI work to upstream main.

Constraint: Current upstream main already includes the earlier cooldown parsing and auth CLI targeting fixes, so this branch must only carry the remaining runtime-state delta
Constraint: Existing auth.json files with inline credential status must continue to work without manual migration
Rejected: Keep runtime state inline and append more fields | continues mixing durable credentials with transient execution state
Rejected: Re-carry already-merged auth CLI and cooldown-display commits in this branch | redundant with upstream main and makes the PR noisy
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep runtime execution state in ; future pool changes should not persist transient exhaustion state back into credential definitions
Tested: uv run python -m pytest tests/test_auth_commands.py tests/test_credential_pool.py tests/test_run_agent.py tests/test_credential_pool_routing.py -q (274 passed); py_compile on changed files; hermes -w auth list/remove smoke test with temporary HERMES_HOME
Not-tested: Full repository pytest suite, non-pooled gateway/integration paths
@kshitijk4poor kshitijk4poor force-pushed the fix-credential-selector-completeness branch from ae069e2 to 7b76935 Compare April 5, 2026 07:41
@alt-glitch alt-glitch added type/refactor Code restructuring, no behavior change P3 Low — cosmetic, nice to have comp/agent Core agent loop, run_agent.py, prompt builder area/auth Authentication, OAuth, credential pools labels May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent loop, run_agent.py, prompt builder P3 Low — cosmetic, nice to have type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants