Commit Graph

15 Commits

Author SHA1 Message Date
teknium1 dd1baee0e4 refactor(secrets): drop scope-aware env shims; runtime_provider and the voice/xai tools read the canonical getters
hermes_cli/runtime_provider._getenv was a 4-line copy of get_secret(name,
default) or default; it becomes agent.secret_scope.get_secret_str (returns
default only when the secret is genuinely unset, still raises
UnscopedSecretError — a child's unscoped read is a spawn-site bug). The
runtime_provider_backends/_custom siblings call it directly instead of via
the origin module.

tools/tts_tool, tools/transcription_tools and tools/xai_http each carried an
identical get_env_value re-export kept "so tests can patch" it; the seam is
hermes_cli.config.get_env_value, read lazily at call time. Callers
(tts_streaming, tts_tool_providers, transcription_cloud, voice_client_config,
tools_config) go there directly; resolve_provider_secret already defaults to
it so the env_getter kwarg is gone. Tests repointed at the canonical; the two
tests that only proved the shim forwarded are deleted.

Behavior change: none.
2026-09-13 05:07:50 -07:00
teknium1 199544e054 fix(openrouter): canonical config URL keeps the pool; mirror key follows the selected endpoint
Two regressions in the mirror support: (1) the canonical
https://openrouter.ai/api/v1 that `hermes setup` persists under
provider: openrouter was treated as a custom endpoint, dropping the
auth.json credential pool and returning an empty API key; (2) an
unrelated CUSTOM_BASE_URL (which outranks the config mirror) still
received OPENROUTER_API_KEY because key selection tested mirror
eligibility, not the endpoint actually selected. A config URL is a
mirror only when its host is not openrouter.ai, and the mirror key
branch fires only when base_url is the config URL.

Found by independent review before merge.
2026-09-12 08:47:04 -07:00
JackJin 63f1016bea fix(cli): honor config base_url mirror for explicit openrouter provider
When config.yaml sets `model.provider: openrouter` together with a
`model.base_url` mirror/proxy, an explicit `--provider openrouter`
request ignored the mirror and sent traffic to the public OpenRouter
endpoint: the config base_url was only trusted for auto/custom, the
credential pool was still consulted (so a pooled key won over the
mirror), and even when the mirror URL was used its host failed the
openrouter.ai match so OPENROUTER_API_KEY was not selected for it.

Trust the config base_url for the explicit openrouter case, treat that
mirror as an OpenRouter context for key selection, and bypass the pool
like the other custom-endpoint cases already do.

Fixes #10622
2026-09-12 08:47:04 -07:00
Teknium 942973ae90 fix: every Bedrock client rebuild lands on the startup wire (Claude SDK, Converse region, guardrails)
Follow-up to 564aef2946 (Mantle SigV4 on /model). The same class of bug covered the
other two Bedrock wires and two more rebuild paths:

- Claude on Bedrock (anthropic_messages): startup builds an AnthropicBedrock SDK
  client (SigV4 via boto3). /model, fallback-to-Bedrock and fallback restore built a
  plain Anthropic client with api_key="aws-sdk" against bedrock-runtime → 401/403.
- Converse models (bedrock_converse: Nova, DeepSeek, Llama): only agent_init set
  _bedrock_region / _bedrock_guardrail_config. After a rebuild the transport fell
  back to us-east-1 and guardrail_config=None, so eu-/ap- users hit the wrong region
  and configured Guardrails silently dropped. switch_model also built a pointless
  OpenAI client against bedrock-runtime.

Introduce bedrock_adapter.bind_bedrock_runtime(agent, base_url, api_mode) as the one
place that puts an agent on a non-Mantle Bedrock wire, and call it from agent_init
(replacing the two duplicated bodies), _build_switched_client, _rebuild_primary_client
and _swap_fallback_clients. try_recover_primary_transport had a hand-copied version of
_rebuild_primary_client's ladder (and would have hit the same gap); it now calls the
shared helper. The region/guardrail parsing that lived in agent_init and
runtime_provider_backends is now bedrock_region_from_runtime_url /
bedrock_guardrail_config in the adapter.

Live probe on origin/main across switch_model, restore_primary_runtime and
_swap_fallback_clients for both wires: 0/6 correct before, 6/6 after.
2026-09-10 18:08:16 -07:00
Teknium 7a33369e81 simplify(compat): interrupt — drop _ThreadAwareEventProxy/_interrupt_event legacy alias, repoint 2 test files
No runtime consumer read the proxy (terminal_tool/environments call is_interrupted()/set_interrupt()
directly); its only users were tests patching tools.interrupt._interrupt_event, which had no effect on
the code under test. tools/terminal_tool.py's own re-export of the name is owned by another worker.
2026-09-03 14:00:59 -07:00
Teknium c93ace77c2 simplify(compat): config/runtime_provider/plugins/commands/secrets_cli/kanban — drop 96 re-exports (incl. PEP 562 facades) + 3 aliases (get_pre_tool_call_directive/_block_message, get_telegram_handler_factories), repoint 56 callers + 50 test files 2026-09-03 14:00:17 -07:00
Teknium e83816a4d1 review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged)
For each issue anchor present in BASE 63279301bc non-test .py and absent on HEAD, the BASE comment/docstring block was re-attached at the HEAD location of the code it explained (matched by the distinctive code line / enclosing def). Sentences already covered by an existing HEAD comment were deduped; the issue number always survives. Insert-only: no code lines changed.
2026-09-03 09:44:26 -07:00
Teknium c926874152 refactor(hermes_cli): backends/custom — fold candidate lists, message literals; drop always-None provider_name conditional 2026-09-02 22:50:07 -07:00
Teknium 465c6dd4e9 refactor(hermes_cli): provider cluster — hanging-indent repack of exploded call sites (AST-identical) 2026-09-02 22:39:49 -07:00
Teknium 951ee86ae6 refactor(hermes_cli): backends/custom — flatten entra branch, registry via origin, canonical_custom_identity tail via custom_provider_slug 2026-09-02 22:28:12 -07:00
Teknium e789d79cfe refactor(hermes_cli): provider cluster — shared _overlay_pdef, pool-select guard collapse, docstring compaction (WHY kept) 2026-09-02 22:14:12 -07:00
Teknium 6740d264f1 refactor(hermes_cli): provider cluster — drop intra-function separator blanks (whitespace-only) 2026-09-02 21:49:11 -07:00
Teknium b69a423835 refactor(hermes_cli): provider cluster — fold/pack short multi-line statements (AST-identical) 2026-09-02 21:24:52 -07:00
Teknium b8c7add3a9 refactor(hermes_cli): runtime_provider_custom/backends — shared _custom_runtime builder, azure key helper, compact docs 2026-09-02 21:21:10 -07:00
Teknium a1066d0317 refactor(runtime_provider): split ladder into collaborators; extract custom-provider and backend modules
- resolve_runtime_provider 463 -> 95 LOC; rung order documented and preserved
  (17,589-case fixture corpus, 0 diffs vs base incl. exceptions + log records)
- hermes_cli/runtime_provider_custom.py: providers:/custom_providers: lookup,
  identity recovery, custom pools, named-custom runtime
- hermes_cli/runtime_provider_backends.py: azure-foundry, openrouter/bare-custom,
  bedrock, external-process builders
- moved bodies resolve origin-internal names via the origin module at call time so
  monkeypatch.setattr(runtime_provider, ...) in tests keeps applying
- _EXPLICIT_RESOLVERS dispatch for the explicit-creds path; shared
  _finalize_base_url / _nous_min_key_ttl / _refresh_nous_pool_entry helpers
2026-09-02 15:50:50 -07:00