-
Notifications
You must be signed in to change notification settings - Fork 6k
feat: Add built-in skill for goose documentation reference #6534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
d13e888
41d980b
1bc6394
a0d92a2
edc28dc
ca0f4ca
c1b06f8
f294d5b
3dcb94b
6107566
05b078c
94bdc32
79b23fe
5503238
d7da411
0fd20e4
53e6f1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| --- | ||
| name: goose-doc-guide | ||
| description: Reference goose documentation to create, configure, or explain goose-specific features like recipes, extensions, sessions, and providers. You MUST fetch relevant goose docs before answering. You MUST NOT rely on training data or assumptions for any goose-specific fields, values, names, syntax, or commands. | ||
| --- | ||
|
|
||
| Use this skill when working with **goose-specific features**: | ||
| - Creating or editing recipes | ||
| - Configuring extensions or providers | ||
| - Explaining how goose features work | ||
| - Any goose configuration or setup task | ||
|
|
||
| Do NOT use this skill for: | ||
| - General coding tasks unrelated to goose | ||
| - Running existing recipes (just run them directly) | ||
|
|
||
| ## Steps (COMPLETE ALL BEFORE RESPONDING) | ||
| 1. **Fetch official docs** | ||
| - Fetch the doc map from `https://block.github.io/goose/goose-docs-map.md` | ||
| - Search the doc map for pages relevant to the user's topic and get the paths for these pages | ||
| - Use the EXACT paths from the doc map. For example: | ||
| - If doc map shows: `docs/guides/sessions/session-management.md` | ||
| - Fetch: `https://block.github.io/goose/docs/guides/sessions/session-management.md` | ||
| - Do NOT modify or guess paths. | ||
| - **ONLY fetch paths that are explicitly listed in the doc map - do not guess or infer URLs** | ||
| - Make multiple fetch calls in parallel and save to temp files | ||
| - Use the temp files for subsequent searches instead of re-fetching | ||
|
|
||
| 2. **Create/modify content** | ||
| - For goose configuration files: | ||
| - Consult schema/field reference documentation first | ||
| - **Search the fetched docs to extract the complete schema for each element you plan to use** | ||
| - Extract example snippets to understand usage patterns | ||
| - Create your configuration based on reference specs, following example patterns | ||
| - **⚠️ STOP: Before showing the user, verify output content MUST match the schema and reference in the goose official documentation:** | ||
| - [ ] Field names match exactly as shown in docs | ||
| - [ ] Required fields/properties are present | ||
| - [ ] Value formats match examples (YAML/JSON syntax, data types, etc.) | ||
| - **If ANY verification fails, revise and repeat this step until ALL verifications pass** | ||
| - **DO NOT present unverified output to the user** | ||
|
|
||
| 3. **MANDATORY VERIFICATION - CHECK ALL THESE ITEMS BEFORE STEP 4** | ||
| Before writing your final answer: | ||
| - [ ] You MUST NOT rely on training data or assumptions for any goose-specific fields, values, names, syntax, or commands. | ||
| - [ ] **Did you include "How to Use", CLI commands, or usage instructions?** | ||
| - If YES and user didn't ask for it → **REMOVE IT NOW** | ||
| - If YES and user asked for it → verify exact commands from fetched docs before including | ||
| - [ ] List all goose-specific items in your answer (commands, fields, syntax, values, how to use, explanations, etc.) | ||
| - [ ] For each item, verify it is correct according to the fetched docs. If not found, either fetch the relevant docs NOW and verify, or remove it (if user asked for it, state "I could not find documentation for [X]"). | ||
|
|
||
| 4. **Provide your answer and include a "Verification Completed" section** | ||
| - For EACH goose-specific item in your response, cite the specific doc file where you verified it | ||
|
|
||
| 5. **List documentation links** | ||
| - Only include docs actually used | ||
| - Remove `.md` suffix from URLs | ||
| - Example: If you fetched `https://block.github.io/goose/docs/guides/sessions/session-management.md`, list it as `https://block.github.io/goose/docs/guides/sessions/session-management` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| use include_dir::{include_dir, Dir}; | ||
|
|
||
| static BUILTIN_SKILLS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/src/agents/builtin_skills"); | ||
|
|
||
| pub fn get_all_builtin_skills() -> Vec<&'static str> { | ||
| BUILTIN_SKILLS_DIR | ||
| .files() | ||
| .filter(|f| f.path().extension().is_some_and(|ext| ext == "md")) | ||
| .filter_map(|f| f.contents_utf8()) | ||
| .collect() | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,4 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use super::builtin_skills; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::agents::extension::PlatformExtensionContext; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::agents::mcp_client::{Error, McpClientTrait}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::config::paths::Paths; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -65,17 +66,38 @@ impl SkillsClient { | |||||||||||||||||||||||||||||||||||||||||||||||||||
| instructions: Some(String::new()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut skills = Self::load_builtin_skills(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| let directories = Self::get_default_skill_directories() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .into_iter() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter(|d| d.exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .collect::<Vec<_>>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| let skills = Self::discover_skills_in_directories(&directories); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| let fs_skills = Self::discover_skills_in_directories(&directories); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| skills.extend(fs_skills); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+76
to
77
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| skills.extend(fs_skills); | |
| // Merge filesystem-discovered skills, warning if they shadow builtin skills. | |
| for (name, skill) in fs_skills { | |
| if skills.contains_key(&name) { | |
| eprintln!( | |
| "Warning: filesystem skill \"{}\" overrides builtin skill with the same name", | |
| name | |
| ); | |
| } | |
| skills.insert(name, skill); | |
| } |
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Errors during built-in skill parsing are silently ignored. If a built-in skill file has invalid frontmatter, it will fail to load without any logging or error reporting. Consider logging parse failures or returning a Result to surface issues during development.
| if let Ok((metadata, body)) = Self::parse_frontmatter(content) { | |
| skills.insert( | |
| metadata.name.clone(), | |
| Skill { | |
| metadata, | |
| body, | |
| directory: PathBuf::new(), | |
| supporting_files: vec![], | |
| }, | |
| ); | |
| match Self::parse_frontmatter(content) { | |
| Ok((metadata, body)) => { | |
| skills.insert( | |
| metadata.name.clone(), | |
| Skill { | |
| metadata, | |
| body, | |
| directory: PathBuf::new(), | |
| supporting_files: vec![], | |
| }, | |
| ); | |
| } | |
| Err(e) => { | |
| tracing::warn!(error = ?e, "Failed to parse built-in skill frontmatter; built-in skill will be skipped"); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
mod.rsfile will be included in the embedded directory byinclude_dir!. This means the filter on line 8 will seemod.rs(without.mdextension) in addition to.mdfiles. While this works becausemod.rsis filtered out by the extension check, it's worth noting that the directory being embedded includes the Rust source file itself.This is not a bug but could be surprising. Consider adding a comment explaining that the macro embeds the entire directory including
mod.rs, which is filtered out at runtime.