Commit Graph

2 Commits

Author SHA1 Message Date
686f6c61 bf7c716648 fix(agent): rebind pool entry id after env credential refresh
Per-turn .env adoption could rewrite agent.api_key while leaving
_credential_pool_entry_id on a previously rotated fallback. The next 429
then marked the healthy fallback exhausted via credential_id precedence
(#79156).

- Sync pool entry id after a successful env credential refresh
- First look does not stomp a pool-rotated key with the env primary
- mark_exhausted_and_rotate prefers api_key_hint when it disagrees with
  credential_id

Fixes #79156
2026-08-08 19:17:02 -07:00
Jeongseok Kang 2d70f56327
fix(agent): adopt .env credential/base-url edits at the turn boundary (#67843)
* fix(agent): adopt .env credential/base-url edits at the turn boundary

A Settings save (desktop PUT /api/env, hermes setup) updates .env and
the saving process's os.environ, but a live session worker keeps the
base_url/api_key captured at agent init until restart — an open chat
silently kept calling the old endpoint (e.g. a local-server key sent to
api.openai.com, failing with an opaque 401).

Add AIAgent._try_refresh_env_client_credentials(), called at the start
of each conversation turn: re-resolve the provider's env-sourced
credentials (load_env() is mtime-memoized, so an unchanged file costs
one stat()) and rebuild the client via the existing
_replace_primary_openai_client machinery when the user edited them.

The refresh reacts only to env edits — resolved values changed since
the last look — never to mere divergence from the agent's current
values: credential-pool rotation and failover legitimately move the
session off the env credential, and stomping those back would flap.
Config model.base_url / pool custom endpoints keep precedence: edits
are only adopted while the session still runs on the registry default
or the previously-seen env value.

Lift _get_env_prefer_dotenv out of _seed_from_env to module level
(get_env_prefer_dotenv) so both the pool seeder and the per-turn
refresh share the same .env-over-os.environ resolution, including the
op:// indirection handling.

Fixes #67821

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(agent): address sweeper review on env credential refresh

- Cover named custom providers (#67935): provider="custom" has no
  PROVIDER_REGISTRY entry, so resolve the config block's key_env through
  the same lookup the runtime resolver uses.
- Make the edit baseline transactional: a failed client rebuild rolls the
  agent back and leaves _env_creds_seen un-advanced so the unchanged edit
  is retried next turn.
- Recompute route-derived TLS material and default headers on a base-url
  change, via a _reapply_route_client_config helper shared with
  credential-pool rotation so the two paths cannot drift.
- Rebase onto main: get_env_prefer_dotenv keeps the scoped _get_secret
  semantics from the profile-isolation fix (no raw os.environ reads).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: map jskang@lablup.com to rapsealk

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Brooklyn Nicholson <brooklyn.bb.nicholson@gmail.com>
2026-08-04 17:53:17 +00:00