// Package agentcli 是 Agent CLI 引擎的顶层入口。 // Logan.Li // 组装 llm 客户端 + 工具注册中心(含 ssh_execute)+ 安全控制器 + Evolver + ReAct 核心, // 对外暴露 Engine,由 controller 通过依赖注入(EventCallback / ConfirmFn / SSH 凭据)驱动。 // // 设计原则(参考 opsxcli,适配为 aiops 后端库): // - 零业务依赖:不 import model/controller,所有持久化与 WS 由 controller 层负责。 // - 复用 aiops 既有能力:LLM 走 OpenAI 兼容(model.LLMConfig),SSH 走 pkg/remoteexec。 // - 安全:危险命令黑名单硬拒,高危命令经 ConfirmFn 由前端确认。 // - 自进化:Evolver 异步学习经验并注入下次 Prompt,失败优雅降级。 package agentcli import ( "context" "fmt" "ezops/pkg/agentcli/core" "ezops/pkg/agentcli/evolver" "ezops/pkg/agentcli/llm" "ezops/pkg/agentcli/safety" "ezops/pkg/agentcli/tools" k8sclient "ezops/pkg/kubernetesclient" "ezops/pkg/remoteexec" ) // RunMode Agent 运行模式 // Logan.Li const ( RunModeHost = "host" RunModeKubernetes = "kubernetes" ) // NormalizeRunMode 规范化运行模式(兼容旧 k8s 参数) // Logan.Li func NormalizeRunMode(mode string) string { if mode == "k8s" || mode == RunModeKubernetes { return RunModeKubernetes } if mode == "" { return RunModeHost } return mode } // KubernetesTarget Kubernetes 模式目标上下文(由 controller 注入) // Logan.Li type KubernetesTarget struct { Client *k8sclient.Client ClusterName string Namespace string PodName string Container string } // EngineConfig 引擎配置(由 controller 从 model.LLMConfig + 目标上下文构建后注入) // Logan.Li type EngineConfig struct { Mode string // host | kubernetes LLM llm.Config // LLM 客户端配置(endpoint 已解析) SSH remoteexec.SSHConfig // 主机模式 SSH 配置 Kubernetes *KubernetesTarget // Kubernetes 模式目标 SafetyMode safety.Mode // 安全模式(默认 balanced) Core *core.Config // ReAct 配置(nil 用默认) MemoryDir string // Evolver 记忆目录(空则 data/agentcli) } // Engine Agent CLI 引擎实例(每个 WebSocket 连接 / 任务一个) // Logan.Li type Engine struct { agent *core.Agent safety *safety.Controller tools *tools.Registry evolver *evolver.EvolverEngine } // NewEngine 组装引擎并注册默认工具集 // Logan.Li func NewEngine(cfg EngineConfig) (*Engine, error) { coreCfg := cfg.Core if coreCfg == nil { coreCfg = core.DefaultConfig() } if cfg.MemoryDir != "" { coreCfg.MemoryDir = cfg.MemoryDir } safetyMode := cfg.SafetyMode if safetyMode == "" { safetyMode = safety.ModeBalanced } // LLM 客户端 client := llm.NewClient(cfg.LLM) // 工具注册中心:按模式注册互斥工具集 // Logan.Li registry := tools.NewRegistry() runMode := NormalizeRunMode(cfg.Mode) coreCfg.Mode = runMode switch runMode { case RunModeKubernetes: if cfg.Kubernetes == nil || cfg.Kubernetes.Client == nil { return nil, fmt.Errorf("Kubernetes 模式缺少集群客户端") } kt := cfg.Kubernetes registry.Register(tools.NewKubernetesGetTool(kt.Client, kt.Namespace)) registry.Register(tools.NewPodLogsTool(kt.Client, kt.Namespace, kt.PodName, kt.Container)) registry.Register(tools.NewPodExecuteTool(kt.Client, kt.Namespace, kt.PodName, kt.Container, coreCfg.ToolTimeout)) registry.Register(tools.NewKubernetesActionTool(kt.Client, kt.Namespace)) default: sshTool, err := tools.NewSSHExecuteTool(cfg.SSH, coreCfg.ToolTimeout) if err != nil { return nil, fmt.Errorf("ssh_execute 初始化失败: %w", err) } registry.Register(sshTool) } registry.Register(tools.NewAnalyzeOutputTool()) // 安全控制器 sc := safety.NewController(safetyMode) // Evolver(LLM 可用时启用学习;失败降级) ev, err := evolver.NewEvolverEngine(coreCfg.MemoryDir, client) if err != nil { ev = nil // 降级:无自学习,不影响主流程 } agent := core.NewAgent(client, registry, coreCfg, sc, ev) return &Engine{agent: agent, safety: sc, tools: registry, evolver: ev}, nil } // SetCallback 注入事件回调(驱动前端渲染 + DB 持久化) // Logan.Li func (e *Engine) SetCallback(cb core.EventCallback) { e.agent.SetCallback(cb) } // SetConfirmFn 注入高危确认回调(controller 推 WS confirm 事件并阻塞等前端回传) // Logan.Li func (e *Engine) SetConfirmFn(fn safety.ConfirmFn) { e.safety.SetConfirmFn(fn) } // SetAutoApprove 测试用:自动批准(生产禁用) // Logan.Li func (e *Engine) SetAutoApprove(b bool) { e.safety.SetAutoApprove(b) } // Run 执行任务(ReAct 循环);targetInfo 为目标上下文摘要;prior 为上一轮对话历史(不含 system) // Logan.Li func (e *Engine) Run(ctx context.Context, query, targetInfo string, prior []llm.Message, priorTokens int) (*core.RunResult, error) { return e.agent.Run(ctx, query, targetInfo, prior, priorTokens) } // EvolveStats 进化统计(供审计展示) // Logan.Li func (e *Engine) EvolveStats() map[string]interface{} { if e.evolver == nil { return map[string]interface{}{"enabled": false} } return e.evolver.GetStats() } // Close 释放资源(含 SSH 长连接) // Logan.Li func (e *Engine) Close() { if e.tools != nil { e.tools.Close() } if e.agent != nil { e.agent.Close() } }