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() } }