feat: add workspace-isolated toolhost runtime and capability-gap skill loop
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -13,9 +14,9 @@ import (
|
||||
"laodingbot/internal/llm"
|
||||
"laodingbot/internal/logger"
|
||||
"laodingbot/internal/memory"
|
||||
"laodingbot/internal/runtimews"
|
||||
"laodingbot/internal/toolhost"
|
||||
"laodingbot/internal/tools"
|
||||
"laodingbot/internal/tools/filetool"
|
||||
"laodingbot/internal/tools/shelltool"
|
||||
"laodingbot/internal/transport/feishu"
|
||||
"laodingbot/internal/transport/telegram"
|
||||
)
|
||||
@@ -23,18 +24,29 @@ import (
|
||||
func main() {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
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))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
appLogger, err := logger.New(cfg.LogLevel)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("init logger failed: %v", err))
|
||||
}
|
||||
appLogger = appLogger.WithComponent("main")
|
||||
appLogger.Infof("config loaded; channel=%s, log_level=%s", cfg.MessageChannel, cfg.LogLevel)
|
||||
appLogger.Infof("config loaded; channel=%s, log_level=%s workspace=%s", cfg.MessageChannel, cfg.LogLevel, workspaceRoot)
|
||||
|
||||
store, err := memory.NewSQLiteStore(cfg.SQLitePath, appLogger.WithComponent("memory"))
|
||||
if err != nil {
|
||||
@@ -44,19 +56,44 @@ func main() {
|
||||
defer store.Close()
|
||||
|
||||
toolRegistry := tools.NewRegistry(appLogger.WithComponent("tools.registry"))
|
||||
toolRegistry.Register(filetool.New(cfg.Security.AllowedDirs, appLogger.WithComponent("tools.file")))
|
||||
toolRegistry.Register(shelltool.New(cfg.Security.AllowedCommands, cfg.Security.WorkDir, 15*time.Second, appLogger.WithComponent("tools.shell")))
|
||||
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"},
|
||||
WorkDir: ".",
|
||||
CallTimeout: time.Duration(cfg.ToolCallTimeoutSec) * time.Second,
|
||||
HeartbeatInterval: 5 * time.Second,
|
||||
MaxConcurrency: 4,
|
||||
}, appLogger.WithComponent("toolhost.client"))
|
||||
if err != nil {
|
||||
appLogger.Errorf("init toolhost client failed: %v", err)
|
||||
panic(err)
|
||||
}
|
||||
defer tc.Close()
|
||||
|
||||
listCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
toolInfos, err := tc.ToolList(listCtx)
|
||||
cancel()
|
||||
if err != nil {
|
||||
appLogger.Errorf("toolhost list failed: %v", err)
|
||||
panic(err)
|
||||
}
|
||||
if len(toolInfos) == 0 {
|
||||
panic("toolhost returned empty tool list")
|
||||
}
|
||||
for _, info := range toolInfos {
|
||||
toolRegistry.Register(toolhost.NewRemoteTool(info.Name, info.Description, time.Duration(cfg.ToolCallTimeoutSec)*time.Second, tc))
|
||||
}
|
||||
|
||||
soul, err := knowledge.LoadSoul(cfg.SoulPath)
|
||||
if err != nil {
|
||||
appLogger.Errorf("load soul failed path=%s err=%v", cfg.SoulPath, err)
|
||||
panic(err)
|
||||
}
|
||||
skillsDoc, err := knowledge.LoadSkills(cfg.SkillsDir)
|
||||
if err != nil {
|
||||
appLogger.Errorf("load skills failed dir=%s err=%v", cfg.SkillsDir, 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)
|
||||
@@ -71,8 +108,12 @@ func main() {
|
||||
toolRegistry,
|
||||
soul,
|
||||
skillSet,
|
||||
skillsDoc,
|
||||
cfg.SkillsDir,
|
||||
cfg.ReactMaxSteps,
|
||||
cfg.EnableCapabilityGap,
|
||||
cfg.AutoSkillDir,
|
||||
cfg.GapDraftTriggerCount,
|
||||
time.Duration(cfg.GapClusterLookbackHours)*time.Hour,
|
||||
appLogger.WithComponent("agent"),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user