feat: lazy skill loading with per-session deduplication - #5938
Closed
RufusLin wants to merge 1 commit into
Closed
Conversation
Add per-session deduplication to skill_view() so that repeated calls within the same task session return a lightweight acknowledgement instead of re-injecting the full SKILL.md body into the conversation context. - tools/skills_tool.py: _loaded_skills state, force param, dedup logic, reset_loaded_skills(), schema update - run_agent.py: call reset_loaded_skills() after context compression - agent/skill_commands.py: pass force=True for slash-command loads - cron/scheduler.py: pass force=True for cron job loads - tests/tools/test_skills_tool.py: 6 new TestSkillViewDeduplication cases
Collaborator
1 similar comment
Collaborator
Author
This was referenced May 27, 2026
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.
feat: Lazy skill loading (with per-session deduplication)
The Problem
Every time
skill_view()is called for the same skill within a session, the fullSKILL.mdbody is injected into the conversation history as a tool result. On long sessions, this means the same skill content can appear multiple times in the context, consuming tokens unnecessarily. Context bloat!My Proposed Solution
This PR adds per-session deduplication to
skill_view(). After the first successful load of a skill's full content, subsequent calls within the same task session return to the model a lightweight message instead of the full skill file:{ "success": true, "already_loaded": true, "name": "my-skill", "message": "Skill 'my-skill' was already loaded earlier in this session. Refer to its instructions in your context. If you cannot find them (e.g. after context compression), call skill_view again with force=True to reload." }Feel free to change that message if you like!
The model can call
skill_view("my-skill", force=True)to bypass the cache and receive the full body again — for example, after context compression has removed the earlier load from the conversation window.Changes
tools/skills_tool.py_loaded_skills: Dict[str, Set[str]]dict (keyed bytask_id) and athreading.Lockfor thread safetyforce: bool = Falseparameter toskill_view()force=False, return the lightweight stub_loaded_skills[task_id]reset_loaded_skills(task_id=None)function to clear the cache (called after context compression)SKILL_VIEW_SCHEMAwith theforcepropertyregistry.registerhandler to passforcethroughrun_agent.pyreset_loaded_skills(task_id)after context compression, alongside the existingreset_file_dedup(task_id)call — ensures the model can reload skills whose content was summarised awayagent/skill_commands.pyforce=Truetoskill_view()in_load_skill_payload()— slash-command skill invocations always need the full body. Sorry, had to add a parameter here, no other way.cron/scheduler.pyforce=Truetoskill_view()in the cron job skill loader — scheduled tasks always need the full bodyTests
Added
TestSkillViewDeduplicationintests/tools/test_skills_tool.pywith 6 cases:force=Truebypasses the stub and returns full contentreset_loaded_skills()clears the cache so the next call returns full contenttask_id— independent sessions don't interferefile_pathset) are never deduplicatedBehavior
SKILL.mdloads. Linked file loads (file_pathargument) are always passed through.forceparameter is also exposed in the tool schema so the model can use it directly in its tool call JSON. This is important if the context has been compressed and it can't find the skill we "claim" is loaded._loaded_skillsis protected by athreading.Lockfor environments that run concurrent tool calls.Thank you for Hermes Agent, I use it 24/7! - Rufus Lin