Files
YunShu/main.go
titor d2b9b2c4bb 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*
2026-05-09 03:55:56 +08:00

147 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"fmt"
"os"
"strings"
"syscall"
"hub.gaomia.site/titor/YunShu/pkg/style"
"hub.gaomia.site/titor/YunShu/pkg/termui"
)
const version = "1.0.0"
func init() {
kernel32 := syscall.NewLazyDLL("kernel32.dll")
setConsoleCP := kernel32.NewProc("SetConsoleOutputCP")
setConsoleCP.Call(65001)
}
func printHelp() {
fmt.Println()
fmt.Println(style.Cyan.Render("☁ 云枢·Agent"), style.Dim.Render("v"+version))
fmt.Println()
fmt.Println(style.Bold.Render("用法:"))
fmt.Println(" yunshu [命令] [查询内容]")
fmt.Println()
fmt.Println(style.Bold.Render("命令:"))
fmt.Println(" onboard 交互式初始化配置")
fmt.Println(" help, -h 显示帮助信息")
fmt.Println(" version, -v 显示版本号")
fmt.Println()
fmt.Println(style.Bold.Render("示例:"))
fmt.Println(" yunshu \"北京今天天气\" ", style.Dim.Render("单次天气查询"))
fmt.Println(" yunshu ", style.Dim.Render("启动交互模式"))
fmt.Println(" yunshu onboard ", style.Dim.Render("重新初始化配置"))
fmt.Println()
fmt.Println(style.Bold.Render("环境变量:"))
fmt.Println(" LLM_API_KEY API Key优先级高于配置文件")
fmt.Println(" LLM_ENDPOINT API 端点")
fmt.Println(" LLM_MODEL 模型名")
fmt.Println()
fmt.Println(style.Bold.Render("配置文件:"), "~/.config/yunshu/config.yaml")
fmt.Println()
}
func printVersion() {
fmt.Println("yunshu", version)
}
func main() {
args := os.Args[1:]
if len(args) > 0 {
switch args[0] {
case "onboard":
runOnboard()
return
case "help", "--help", "-h":
printHelp()
return
case "version", "--version", "-v":
printVersion()
return
default:
if strings.HasPrefix(args[0], "-") {
fmt.Fprintln(os.Stderr, style.Red.Render("未知选项: "+args[0]))
fmt.Fprintln(os.Stderr, "可用命令: onboard, help, version")
os.Exit(1)
}
}
}
cfg, err := LoadConfig()
if err != nil {
fmt.Fprintln(os.Stderr, style.Red.Render("未找到配置文件。请先运行:"))
fmt.Fprintln(os.Stderr, " yunshu onboard")
os.Exit(1)
}
_ = cfg
GenerateToolsYAML()
agentPath := SearchFile("agents/weather-agent.md")
def, err := LoadAgent(agentPath)
if err != nil {
fmt.Fprintln(os.Stderr, style.Red.Render("加载 agent 失败: "+err.Error()))
os.Exit(1)
}
if len(args) > 0 {
ClearSession()
query := strings.Join(args, " ")
if err := RunAgent(def, query); err != nil {
fmt.Fprintln(os.Stderr, style.Red.Render("错误: "+err.Error()))
os.Exit(1)
}
return
}
fmt.Println()
fmt.Println(style.Cyan.Render("☁ 云枢·Agent"), style.Dim.Render("· 天气情报官"))
fmt.Println(style.Dim.Render(" /exit 退出,// 开头的行不发给 LLM"))
fmt.Println()
ClearSession()
for {
fmt.Print(style.Cyan.Render(" "))
input := termui.ReadLine()
input = strings.TrimSpace(input)
if input == "" {
continue
}
if strings.HasPrefix(input, "//") {
continue
}
switch input {
case "/exit", "exit", "quit":
fmt.Println("再见!")
fmt.Println()
return
case "/clear":
ClearSession()
fmt.Print("\033[2J\033[H")
fmt.Println(style.Dim.Render("会话已清空"))
fmt.Println()
continue
case "/help":
fmt.Println("可用命令:")
fmt.Println(" /exit 退出")
fmt.Println(" /clear 清空会话")
fmt.Println(" /help 显示帮助")
fmt.Println(" // 不发给 LLM 的注释行")
fmt.Println()
continue
}
if err := RunAgent(def, input); err != nil {
fmt.Fprintln(os.Stderr, style.Red.Render("错误: "+err.Error()))
}
fmt.Println()
}
}