2026-05-09 03:55:56 +08:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"os"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
"syscall"
|
|
|
|
|
|
|
|
|
|
|
|
"hub.gaomia.site/titor/YunShu/pkg/style"
|
|
|
|
|
|
"hub.gaomia.site/titor/YunShu/pkg/termui"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-05-09 03:58:21 +08:00
|
|
|
|
const version = "1.1.0"
|
2026-05-09 03:55:56 +08:00
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|