- 模块名重命名 yunshu -> hub.gaomia.site/titor/YunShu - Go 版本升级 1.21 -> 1.25 - src/ 目录删除,所有文件移至根目录 - 新增 pkg/mdprint/: Markdown AST 解析+ANSI 渲染 - 新增 pkg/style/: 终端颜色样式(8色 ANSI + 24位真彩色) - 新增 pkg/termui/: 终端输入组件(交互式输入/密码/确认) - 更新文档:AGENTS.md、architecture.md、changelog.md、taolun.md - gitignore 通配符修复 yunshu.exe -> yunshu.exe*
77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"strings"
|
||
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// LoadAgent 从 .md 文件加载 agent 定义
|
||
// 搜索结果:项目目录 → 全局配置目录
|
||
func LoadAgent(name string) (*AgentDef, error) {
|
||
path := SearchFile(name)
|
||
data, err := os.ReadFile(path)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("读取 agent 文件失败 (搜索路径: %s): %w", name, err)
|
||
}
|
||
|
||
content := string(data)
|
||
frontmatter, body, err := parseFrontmatter(content)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
def := &AgentDef{SystemPrompt: strings.TrimSpace(body)}
|
||
if err := yaml.Unmarshal([]byte(frontmatter), def); err != nil {
|
||
return nil, fmt.Errorf("解析 frontmatter 失败: %w", err)
|
||
}
|
||
|
||
if def.Name == "" {
|
||
return nil, fmt.Errorf("agent 定义缺少 name 字段")
|
||
}
|
||
|
||
// 注入能力边界目录到 system prompt
|
||
def.SystemPrompt += BuildInjectPrompt(def.Tools)
|
||
|
||
return def, nil
|
||
}
|
||
|
||
func parseFrontmatter(content string) (string, string, error) {
|
||
lines := strings.Split(content, "\n")
|
||
if len(lines) < 2 || strings.TrimSpace(lines[0]) != "---" {
|
||
return "", content, nil
|
||
}
|
||
|
||
endIdx := -1
|
||
for i := 1; i < len(lines); i++ {
|
||
if strings.TrimSpace(lines[i]) == "---" {
|
||
endIdx = i
|
||
break
|
||
}
|
||
}
|
||
if endIdx == -1 {
|
||
return "", content, nil
|
||
}
|
||
|
||
frontmatter := strings.Join(lines[1:endIdx], "\n")
|
||
body := strings.Join(lines[endIdx+1:], "\n")
|
||
return frontmatter, body, nil
|
||
}
|
||
|
||
// LoadSkill 按名称加载 skill 知识内容
|
||
// 搜索结果:skills/<name>/SKILL.md → ~/.config/weather-cli/skills/<name>/SKILL.md
|
||
func LoadSkill(name string) (string, error) {
|
||
relativePath := fmt.Sprintf("skills/%s/SKILL.md", name)
|
||
path := SearchFile(relativePath)
|
||
|
||
data, err := os.ReadFile(path)
|
||
if err != nil {
|
||
return "", fmt.Errorf("skill %q 未找到", name)
|
||
}
|
||
|
||
_, body, _ := parseFrontmatter(string(data))
|
||
return strings.TrimSpace(body), nil
|
||
}
|