gitdataai/libs/agent/skills/mod.rs
ZhenYi afad0ab55d feat(agent): implement built-in skills system (16 skills)
Add built-in skills with trigger-based activation system:

Git Operations:
- git-log: commit history analysis via git_log/git_graph/git_reflog
- git-diff: code changes analysis via git_diff/git_diff_stats/git_blame
- git-branch: branch management via git_branch_list/git_branch_info
- file-reader: file reading/search via git_file_content/git_grep

Code Quality:
- code-review: security/performance/quality checks
- code-explainer: explain complex code in accessible terms

Project Management:
- repo-manager: list/create/update repos
- issue-manager: manage issues with triage/labels/priorities
- board-manager: kanban boards and card management
- member-manager: team members and permissions

Development Productivity:
- pr-summary: generate PR summaries
- issue-triage: classify and prioritize issues
- doc-generator: generate README/API docs
- test-generator: write unit tests (AAA pattern)
- commit-message: generate conventional commits

Utilities:
- http-requester: HTTP requests and API testing

Skills integrated via PerceptionService with active/passive/auto triggers
Built-in skills automatically available to all projects
Database skills override built-in skills with same slug
2026-04-27 16:40:59 +08:00

154 lines
5.1 KiB
Rust

//! Built-in skills for the AI agent.
//!
//! This module provides pre-defined, system-level skills that can be
//! automatically enabled for projects or selectively injected based on context.
//!
//! # Built-in Skills
//!
//! ## Git Operations
//! - `git-log`: Analyze commit history and understand code evolution
//! - `git-diff`: Understand code changes between commits or branches
//! - `git-branch`: Manage branches and understand branch relationships
//! - `file-reader`: Read file contents and search for patterns in code
//!
//! ## Code Quality
//! - `code-review`: Expert code review with security, performance, and quality checks
//! - `code-explainer`: Explain complex code in simple, accessible terms
//!
//! ## Project Management
//! - `repo-manager`: List, create, and manage project repositories
//! - `issue-manager`: Manage issues with triage, labels, and priorities
//! - `board-manager`: Manage project boards, cards, and kanban workflows
//! - `member-manager`: Manage team members, roles, and permissions
//!
//! ## Development Productivity
//! - `pr-summary`: Generate clear PR summaries
//! - `issue-triage`: Classify and prioritize issues
//! - `doc-generator`: Generate README and API documentation
//! - `test-generator`: Write comprehensive unit tests
//! - `commit-message`: Generate conventional commit messages
//!
//! ## Utilities
//! - `http-requester`: Make HTTP requests and test APIs
//!
//! # Trigger System
//!
//! Skills are activated through three mechanisms:
//!
//! ## 1. Active Triggers (Highest Priority)
//! User explicitly invokes a skill:
//! - `用 code-review` / `use code-review`
//! - `@code-review` / `skill:code-review`
//! - Natural language: "帮我做 code review"
//!
//! ## 2. Passive Triggers (Medium Priority)
//! Tool calls trigger related skills:
//! - Tool `git_diff` called → activates `git-diff` skill
//! - Tool `list_issues_exec` called → activates `issue-manager` skill
//!
//! ## 3. Auto Triggers (Background)
//! Keyword matching based on conversation context:
//! - Configurable overlap threshold (default: 0.15)
//! - Maximum auto-injected skills (default: 3)
//!
//! # Usage
//!
//! ```rust,ignore
//! use agent::{get_skill, is_built_in_skill, all_skill_slugs};
//!
//! // Check if a slug is a built-in skill
//! if is_built_in_skill("code-review") {
//! let skill = get_skill("code-review").unwrap();
//! // Use skill.name, skill.description, skill.content
//! }
//!
//! // List all built-in skills
//! for slug in all_skill_slugs() {
//! println!("Available: {}", slug);
//! }
//! ```
mod templates;
pub use templates::BuiltInSkill;
pub use templates::SKILL_TEMPLATES;
/// Get a built-in skill by its slug.
pub fn get_skill(slug: &str) -> Option<&'static BuiltInSkill> {
SKILL_TEMPLATES.get(slug)
}
/// Get all built-in skill slugs.
pub fn all_skill_slugs() -> impl Iterator<Item = &'static str> {
SKILL_TEMPLATES.keys().copied()
}
/// Get all built-in skills.
pub fn all_skills() -> impl Iterator<Item = &'static BuiltInSkill> {
SKILL_TEMPLATES.values()
}
/// Check if a slug corresponds to a built-in skill.
pub fn is_built_in_skill(slug: &str) -> bool {
SKILL_TEMPLATES.contains_key(slug)
}
/// Check if a tool name should trigger any built-in skill.
/// Returns the skill slug if found.
pub fn get_skill_by_tool(tool_name: &str) -> Option<&'static BuiltInSkill> {
for skill in SKILL_TEMPLATES.values() {
if skill.trigger_tools.iter().any(|t| *t == tool_name) {
return Some(skill);
}
}
None
}
/// Check if any keyword matches a built-in skill.
/// Returns the best matching skill based on keyword overlap.
pub fn match_skill_by_keyword(keywords: &[&str]) -> Option<&'static BuiltInSkill> {
let mut best_match: Option<&BuiltInSkill> = None;
let mut best_score = 0;
for skill in SKILL_TEMPLATES.values() {
let score = skill
.trigger_keywords
.iter()
.filter(|kw| {
keywords.iter().any(|k| k.to_lowercase().contains(&kw.to_lowercase()))
})
.count();
if score > best_score {
best_score = score;
best_match = Some(skill);
}
}
if best_score > 0 {
best_match
} else {
None
}
}
/// Get skills grouped by category.
pub fn skills_by_category() -> std::collections::HashMap<&'static str, Vec<&'static BuiltInSkill>> {
let mut categories: std::collections::HashMap<&'static str, Vec<&'static BuiltInSkill>> =
std::collections::HashMap::new();
for skill in SKILL_TEMPLATES.values() {
let category = match skill.slug {
"git-log" | "git-diff" | "git-branch" => "Git Operations",
"code-review" | "code-explainer" => "Code Quality",
"repo-manager" | "issue-manager" | "board-manager" | "member-manager" => "Project Management",
"pr-summary" | "issue-triage" | "doc-generator" | "test-generator" | "commit-message" => "Development Productivity",
"file-reader" | "http-requester" => "Utilities",
_ => "Other",
};
categories.entry(category).or_default().push(skill);
}
categories
}