hermes - ✅(Solved) Fix Curator: `bump_use()` has zero production call sites — `use_count` always 0 [5 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#17782Fetched 2026-05-01 05:55:52
View on GitHub
Comments
2
Participants
2
Timeline
15
Reactions
0
Author
Timeline (top)
cross-referenced ×6labeled ×3referenced ×3commented ×2

Fix Action

Fixed

PR fix notes

PR #17818: fix(skills): wire bump_use() into skill invocation and preload paths (#17782)

Description (problem / solution / changelog)

Summary

Connects bump_use() to its intended call sites so Curator's lifecycle tracking actually works.

Problem

bump_use() in tools/skill_usage.py existed and was fully tested, but had zero production call sites. As a result:

  • use_count stayed at 0 for all skills
  • last_used_at stayed None forever
  • Curator's stale timer (30 days) couldn't distinguish used vs. unused skills
  • Every non-pinned agent-created skill would transition to stale simultaneously

Meanwhile bump_view() was correctly wired into skills_tool.py.

Fix

Wire bump_use() into the two canonical "a skill is actively being used" paths in agent/skill_commands.py:

  1. build_skill_invocation_message() — when a user invokes a /skill-name slash command and the skill content is injected into the prompt
  2. build_preloaded_skills_prompt() — when a skill is preloaded at CLI session start via hermes --skill <name>

Both calls are wrapped in try/except to remain non-critical — skill invocation proceeds regardless of usage tracking errors.

Why these paths

  • Slash command invocation = the user explicitly activated the skill to solve a task
  • Preload = the user started an entire session with this skill active
  • Both represent genuine "use" (vs. bump_view which tracks browsing/listing)

Testing

Existing test_skill_usage.py tests for bump_use pass. The function itself is well-tested; it simply had no callers.

Closes #17782

Changed files

  • agent/skill_commands.py (modified, +16/-0)

PR #17865: fix: wire bump_use() into skill loading paths

Description (problem / solution / changelog)

Summary

bump_use() in tools/skill_usage.py existed and was tested, but had zero production call sitesuse_count stayed at 0 and last_used_at stayed None forever, making the Curator's stale timer unable to distinguish actively-used skills from never-used ones.

Changes

Adds bump_use() calls to two skill loading paths in agent/skill_commands.py:

  1. build_skill_invocation_message() — when a /skill slash command is resolved and its content is injected into the prompt
  2. build_preloaded_skills_prompt() — when skills are loaded via the CLI --skills flag at session start

Both calls follow the same pattern as the existing bump_view() call in skills_tool.py: wrapped in try/except Exception for best-effort operation that never breaks skill loading.

Why these paths

Per the issue's analysis, option 1 (slash command resolution) is the most precise: a skill is "used" when its content is actually injected to solve a task, not just when it's listed or browsed. The preload path is included because it represents intentional, active use of a skill for a session.

Before

$ grep -rn 'bump_use(' tools/ --include='*.py'
tools/skill_usage.py:277:def bump_use(skill_name: str) -> None:
# ← zero production call sites

# .usage.json: all skills show use_count: 0, last_used_at: null

After

# After invoking /my-skill or loading via --skills:
# .usage.json shows use_count: 1, last_used_at: <timestamp>

Fixes #17782

Changed files

  • agent/skill_commands.py (modified, +10/-0)

PR #17866: fix(skills): wire bump_use() into skill invocation and preload paths (#17782)

Description (problem / solution / changelog)

Summary

bump_use() in tools/skill_usage.py had zero production call sites — it was only called in tests. This meant:

  • use_count stays 0 for all skills
  • last_used_at stays None forever
  • Curator's stale timer (30 days) cannot distinguish "viewed" from "actively used" skills

Meanwhile bump_view() IS wired (from skills_tool.py:1500-1501) and works correctly.

Fix

Wire bump_use() into two code paths in agent/skill_commands.py:

  1. build_skill_command_message() — when user invokes /skill-name and the skill content is loaded for injection
  2. build_preloaded_skills_prompt() — when skills are preloaded at session start via --skill flag or skills.preload config

Both use try/except Exception: pass to match the defensive pattern used by bump_view().

Why These Two Locations

  • build_skill_command_message() is the gateway entry point — called when any slash command resolves to a skill
  • build_preloaded_skills_prompt() is the CLI entry point — called when skills are loaded at session start
  • Together they cover all production paths where skill content is actually used (not just viewed)

Fixes #17782

Changed files

  • agent/skill_commands.py (modified, +12/-0)

PR #17932: fix(skills): wire bump_use() into skill invocation, preload, and skill_view tool (#17782 salvage)

Description (problem / solution / changelog)

Salvage of #17818 by @Bartok9, widened to cover the dominant agent-initiated path.

What

bump_use() in tools/skill_usage.py had zero production call sites — use_count stayed at 0 and last_used_at stayed None for every skill. Since curator's stale timer keys off last_used_at (agent/curator.py:233), every non-pinned agent-created skill would transition to stale simultaneously regardless of actual use.

Changes

  • agent/skill_commands.py — call bump_use() from build_skill_invocation_message (slash command) and build_preloaded_skills_prompt (--skill preload). [@Bartok9's commit]
  • tools/skills_tool.py — also call bump_use() alongside the existing bump_view() in _skill_view_with_bump. This is the dominant path: the agent calling skill_view to load a skill is explicit "I'm using this skill to do work," stronger than passive system-prompt indexing. [widening]

All three bumps are wrapped in try/except — usage telemetry failures never break tool calls.

Validation

BeforeAfter
skill_view tool callview=1, use=0view=1, use=1, last_used_at set
slash invocationuse=0use=1
preload (--skill)use=0use=1

E2E: isolated HERMES_HOME, real agent-created skill, all three paths traced. Unit: scripts/run_tests.sh tests/tools/test_skill_usage.py tests/tools/test_skills_tool.py tests/agent/test_curator.py → 153 passed.

Closes #17782. Supersedes #17866 (same fix, submitted ~2h later) and the overlapping bump_use portion of #17598.

Changed files

  • agent/skill_commands.py (modified, +16/-0)
  • tools/skills_tool.py (modified, +5/-1)

PR #17953: fix: use skill activity in curator status

Description (problem / solution / changelog)

Summary

  • Derive last_activity_at and activity_count from skill use/view/patch telemetry.
  • Use last_activity_at for curator automatic lifecycle transitions, so recently viewed or patched skills are not falsely marked stale.
  • Update hermes curator status and curator candidate rendering to show activity instead of only last_used_at.
  • Add regression coverage for activity derivation, false stale prevention, and CLI status output.

Test Plan

  • /Users/areslee/.hermes/hermes-agent/venv/bin/python -m pytest tests/tools/test_skill_usage.py tests/agent/test_curator_activity.py tests/hermes_cli/test_curator_status.py -q
    • 38 passed
  • /Users/areslee/.hermes/hermes-agent/venv/bin/python -m py_compile tools/skill_usage.py agent/curator.py hermes_cli/curator.py
  • git diff --check
  • Added-lines static scan for secrets/shell/eval/pickle/debugger: no findings
  • Independent review agent: passed, no security concerns or logic errors

Refs #17782 Refs #7816

Fixes #17952

Changed files

  • agent/curator.py (modified, +9/-8)
  • hermes_cli/curator.py (modified, +14/-5)
  • tests/agent/test_curator_activity.py (added, +56/-0)
  • tests/hermes_cli/test_curator_status.py (added, +43/-0)
  • tests/tools/test_skill_usage.py (modified, +20/-0)
  • tools/skill_usage.py (modified, +51/-3)

Code Example

$ grep -rn "bump_use(" tools/ --include="*.py"
tools/skill_usage.py:277:def bump_use(skill_name: str) -> None:
# ← no other hits in tools/

$ grep -rn "bump_use(" tests/ --include="*.py"
tests/tools/test_skill_usage.py:112:    bump_use("my-skill")
tests/tools/test_skill_usage.py:135:    bump_use("skill-b")
tests/tools/test_skill_usage.py:411:    bump_use("from-hub")
tests/tools/test_skill_usage.py:468:        bump_use(name)
# ← only called in tests
RAW_BUFFERClick to expand / collapse

Bug

bump_use() in tools/skill_usage.py is never called from any production code path. It exists and is tested, but has zero call sites outside of tests/tools/test_skill_usage.py.

Impact

  • use_count stays at 0 for all skills in .usage.json
  • last_used_at stays None forever
  • Curator's stale timer (30 days) relies on last_used_at — every non-pinned agent-created skill will transition to stale simultaneously once the timer triggers
  • Curator cannot distinguish "viewed but never used" from "actively used" skills

Evidence

$ grep -rn "bump_use(" tools/ --include="*.py"
tools/skill_usage.py:277:def bump_use(skill_name: str) -> None:
# ← no other hits in tools/

$ grep -rn "bump_use(" tests/ --include="*.py"
tests/tools/test_skill_usage.py:112:    bump_use("my-skill")
tests/tools/test_skill_usage.py:135:    bump_use("skill-b")
tests/tools/test_skill_usage.py:411:    bump_use("from-hub")
tests/tools/test_skill_usage.py:468:        bump_use(name)
# ← only called in tests

Meanwhile bump_view() IS wired (called from skills_tool.py:1500-1501) and works correctly — all 33 agent-created skills in my .usage.json show view_count >= 1.

Proposed Fix

Wire bump_use() into the skill-loading path. Candidates:

  1. skill_commands.py — when a skill slash command is resolved and its content is injected into the prompt as a user message
  2. run_agent.py — when skill content is loaded into the system prompt at session start (though this may be too aggressive — every session start would bump all loaded skills)
  3. skills_tool.py — when skill_manage(action="view") or similar active-use paths are invoked (distinct from passive skill_view)

Option 1 seems most precise: a skill is "used" when its content is actually injected to solve a task, not just when it's listed or browsed.

Environment

  • hermes-agent: current main
  • .usage.json: 33 agent-created skills, all use_count: 0, last_used_at: None

extent analysis

TL;DR

Wire the bump_use() function into the skill-loading path, likely in skill_commands.py, to accurately track skill usage.

Guidance

  • Identify the correct location to call bump_use() based on the application's logic, with skill_commands.py being a promising candidate.
  • Verify that bump_use() is called when a skill is actually used, such as when its content is injected into the prompt as a user message.
  • Consider the implications of calling bump_use() at other points, such as session start or skill viewing, to ensure accurate tracking of skill usage.
  • Test the proposed fix to ensure that use_count and last_used_at are updated correctly in .usage.json.

Example

No code snippet is provided as the issue does not contain sufficient information to generate a specific example.

Notes

The proposed fix assumes that bump_use() is correctly implemented and only needs to be called at the right point in the application's logic. Additional testing and verification may be necessary to ensure the fix works as expected.

Recommendation

Apply the workaround by wiring bump_use() into the skill-loading path, as this will allow for accurate tracking of skill usage and prevent the Curator's stale timer from incorrectly marking skills as stale.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Curator: `bump_use()` has zero production call sites — `use_count` always 0 [5 pull requests, 2 comments, 2 participants]