Skip to content

feat(agent,gateway): cross-mode fallback context bridge + Inspector server - #43289

Closed
cjakma wants to merge 1 commit into
NousResearch:mainfrom
cjakma:feat/fallback-context-bridge-inspector
Closed

feat(agent,gateway): cross-mode fallback context bridge + Inspector server#43289
cjakma wants to merge 1 commit into
NousResearch:mainfrom
cjakma:feat/fallback-context-bridge-inspector

Conversation

@cjakma

@cjakma cjakma commented Jun 10, 2026

Copy link
Copy Markdown

What changed and why

feat(agent): Cross-mode fallback context bridge

When the api_mode changes during failover (e.g. codex_responsesanthropic_messages), the existing api_messages carry provider-specific fields (codex reasoning items, encrypted blobs) that the new provider rejects. This PR detects the mode change in try_activate_fallback, sets _pending_context_bridge on the agent, and applies fallback_context_bridge.apply_fallback_context_bridge() in conversation_loop before the retry request. The bridge strips the stale provider-specific fields and clears the cached system prompt so it rebuilds with current skill context for the new provider.

feat(gateway): Read-only Inspector server

Adds gateway/inspector.py — a lightweight read-only HTTP meta-API that external containers (sidecars, monitoring tools) can query for gateway state without touching the main gateway socket. Enabled by default; opt out with HERMES_INSPECTOR_DISABLED=1. Host/port configurable via HERMES_INSPECTOR_HOST / HERMES_INSPECTOR_PORT (default 127.0.0.1:8646).

fix(providers): Use hostname for api.openai.com detection

determine_api_mode was using in url_lower string containment which could match URLs that merely contain api.openai.com as a substring. Switched to base_url_hostname(base_url) == "api.openai.com" for exact hostname matching.

fix(tools): Exclude nested skill docs from strategy-3 flat search

skill_view strategy-3 (rglob) was picking up reference/template .md files nested inside another skill's directory. Added an ancestor-walk check to skip any file whose parent chain contains a SKILL.md between it and the search root.

How to test

Fallback bridge:

# Simulate a codex → anthropic fallback
python scripts/simulate_codex_fallback.py
# Integration test
pytest tests/agent/test_fallback_context_bridge_integration.py -v

Inspector server:

# Start gateway, then:
curl http://127.0.0.1:8646/health
curl http://127.0.0.1:8646/state
# Disable:
HERMES_INSPECTOR_DISABLED=1 hermes gateway start

Provider fix:

from hermes_cli.providers import determine_api_mode
assert determine_api_mode("openai", "https://api.openai.com/v1") == "codex_responses"
assert determine_api_mode("openai", "https://proxy.api.openai.com.evil.com/v1") != "codex_responses"

Skills fix:

hermes -q "use skill: skill-name"  # should not load nested reference docs

Platforms tested

  • Linux (Ubuntu 22.04)

Notes

  • notion-backup-slack-thread-2026-05-15.md is intentionally excluded (internal file)
  • Inspector server failure is non-fatal — gateway continues if it cannot bind

…erver

- Add fallback_context_bridge to strip provider-specific fields (codex
  reasoning blobs) and rebuild the system prompt when api_mode changes
  during failover (e.g. codex_responses → anthropic_messages)
- Set _pending_context_bridge flag in try_activate_fallback and consume
  it in conversation_loop before the next retry request
- Add read-only Inspector server (gateway/inspector.py) with opt-in
  startup in start_gateway; configurable via HERMES_INSPECTOR_HOST/PORT
- Fix providers.py: use base_url_hostname() for api.openai.com detection
  to prevent false matches on URLs containing the string as a substring
- Fix skills_tool strategy-3 flat search to skip files nested inside
  another skill's SKILL.md directory (reference assets, not standalone)
- Add simulation/trigger scripts and integration test for fallback bridge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/gateway Gateway runner, session dispatch, delivery labels Jun 10, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Comment (High Surface Area)

Scope

  • 2,485 additions, 4 deletions across 15+ files — this is a significant new feature introducing a cross-mode fallback context bridge and an Inspector debug server.

Security

  • The new /config/public endpoint explicitly strips sensitive keys (api_key, token, secret, password, auth, credential, bearer) — good security posture.
  • The Inspector server binds to 127.0.0.1:8646 by default and can be configured via inspector.host/inspector.port — appropriate for a local-only debug tool.
  • One concern: The _SENSITIVE_KEY_PATTERNS regex approach may miss edge cases (e.g., nested keys, case variations). Consider validating against a known list of sensitive field names in addition to pattern matching.

Code Quality

  • The diff contains curl commands with pipe-to-python in comments (lines 168-170) — these appear to be development notes left in the code. Consider removing before merge.
  • print() statements in the bridge implementation (lines 1205, 1252) look like debug leftovers.
  • The module is well-structured with clear separation between the fallback bridge, Inspector server, and session management.

Performance

  • The Inspector server spawns a new asyncio server per call to start_inspector_server() — if this is called repeatedly, it could leave orphan servers. Verify cleanup on shutdown.

Suggestion

  • Add a test for the /config/public endpoint to ensure sensitive keys are actually filtered in all code paths.

Reviewed by Hermes Agent

@kyssta-exe

Copy link
Copy Markdown
Contributor

Thanks for the PR! A few observations:

1. Stray file in the diff — README_Code_Update.md

This 528-line Korean-language changelog document doesn't appear to be part of the codebase. It's a local documentation file describing the changes in this PR and general contributing guidelines. It should be removed before merging — it will pollute the repo root.

2. Inspector server CORS policy when bound to 0.0.0.0

The Inspector server sets Access-Control-Allow-Origin: * on every response (via _cors_headers()). This is safe on the default 127.0.0.1 bind, but the docs and code explicitly support HERMES_INSPECTOR_HOST=0.0.0.0 for Docker scenarios. When bound to all interfaces, any website the user visits could make cross-origin requests to the Inspector and learn the model/provider in use, the list of installed skills, and the gateway state.

Consider either:

  • Omitting the Access-Control-Allow-Origin header when host is not localhost
  • Or documenting that 0.0.0.0 should only be used in trusted/restricted networks

3. PR bundles four unrelated changes

The PR description and diff include: (a) fallback context bridge, (b) Inspector server, (c) providers.py hostname fix, (d) skills_tool.py nested-dir fix. The contributing guidelines recommend one logical change per PR. Splitting these would make review easier and reduce risk.

@cjakma

cjakma commented Jun 10, 2026

Copy link
Copy Markdown
Author

Closing this PR in response to review feedback. Split into 4 focused PRs:

Also removed README_Code_Update.md from all branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants