feat(skills): /learn — distill a verified skill from directories of source material - #47234
feat(skills): /learn — distill a verified skill from directories of source material#47234teknium1 wants to merge 2 commits into
Conversation
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
1 |
unresolved-attribute |
1 |
First entries
tests/agent/test_skill_distill.py:14: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
gateway/slash_commands.py:2319: [unresolved-attribute] unresolved-attribute: Object of type `Self@_handle_learn_command` has no attribute `config`
✅ Fixed issues: none
Unchanged: 5775 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
680f5b1 to
3ee49f0
Compare
…ource material Point Hermes at directories of source material (code, API docs, manuals, PDFs, configs) and it distills a reusable skill: ingest + classify -> draft SKILL.md via the main model -> sandboxed verification -> commit only when the verification tier meets the floor. Surfaces (all call the shared agent/skill_distill.py engine): - CLI: `hermes learn <dirs> [--hint --category --run --min-tier --json]` - In-session /learn slash command (CLI + TUI + every messaging platform) - Dashboard: Skills tab 'Learn from sources' dialog + /api/skills/learn endpoint Verification is an honest tier (executed / checked / unverified / failed), stamped into the skill frontmatter; never claims 'tested' when only parsed. --run executes only allowlisted read-only snippets in a throwaway temp dir, and is admin-gated over the gateway. Zero new model tools (footprint ladder rung 2). Synthesis uses call_llm(task='skill_distill') so it's main-model-first and cache-safe. 13 targeted engine tests; live-tested CLI + gateway end-to-end (reached the 'executed' tier in a sandbox).
The startup-plugin-gating test requires every live CLI subcommand to be in _BUILTIN_SUBCOMMANDS so plugin discovery is skipped when the user targets a builtin. Add 'learn'.
3ee49f0 to
9f08fc9
Compare
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Comment (high surface area)
What was changed
New skill: /learn — distill a verified skill from directories of source material. This is a major new skill that can ingest a directory of source code/text and produce a working SKILL.md file. 1615 additions across 14 files.
Observations
This is a substantial new feature (SKILL.md generation from source material). The implementation includes:
- A new
/learnCLI command - Skill distillation logic (reading source files, analyzing patterns, generating documentation)
- Template-based output (produces
.skills/SKILL.mdformat)
Given the complexity of the skill generation (prompt engineering, file selection, template rendering), the output quality depends heavily on the distillation prompt.
High-surface-area note
14 files, 1615 additions. As a new major skill, recommend thorough testing of edge cases:
- Empty directories
- Non-code files mixed with code
- Very large files (>10k lines)
- Binary/non-text files in source directories
The print() statements in the diff appear to be user-facing progress output (which is expected for an interactive CLI tool), not debug artifacts.
Security
No hardcoded secrets or credentials. The skill reads local files and generates documentation — no network I/O or credential handling.
Reviewed by Hermes Agent
|
Superseded by #51506 (merged: e32ebc6). Reworked /learn to be open-ended and engine-free per review: instead of a directory-only distillation engine, /learn now takes anything you can describe (a dir, a URL, the workflow you just walked the agent through, pasted notes) and the live agent gathers it with its own tools and authors the SKILL.md via skill_manage. No engine, no model-tool footprint, works on any terminal backend (local/Docker/remote). Includes the dashboard Skills-page 'Learn a skill' panel. |
Summary
Adds
/learn— feed Hermes directories of source material (code, API docs, manuals, PDFs, configs) and it distills a verified reusable skill instead of you writing one by hand.The flow: ingest + classify sources → assemble a token-budgeted corpus → synthesize a draft
SKILL.mdvia the main model → verify it in a throwaway sandbox → commit the skill only when the verification tier meets the floor.All surfaces call one shared engine (
agent/skill_distill.py) — zero new model tools (footprint-ladder rung 2: CLI command + skill-producing engine).Surfaces
hermes learn <dir> [dir ...] [--hint --category --run --min-tier --json]/learnslash command — works in CLI, the Ink TUI, and every messaging platform (registry-driven; TUI forwards via the slash worker →cli.process_command)POST /api/skills/learnendpointHonest verification (not a boolean)
Each distilled skill is stamped with the tier it actually reached:
executedcheckedunverifiedfailedDefault commit floor is
checked.--runexecutes only allowlisted read-only snippets (--version,--help,ls, …) in a temp dir; destructive/network-mutating commands are never auto-run, and--runis admin-gated over the gateway.Design notes
call_llm(task="skill_distill")→ main-model-first, cache-safe, no conversation-prompt-cache invalidation. Per-task override viaauxiliary.skill_distill.*.tools.skill_manager_tool._create_skill(validation + security scan).skills.distill.*inconfig.yaml.Changes
agent/skill_distill.py(new): ingest/classify, corpus, synth, sandbox verify, stamp, commit, shared rendererhermes_cli/subcommands/learn.py(new) +main.pywiring +commands.pyregistry entrycli.py+hermes_cli/cli_commands_mixin.py:/learnin-session handlergateway/run.py+gateway/slash_commands.py: gateway/learn(admin-gated--run, runs in executor)ui-tui/src/app/slash/commands/ops.ts: TUI/learncommandweb/src/lib/api.ts+web/src/pages/SkillsPage.tsx: dashboard dialog + API method/typehermes_cli/web_server.py:/api/skills/learnendpointwebsite/docs/user-guide/features/skills.md: docstests/agent/test_skill_distill.py(new): 13 targeted testsValidation
hermes learnagainst a real source dir — synthesized + committed a valid skill with the tier stamped; gateway handler live-tested through a fake messenger event and reached theexecutedtier by running snippets in the sandboxInfographic