mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-27 11:22:03 +00:00
Open-ended skill learning across every surface. /learn <free text> takes a description of any source — a directory, a URL, the workflow you just walked the agent through, or pasted notes — and the live agent gathers it with the tools it already has (read_file/search_files, web_extract, the conversation, the pasted text), then authors a SKILL.md via skill_manage following the house authoring standards (<=60-char description, the standard section order, Hermes-tool framing, no invented commands). No engine, no model-tool footprint, works on any terminal backend (local, Docker, remote): /learn builds a standards-guided prompt and hands it to the agent as a normal turn. - agent/learn_prompt.py: shared standards-guided prompt builder - /learn registry entry (both surfaces) + CLI handler (inject onto input queue) + gateway handler (rewrite turn, fall through, /blueprint pattern) - tui_gateway command.dispatch returns a send directive -> TUI + dashboard chat - dashboard Skills page 'Learn a skill' panel (dir + URL + open-ended text) composes a /learn request and runs it in chat - docs (slash-commands ref + skills feature page), 11 targeted tests Inspired by OpenAI Codex's Record & Replay and the /learn concept from #47234 (dir-distillation engine); reworked to be open-ended and engine-free per review.
109 lines
5.5 KiB
Python
109 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""``/learn`` — build the standards-guided prompt that turns whatever the user
|
|
described into a reusable skill.
|
|
|
|
``/learn`` is open-ended. The user can point it at anything they can describe:
|
|
a directory of code, an API doc URL, a workflow they just walked the agent
|
|
through in this conversation, or pasted notes. This module builds ONE prompt
|
|
that instructs the live agent to:
|
|
|
|
1. Gather the sources the user named, using the tools it already has
|
|
(``read_file`` / ``search_files`` for dirs, ``web_extract`` for URLs, the
|
|
current conversation for "what I just did", the user's text for pasted
|
|
material).
|
|
2. Author a single ``SKILL.md`` via ``skill_manage`` that follows the Hermes
|
|
skill-authoring standards (description <=60 chars, the modern section
|
|
order, Hermes-tool framing, no invented commands).
|
|
|
|
There is no separate distillation engine and no model-tool footprint: the
|
|
agent does the work with its existing toolset, so this works identically on
|
|
local, Docker, and remote terminal backends. Every surface (CLI ``/learn``,
|
|
gateway ``/learn``, the dashboard "Learn a skill" panel) calls
|
|
:func:`build_learn_prompt` and feeds the result to the agent as a normal turn.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
# The house-style rules, distilled from AGENTS.md "Skill authoring standards
|
|
# (HARDLINE)" and the hermes-agent-dev new-skill salvage reference. Embedded in
|
|
# the prompt so the agent authors skills the way a maintainer would by hand.
|
|
_AUTHORING_STANDARDS = """\
|
|
Follow the Hermes skill-authoring standards exactly:
|
|
|
|
Frontmatter:
|
|
- name: lowercase-hyphenated, <=64 chars, no spaces.
|
|
- description: ONE sentence, <=60 characters, ends with a period. State the
|
|
capability, not the implementation. No marketing words (powerful,
|
|
comprehensive, seamless, advanced). Do NOT repeat the skill name. If the
|
|
description contains a colon, wrap the whole value in double quotes.
|
|
- version: 0.1.0
|
|
- metadata.hermes.tags: a few Capitalized, Relevant, Tags.
|
|
|
|
Body section order (omit a section only if it genuinely has no content):
|
|
1. "# <Human Title>" then a 2-3 sentence intro: what it does, what it does NOT
|
|
do, and the key dependency stance (e.g. "stdlib only").
|
|
2. "## When to Use" — bullet list of concrete trigger phrases.
|
|
3. "## Prerequisites" — exact env vars, install steps, credentials.
|
|
4. "## How to Run" — the canonical invocation, framed through Hermes tools.
|
|
5. "## Quick Reference" — a flat command/endpoint list, no narration.
|
|
6. "## Procedure" — numbered steps with copy-paste-exact commands.
|
|
7. "## Pitfalls" — known limits, rate limits, things that look broken but aren't.
|
|
8. "## Verification" — a single command/check that proves the skill worked.
|
|
|
|
Hermes-tool framing (this is what makes it a skill, not shell docs):
|
|
- Frame running scripts as "invoke through the `terminal` tool".
|
|
- Use `read_file` (not cat/head/tail), `search_files` (not grep/find/ls),
|
|
`patch` (not sed/awk), `web_extract` (not curl-to-scrape),
|
|
`vision_analyze` for images. Reference these tools by name in backticks.
|
|
- Do NOT name shell utilities the agent already has wrapped.
|
|
|
|
Quality bar:
|
|
- Prefer exact commands, endpoint URLs, function signatures, and config keys
|
|
that appear VERBATIM in the source. NEVER invent flags, paths, or APIs — if
|
|
you didn't see it in the source, don't write it.
|
|
- Keep it tight and scannable: ~100 lines for a simple skill, ~200 for a
|
|
complex one. Don't re-paste the source docs.
|
|
- Don't write a router/index/hub skill that only points at other skills.
|
|
- Larger scripts/parsers belong in a `scripts/` file (add via
|
|
`skill_manage` write_file), referenced from SKILL.md by relative path — not
|
|
inlined for the agent to re-type every run."""
|
|
|
|
|
|
def build_learn_prompt(user_request: str) -> str:
|
|
"""Build the agent prompt for an open-ended ``/learn`` request.
|
|
|
|
Args:
|
|
user_request: the free-text the user gave after ``/learn`` — a
|
|
description of the workflow, paths, URLs, or "what I just did".
|
|
|
|
Returns:
|
|
A complete instruction the agent runs as a normal turn. The agent
|
|
gathers the described sources with its existing tools and authors the
|
|
skill via ``skill_manage``.
|
|
"""
|
|
req = (user_request or "").strip()
|
|
if not req:
|
|
req = (
|
|
"the workflow we just went through in this conversation — review "
|
|
"the steps taken and distill them into a reusable skill"
|
|
)
|
|
|
|
return (
|
|
"[/learn] The user wants you to learn a reusable skill from the "
|
|
"source(s) they described below, and save it.\n\n"
|
|
f"WHAT TO LEARN FROM:\n{req}\n\n"
|
|
"Do this:\n"
|
|
"1. Gather the material. Resolve whatever the user named using the "
|
|
"tools you already have — `read_file`/`search_files` for local files "
|
|
"or directories, `web_extract` for URLs, the current conversation "
|
|
"history if they referred to something you just did, and the text "
|
|
"they pasted as-is. If the request is ambiguous about scope, make a "
|
|
"reasonable choice and note it; do not stall.\n"
|
|
"2. Author ONE SKILL.md and save it with the `skill_manage` tool "
|
|
"(action=\"create\"). Pick a sensible category. If the procedure needs "
|
|
"a non-trivial script, add it under the skill's `scripts/` with "
|
|
"`skill_manage` write_file and reference it by relative path.\n\n"
|
|
f"{_AUTHORING_STANDARDS}\n\n"
|
|
"When done, tell the user the skill name, its category, and a "
|
|
"one-line summary of what it captured."
|
|
)
|