refactor: 项目结构重组,src/ 扁平化为根目录,提取 pkg/ 子包
- 模块名重命名 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*
This commit is contained in:
76
loader.go
Normal file
76
loader.go
Normal file
@@ -0,0 +1,76 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user