shell: support Windows cmd /C; normalize date/time; allow all commands; add tests
This commit is contained in:
@@ -21,19 +21,26 @@ import (
|
||||
"laodingbot/internal/transport/telegram"
|
||||
)
|
||||
|
||||
// main 是程序的入口点。它负责初始化环境、加载配置、注册工具并启动消息通道。
|
||||
func main() {
|
||||
// 设置优雅监听上下文,接收中断和终止信号
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
// 检查是否作为 Toolhost 的子进程运行
|
||||
isToolhostChild := len(os.Args) > 1 && os.Args[1] == "--toolhost"
|
||||
workspaceRoot, err := runtimews.PrepareFromEnv()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("prepare runtime workspace failed: %v", err))
|
||||
}
|
||||
|
||||
// 加载应用配置
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("load config failed: %v", err))
|
||||
}
|
||||
|
||||
// 如果是作为子进程运行,则启动工具宿主端
|
||||
if isToolhostChild {
|
||||
if err := toolhost.RunChild(ctx, cfg, nil); err != nil && ctx.Err() == nil {
|
||||
panic(fmt.Sprintf("toolhost child failed: %v", err))
|
||||
@@ -41,6 +48,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// 初始化日志系统
|
||||
appLogger, err := logger.New(cfg.LogLevel)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("init logger failed: %v", err))
|
||||
@@ -48,6 +56,7 @@ func main() {
|
||||
appLogger = appLogger.WithComponent("main")
|
||||
appLogger.Infof("config loaded; channel=%s, log_level=%s workspace=%s", cfg.MessageChannel, cfg.LogLevel, workspaceRoot)
|
||||
|
||||
// 初始化 SQLite 数据库存储层(例如记忆存储等)
|
||||
store, err := memory.NewSQLiteStore(cfg.SQLitePath, appLogger.WithComponent("memory"))
|
||||
if err != nil {
|
||||
appLogger.Errorf("init memory store failed: %v", err)
|
||||
@@ -55,12 +64,15 @@ func main() {
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
// 注册内部系统工具
|
||||
toolRegistry := tools.NewRegistry(appLogger.WithComponent("tools.registry"))
|
||||
exePath, err := os.Executable()
|
||||
if err != nil {
|
||||
appLogger.Errorf("resolve executable path failed: %v", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 初始化工具宿主客户端,以便运行独立进程内的工具
|
||||
tc, err := toolhost.NewClient(toolhost.ClientConfig{
|
||||
ExecutablePath: exePath,
|
||||
Args: []string{"--toolhost"},
|
||||
@@ -75,6 +87,7 @@ func main() {
|
||||
}
|
||||
defer tc.Close()
|
||||
|
||||
// 获取支持的工具列表并将其注册
|
||||
listCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
toolInfos, err := tc.ToolList(listCtx)
|
||||
cancel()
|
||||
@@ -89,25 +102,37 @@ func main() {
|
||||
toolRegistry.Register(toolhost.NewRemoteTool(info.Name, info.Description, time.Duration(cfg.ToolCallTimeoutSec)*time.Second, tc))
|
||||
}
|
||||
|
||||
// 加载 AI 角色的基础信息 (Soul)
|
||||
soul, err := knowledge.LoadSoul(cfg.SoulPath)
|
||||
if err != nil {
|
||||
appLogger.Errorf("load soul failed path=%s err=%v", cfg.SoulPath, err)
|
||||
panic(err)
|
||||
}
|
||||
// 加载所有可用技能
|
||||
skillSet, err := knowledge.LoadSkillSet(cfg.SkillsDir)
|
||||
if err != nil {
|
||||
appLogger.Errorf("load skill set failed dir=%s err=%v", cfg.SkillsDir, err)
|
||||
panic(err)
|
||||
}
|
||||
// 加载技能总结,用于后续路由和匹配
|
||||
skillSummaries, err := knowledge.LoadSkillSummaries(cfg.SkillsDir)
|
||||
if err != nil {
|
||||
appLogger.Errorf("load skill summaries failed dir=%s err=%v", cfg.SkillsDir, err)
|
||||
panic(err)
|
||||
}
|
||||
appLogger.Infof("knowledge loaded soul_path=%s skills_dir=%s", cfg.SoulPath, cfg.SkillsDir)
|
||||
|
||||
// 实例化 LLM 客户端
|
||||
llmClient := llm.NewOpenAICompatibleClient(cfg.LLM, appLogger.WithComponent("llm"))
|
||||
|
||||
// 创建编排器,整合 LLM、记忆系统、知识技能库与各种工具
|
||||
engine := agent.NewOrchestrator(
|
||||
llmClient,
|
||||
store,
|
||||
toolRegistry,
|
||||
soul,
|
||||
skillSet,
|
||||
skillSummaries,
|
||||
cfg.SkillsDir,
|
||||
cfg.ReactMaxSteps,
|
||||
cfg.EnableCapabilityGap,
|
||||
@@ -118,6 +143,7 @@ func main() {
|
||||
)
|
||||
|
||||
appLogger.Infof("LaodingBot started, channel=%s", cfg.MessageChannel)
|
||||
// 根据配置启动对应的信息通道
|
||||
if err := runMessageChannel(ctx, cfg, engine, appLogger); err != nil && ctx.Err() == nil {
|
||||
appLogger.Errorf("message channel run failed: %v", err)
|
||||
panic(err)
|
||||
@@ -125,6 +151,7 @@ func main() {
|
||||
appLogger.Infof("LaodingBot stopped")
|
||||
}
|
||||
|
||||
// runMessageChannel 负责初始化并运行配置指定的消息通道(如 telegram 或 feishu)。
|
||||
func runMessageChannel(ctx context.Context, cfg config.Config, engine *agent.Orchestrator, lg *logger.Logger) error {
|
||||
switch cfg.MessageChannel {
|
||||
case "telegram":
|
||||
|
||||
Reference in New Issue
Block a user