feat(cli): add hermes agent subcommand for multi-agent management (4/6)#37498
Open
davidgut1982 wants to merge 8 commits into
Open
feat(cli): add hermes agent subcommand for multi-agent management (4/6)#37498davidgut1982 wants to merge 8 commits into
davidgut1982 wants to merge 8 commits into
Conversation
This was referenced Jun 2, 2026
Open
8aaab05 to
2d4ccd4
Compare
Introduce AgentProfile dataclass and a ContextVar (_current_agent_profile) that lets path getters (get_hermes_home, get_skills_dir, get_memory_dir) resolve to the active agent's home directory under asyncio. - agent/profile.py: AgentProfile, use_profile() context manager, load_agent_registry() from GatewayConfig - hermes_constants.py: get_hermes_home() reads ContextVar before env fallback - tests/agent/test_profile_contextvar.py: ContextVar isolation under asyncio.gather, nested contexts, registry loading Single-agent installs see zero change — no profile bound means fallback to HERMES_HOME env var as before.
Add agent_id field to SessionSource and SessionEntry, prefix session keys with agent:<id>: in build_session_key. Default "main" preserves every historical key string for single-agent installs. - gateway/session.py: SessionSource.agent_id, SessionEntry.agent_id, build_session_key prefixing - hermes_state.py: sessions table migration (agent_id TEXT DEFAULT 'main'), new idx_sessions_agent index - tests/gateway/test_session.py: build_session_key prefixing for all chat_type × agent_id combinations - tests/*/test_session_boundary_hooks.py: hook payload agent_id kwarg
… hook
Add declarative routing (routes: match → agent) and a select_agent plugin
hook. _attach_agent_id injects the resolved agent_id into event.source
before build_session_key. Seven platform adapters get pre-injection for
batching paths; the rest inherit it from base.py.
- gateway/agent_routing.py: resolve_agent_id(), _route_matches()
- gateway/config.py: agents, routes, default_agent schema
- gateway/platforms/base.py: _attach_agent_id(), set_routing_context()
- gateway/platforms/{telegram,discord,slack,matrix,feishu,wecom,yuanbao}.py:
pre-batch injection
- hermes_cli/plugins.py: select_agent hook registration
- tests/gateway/test_agent_routing.py: declared-order matching, hook chain,
default fallback, profile isolation
…s agent_id to hooks
GatewayRunner loads the agent registry at init and wraps every inbound
message in use_profile(). AIAgent accepts an optional profile= kwarg.
All invoke_hook call sites gain agent_id= kwarg. _handle_message is
split into _handle_message (ContextVar plumbing) + _handle_message_inner
(legacy logic) so tests that grep the source body continue to work.
- gateway/run.py: registry loading, use_profile() wrapping, hook kwargs
- run_agent.py: AIAgent(profile=), profile-aware model/toolset resolution
- model_tools.py, tools/{approval,terminal,delegate}.py: hook agent_id
- cli.py, tui_gateway/server.py: session boundary hook agent_id
- tests/gateway/test_profile_overrides.py: per-agent model/toolset overrides
- tests/test_model_tools.py: hook payload verification
- tests/gateway/test_{update,title,reasoning}_command.py: adapt to
_handle_message split
New hermes agent subcommand group: list, show, add, remove. Manages agent profiles and routing config in ~/.hermes/config.yaml. - hermes_cli/agent.py: cmd_agent_list, cmd_agent_show, cmd_agent_add, cmd_agent_remove with profile cloning and route cleanup - hermes_cli/main.py: parser registration - tests/hermes_cli/test_agent_cli.py: list/show/add/remove coverage, route orphan warnings, SOUL summarization
The MGA series added _attach_agent_id() into the handle_message hot path (base.py:handle_message). It reads three instance attributes set only in BasePlatformAdapter.__init__: _default_agent_id, _gateway_routes, and _gateway_ref. Any adapter constructed without running __init__ (or a future partial-construction path) crashes with AttributeError on _default_agent_id, which is read outside the existing try/except. Because this runs on every inbound message, a missing attribute would crash real message processing, not just tests. Harden the method to read all three via getattr() with safe defaults so a partially-constructed adapter degrades to the "main" agent instead of raising. Also fix the _make_adapter() test helper, which deliberately bypasses __init__ via object.__new__() and hand-sets attributes: it predated the MGA routing attributes and never set them. Add the three so the mock faithfully mirrors a real __init__-constructed adapter. Fixes 10 regressions in tests/gateway/test_active_session_text_merge.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7902f55 to
6d09f4b
Compare
DeliveryRouter.__init__ was missing the `registry` keyword argument that gateway/run.py:1868 passes as `DeliveryRouter(self.config, registry=self._agent_registry)`. This caused a TypeError on startup failing pytest shards 2/3/4/6 on PR NousResearch#37498 (mga-4). Also restores: - `agent_id` field on DeliveryTarget dataclass - `agent_id=origin.agent_id` propagation in DeliveryTarget.parse() - `_profile`/`use_profile` profile-binding block in deliver() Authoritative reference: feat/mga-5-cron-api-propagation:gateway/delivery.py Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Empty commit to fire push event so the fix(gateway) delivery.py commit (b8f7365) is picked up by NousResearch CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What
Add a
hermes agentCLI subcommand for multi-agent management, plus the supporting conversation-loop wiring.Why
Operators need a first-class CLI surface to create, list, and manage the agents that the gateway routes to, rather than hand-editing config.
How to test
Platforms tested
Linux (CT 133 / Proxmox LXC)
Part 4 of 6 in the multi-agent gateway decomposition (replaces #34741). Depends on: #37497