feat(skills): /reload-skills slash command (salvage of #17670)#17744
Merged
Conversation
Adds a public reload path for the in-process skill caches so newly installed (or removed) skills become visible mid-session without a gateway restart. Mirrors the shape of /reload-mcp. Three surfaces: * /reload-skills slash command — CLI (cli.py) and gateway (gateway/run.py), with /reload_skills alias for Telegram autocomplete and an explicit Discord registration. * skills_reload agent tool (tools/skills_tool.py) — lets agents/subagents pick up freshly-installed skills via tool call. * agent.skill_commands.reload_skills() — shared helper that clears _skill_commands, _SKILLS_PROMPT_CACHE (in-process LRU), and the on-disk .skills_prompt_snapshot.json, then returns an added/removed diff plus the new total count. Tested: * tests/agent/test_skill_commands_reload.py (9 cases) * tests/cli/test_cli_reload_skills.py (3 cases) * tests/gateway/test_reload_skills_command.py (4 cases) Use case: NemoClaw / OpenShell-style sandboxed orchestrators that drop skills into ~/.hermes/skills mid-session, plus agentic flows where the agent itself installs a skill via the shell tool and needs it bound without a gateway restart. The Python helper clear_skills_system_prompt_cache(clear_snapshot=True) already exists internally — this PR just exposes it via slash command and tool.
…ation + agent tool Salvage-follow-up to @shannonsands's /reload-skills PR. Trims the feature to match the design: user-initiated rescan, no prompt-cache reset, no new schema surface, no phantom user turn, and the next-turn note carries each added/removed skill's 60-char description (not just its name). Changes vs the original PR: * Drop the in-process skills prompt-cache clear in reload_skills(). Skills are invoked at runtime via /skill-name, skills_list, or skill_view — they don't need to live in the system prompt for the model to use them. Keeping the cache intact preserves prefix caching across the reload so /reload-skills pays no cache-reset cost. (MCP has to break the cache because tool schemas must be known at conversation start; skills do not.) * Drop the skills_reload agent tool and SKILLS_RELOAD_SCHEMA from tools/skills_tool.py, plus the four skills_reload enumerations in toolsets.py. No new schema surface — agents can already see a freshly- installed skill via skill_view / skills_list the moment it's on disk. * Replace the phantom 'role: user' turn injection with a one-shot queued note. CLI uses self._pending_skills_reload_note (same pattern as _pending_model_switch_note, prepended to the next API call and cleared). Gateway uses self._pending_skills_reload_notes[session_key]. The note is prepended to the NEXT real user message in this session, so message alternation stays intact and nothing out-of-band is persisted to the transcript. * reload_skills() now returns added/removed as [{'name': str, 'description': str}, ...] (description truncated to 60 chars — matches the curator / gateway adapter budget). The injected next-turn note formats each entry as 'name — description' so the model can actually reason about which new skills to call without running skills_list first. * Only emit the note when the diff is non-empty. On empty diff, print 'No new skills detected' and do nothing else. * Tests rewritten to cover the queue semantics, the description payload, and a regression guard that the prompt-cache snapshot is preserved.
13 tasks
4 tasks
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.
Salvage of #17670 by @shannonsands. Adds
/reload-skills(CLI + gateway + Discord) that rescans~/.hermes/skills/and queues a one-shot note for the next user turn listing what changed.Summary
/reload-skillslets a user make newly-installed skills visible mid-session without a gateway restart — critical for agent-driven skill installation (an agent drops a skill via the shell, then runs/reload-skillsto pick it up).What changes vs. the original PR #17670
/skill-name,skills_list, orskill_view— they don't need to live in the system prompt for the model to use them. Keeping the cache intact preserves prefix caching across the reload. (MCP has to break the cache because tool schemas must be known at conversation start; skills do not.)skills_reloadagent tool. Dropped the tool, schema, and four toolset enumerations. The model doesn't need a new schema entry to see a just-installed skill.conversation_history.append({role: 'user', ...})/session_store.append_to_transcriptcalls with a one-shot queued note:self._pending_skills_reload_note(same pattern as_pending_model_switch_note, prepended to the next API call and cleared).self._pending_skills_reload_notes[session_key](consumer in_run_agent_turnprepends to the nextmessageand pops the entry).reload_skills()now returnsadded/removedas[{"name", "description"}, ...]. The description is the skill's SKILL.md frontmatterdescription:field, verbatim — same string the system prompt renders.- name: description; the reload note uses the same shape so the model reads the diff in its original catalog format:Files changed
agent/skill_commands.pyreload_skills()helper — rescans, returns diff with name + descriptioncli.py/reload-skillshandler + queued note consumergateway/run.py_run_agent_turngateway/platforms/discord.pyhermes_cli/commands.pyCommandDef("reload-skills", ...)with/reload_skillsaliastests/agent/test_skill_commands_reload.pytests/cli/test_cli_reload_skills.pytests/gateway/test_reload_skills_command.pyValidation
Closes #17670.
Authorship preserved via cherry-pick + rebase-merge — commit
bf5d011b5stays @shannonsands, follow-upcb9393152is @teknium1.