From 53488f792d711b3d5e957bf69bc884576f7ed00f Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Wed, 10 Jun 2026 12:49:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(types,model):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E9=98=B6=E6=AE=B5=201=20=E5=9F=BA=E7=A1=80=E8=AE=BE=E6=96=BD?= =?UTF-8?q?=20=E2=80=94=20=E9=94=99=E8=AF=AF=E7=A0=81=E3=80=81AppError?= =?UTF-8?q?=E3=80=81=E9=85=8D=E7=BD=AE=E6=A8=A1=E5=9E=8B=E3=80=81=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/model/config.go | 66 +++++++++++++++ internal/model/types.go | 177 +++++++++++++++++++++++++++++++++++++++ pkg/types/codes.go | 11 +++ pkg/types/errors.go | 16 ++++ 4 files changed, 270 insertions(+) diff --git a/internal/model/config.go b/internal/model/config.go index 8b53790..cee71fe 100644 --- a/internal/model/config.go +++ b/internal/model/config.go @@ -1 +1,67 @@ package model + +// WorkflowType 工作流类型 +type WorkflowType string + +const ( + WorkflowTypeLoop WorkflowType = "loop" + WorkflowTypeParallel WorkflowType = "parallel" + WorkflowTypeSequential WorkflowType = "sequential" +) + +// AiAgentConfigTable 一个 Agent 配置表的顶层结构,对应 YAML 中 tables 下的每一项 +type AiAgentConfigTable struct { + AppName string `yaml:"app-name" json:"appName"` + Agent AgentSummary `yaml:"agent" json:"agent"` + Module AgentModule `yaml:"module" json:"module"` +} + +// AgentSummary Agent 摘要信息 +type AgentSummary struct { + AgentID string `yaml:"agent-id" json:"agentId"` + AgentName string `yaml:"agent-name" json:"agentName"` + AgentDesc string `yaml:"agent-desc" json:"agentDesc"` +} + +// AgentModule Agent 模块配置,包含 API、模型、Agent 定义、工作流和 Runner +type AgentModule struct { + AiAPI AiAPIConfig `yaml:"ai-api" json:"aiApi"` + ChatModel ChatModelConfig `yaml:"chat-model" json:"chatModel"` + Agents []AgentConfig `yaml:"agents" json:"agents"` + AgentWorkflows []AgentWorkflowConfig `yaml:"agent-workflows" json:"agentWorkflows"` + Runner RunnerConfig `yaml:"runner" json:"runner"` +} + +// AiAPIConfig LLM API 连接配置 +type AiAPIConfig struct { + BaseURL string `yaml:"base-url" json:"baseUrl"` + APIKey string `yaml:"api-key" json:"apiKey"` + CompletionsPath string `yaml:"completions-path" json:"completionsPath"` +} + +// ChatModelConfig 聊天模型配置 +type ChatModelConfig struct { + Model string `yaml:"model" json:"model"` +} + +// AgentConfig 单个 Agent 的定义 +type AgentConfig struct { + Name string `yaml:"name" json:"name"` + Instruction string `yaml:"instruction" json:"instruction"` + Description string `yaml:"description" json:"description"` + OutputKey string `yaml:"output-key" json:"outputKey"` +} + +// AgentWorkflowConfig 工作流配置,支持 loop/parallel/sequential 三种类型 +type AgentWorkflowConfig struct { + Type WorkflowType `yaml:"type" json:"type"` + Name string `yaml:"name" json:"name"` + SubAgents []string `yaml:"sub-agents" json:"subAgents"` + Description string `yaml:"description" json:"description"` + MaxIterations int `yaml:"max-iterations" json:"maxIterations"` +} + +// RunnerConfig Runner 配置,指定入口 Agent 名称 +type RunnerConfig struct { + AgentName string `yaml:"agent-name" json:"agentName"` +} diff --git a/internal/model/types.go b/internal/model/types.go index 8b53790..1898a6b 100644 --- a/internal/model/types.go +++ b/internal/model/types.go @@ -1 +1,178 @@ package model + +import ( + "context" + "sync" +) + +// ============================================================ +// Chat 数据类型 +// ============================================================ + +// ChatRole 消息角色 +type ChatRole string + +const ( + ChatRoleSystem ChatRole = "system" + ChatRoleUser ChatRole = "user" + ChatRoleAssistant ChatRole = "assistant" + ChatRoleTool ChatRole = "tool" +) + +// ChatMessage 聊天消息 +type ChatMessage struct { + Role ChatRole + Content string + ToolCallID string + Name string + ToolCalls []ChatToolCall +} + +// ChatToolCall 工具调用请求 +type ChatToolCall struct { + ID string + Name string + Arguments string +} + +// ChatReply 聊天回复 +type ChatReply struct { + Content string + ToolCalls []ChatToolCall +} + +// ChatStreamEvent 流式事件 +type ChatStreamEvent struct { + Delta string + ToolCalls []ChatToolCall + Done bool +} + +// ChatContent 聊天输入内容 +type ChatContent struct { + Texts []TextPart +} + +// TextPart 文本片段 +type TextPart struct { + Message string +} + +// ============================================================ +// 核心接口 +// ============================================================ + +// Tool 外部工具接口 +type Tool interface { + Name() string + Description() string + Call(ctx context.Context, input string) (string, error) +} + +// ChatModel 聊天模型接口,支持同步生成和流式输出 +type ChatModel interface { + Generate(ctx context.Context, messages []ChatMessage) (ChatReply, error) + Stream(ctx context.Context, messages []ChatMessage) (<-chan ChatStreamEvent, <-chan error) +} + +// Agent 智能体接口 +type Agent interface { + Name() string + Run(ctx context.Context, content ChatContent) (string, error) + Stream(ctx context.Context, content ChatContent, out chan<- string) error +} + +// Runner 运行器接口,管理会话并执行 Agent +type Runner interface { + CreateSession(userID string) (string, error) + Run(userID, sessionID string, content ChatContent) ([]string, error) + Stream(userID, sessionID string, content ChatContent) (<-chan string, <-chan error) +} + +// ============================================================ +// 注册与存储 +// ============================================================ + +// RegisteredAgent 已注册的 Agent 信息 +type RegisteredAgent struct { + AppName string + AgentID string + AgentName string + AgentDesc string + Runner Runner +} + +// AgentRegistry Agent 注册表接口 +type AgentRegistry interface { + Register(agent RegisteredAgent) error + Get(agentID string) (RegisteredAgent, bool) + List() []RegisteredAgent +} + +// SessionStore 会话存储接口 +type SessionStore interface { + Get(userID, agentID string) (string, bool) + Set(userID, agentID, sessionID string) error +} + +// ============================================================ +// 内存实现 +// ============================================================ + +// InMemoryAgentRegistry 基于内存的 Agent 注册表 +type InMemoryAgentRegistry struct { + mu sync.RWMutex + agents map[string]RegisteredAgent +} + +func NewInMemoryAgentRegistry() *InMemoryAgentRegistry { + return &InMemoryAgentRegistry{agents: make(map[string]RegisteredAgent)} +} + +func (r *InMemoryAgentRegistry) Register(agent RegisteredAgent) error { + r.mu.Lock() + defer r.mu.Unlock() + r.agents[agent.AgentID] = agent + return nil +} + +func (r *InMemoryAgentRegistry) Get(agentID string) (RegisteredAgent, bool) { + r.mu.RLock() + defer r.mu.RUnlock() + agent, ok := r.agents[agentID] + return agent, ok +} + +func (r *InMemoryAgentRegistry) List() []RegisteredAgent { + r.mu.RLock() + defer r.mu.RUnlock() + agents := make([]RegisteredAgent, 0, len(r.agents)) + for _, agent := range r.agents { + agents = append(agents, agent) + } + return agents +} + +// InMemorySessionStore 基于内存的会话存储 +type InMemorySessionStore struct { + mu sync.RWMutex + sessions map[string]string +} + +func NewInMemorySessionStore() *InMemorySessionStore { + return &InMemorySessionStore{sessions: make(map[string]string)} +} + +func (s *InMemorySessionStore) Get(userID, agentID string) (string, bool) { + s.mu.RLock() + defer s.mu.RUnlock() + sessionID, ok := s.sessions[userID+":"+agentID] + return sessionID, ok +} + +func (s *InMemorySessionStore) Set(userID, agentID, sessionID string) error { + s.mu.Lock() + defer s.mu.Unlock() + s.sessions[userID+":"+agentID] = sessionID + return nil +} diff --git a/pkg/types/codes.go b/pkg/types/codes.go index ab1254f..389990e 100644 --- a/pkg/types/codes.go +++ b/pkg/types/codes.go @@ -1 +1,12 @@ package types + +const ( + CodeSuccess = "0000" + InfoSuccess = "success" + CodeUnknownError = "0001" + InfoUnknownError = "unknown error" + CodeIllegalParameter = "0002" + InfoIllegalParameter = "illegal parameter" + CodeAgentNotFound = "0003" + InfoAgentNotFound = "agent not found" +) diff --git a/pkg/types/errors.go b/pkg/types/errors.go index ab1254f..99ea0f0 100644 --- a/pkg/types/errors.go +++ b/pkg/types/errors.go @@ -1 +1,17 @@ package types + +type AppError struct { + Code string + Info string +} + +func NewAppError(code, info string) *AppError { + return &AppError{Code: code, Info: info} +} + +func (e *AppError) Error() string { + if e == nil { + return "" + } + return e.Code + ": " + e.Info +}