Documentation
¶
Overview ¶
Package agent 定义 AI Agent 调用的统一抽象层。
它屏蔽了具体第三方 Agent(Claude Code / Codex / Copilot)与后续自研 Agent 的差异, 向上层业务(AISummaryWorker、LLMHandler 等)统一暴露两种调用语义:
- Invoke:一次性任务调用,同步等待最终结果。适合 AI 摘要、后台任务等场景。
- Stream:流式调用,通过 Runtime.Emit 逐块输出事件。适合前端聊天等场景。
除“调用”本身外,本包还实现了 design.md 中描述的“执行架构”:
- Agent:执行层,负责产生文本 / 推理 / 工具调用等事件,并在需要时请求权限。
- Runtime:Agent 执行期的运行时环境(Emit / RequestPermission / WaitPermission)。
- Operation / PermissionPolicy:描述“要做什么”以及“能不能做”。
- PermissionManager / PermissionRequest:持久化的权限请求与批准 / 拒绝。
- Task / TaskManager(AgentService):任务状态机与编排。
- EventBus / AgentEvent:实时通知层(带 sequence,可恢复)。
- Repository:持久化抽象(默认提供内存实现,后续可替换为 DB)。
各 Provider 通过 Registry 注册,运行时按名称解析;Client 是统一门面,负责 解析请求应使用的 Provider 并转发 Invoke / Stream。
Package agent 中的 memory 层:Agent 的「长期记忆」子系统。
与 conversation.go 中的「短期上下文」(单次会话的多轮历史)不同,memory 负责跨轮次、 跨会话、跨任务的持久化记忆,例如用户偏好、已确认的事实、任务摘要等。它遵循与权限 子系统一致的架构原则:Repository 是状态源,Manager 负责编排,检索 / 提取可插拔。
Index ¶
- Constants
- Variables
- func BuildMemoryContext(memories []*Memory) string
- type Agent
- type AgentEvent
- type AgentEventType
- type AgentService
- func (s *AgentService) ApprovePermission(ctx context.Context, id int64, by string) error
- func (s *AgentService) CancelTask(ctx context.Context, taskID int64) error
- func (s *AgentService) CreateTask(ctx context.Context, req Request) (*Task, error)
- func (s *AgentService) DeleteMemory(ctx context.Context, id string) error
- func (s *AgentService) DeleteProfile(ctx context.Context, userID string, id int64) error
- func (s *AgentService) DenyPermission(ctx context.Context, id int64, by string) error
- func (s *AgentService) GetEvents(ctx context.Context, taskID int64, after int64) ([]*AgentEvent, error)
- func (s *AgentService) GetMemory(ctx context.Context, id string) (*Memory, error)
- func (s *AgentService) GetPendingPermissions(ctx context.Context, taskID int64) ([]*PermissionRequest, error)
- func (s *AgentService) GetProfile(ctx context.Context, userID string, id int64) (*Profile, error)
- func (s *AgentService) GetTask(ctx context.Context, id int64) (*Task, error)
- func (s *AgentService) GetTaskRequest(ctx context.Context, taskID int64) (*Request, error)
- func (s *AgentService) ListMemory(ctx context.Context, userID string, offset, limit int, kinds ...MemoryKind) ([]*Memory, int64, error)
- func (s *AgentService) ListProfiles(ctx context.Context, userID string) ([]*Profile, error)
- func (s *AgentService) PageEvents(ctx context.Context, offset, limit int, taskID int64) ([]*AgentEvent, int64, error)
- func (s *AgentService) PagePermissions(ctx context.Context, offset, limit int, taskID int64, ...) ([]*PermissionRequest, int64, error)
- func (s *AgentService) PageTasks(ctx context.Context, offset, limit int, statuses ...TaskStatus) ([]*Task, int64, error)
- func (s *AgentService) ProjectContext(ctx context.Context, userID string) (string, error)
- func (s *AgentService) Recover(ctx context.Context) error
- func (s *AgentService) RetrieveMemory(ctx context.Context, userID, query string, limit int) ([]*Memory, error)
- func (s *AgentService) RunTask(ctx context.Context, req Request, handler StreamHandler) (*Task, error)
- func (s *AgentService) RunTaskSync(ctx context.Context, req Request) (*Result, error)
- func (s *AgentService) SaveMemory(ctx context.Context, memory *Memory) error
- func (s *AgentService) SaveProfile(ctx context.Context, profile *Profile) error
- func (s *AgentService) StartTask(ctx context.Context, taskID int64, handler StreamHandler) error
- func (s *AgentService) Subscribe(taskID int64, handler EventHandler) func()
- type Client
- func (c *Client) InvokeRuntime(ctx context.Context, req Request, rt Runtime) (*Result, error)
- func (c *Client) SetDefault(provider string, opts Options)
- func (c *Client) Stream(ctx context.Context, req Request, handler StreamHandler) (*Result, error)
- func (c *Client) StreamRuntime(ctx context.Context, req Request, rt Runtime) (*Result, error)
- type ContextConfig
- type Conversation
- type ConversationMessage
- type ConversationRepository
- type ConversationService
- func (s *ConversationService) CreateTurn(ctx context.Context, in TurnInput) (*Task, *Conversation, error)
- func (s *ConversationService) GetConversation(ctx context.Context, id int64) (*Conversation, error)
- func (s *ConversationService) PageConversations(ctx context.Context, userID string, offset, limit int) ([]*Conversation, int64, error)
- func (s *ConversationService) StartTurn(ctx context.Context, taskID int64) error
- type EventBus
- type EventHandler
- type EventRepository
- type Memory
- type MemoryConfig
- type MemoryExtractor
- type MemoryExtractorFunc
- type MemoryKind
- type MemoryManager
- func (m *MemoryManager) Delete(ctx context.Context, id string) error
- func (m *MemoryManager) Extract(ctx context.Context, turn MemoryTurn) ([]*Memory, error)
- func (m *MemoryManager) Get(ctx context.Context, id string) (*Memory, error)
- func (m *MemoryManager) List(ctx context.Context, userID string, offset, limit int, kinds ...MemoryKind) ([]*Memory, int64, error)
- func (m *MemoryManager) Retrieve(ctx context.Context, userID, query string, limit int) ([]*Memory, error)
- func (m *MemoryManager) Save(ctx context.Context, memory *Memory) error
- func (m *MemoryManager) Touch(ctx context.Context, id string) error
- type MemoryRepository
- type MemoryRetriever
- type MemoryTurn
- type Message
- type MessageBlock
- type Operation
- type OperationType
- type Options
- type PermissionDecision
- type PermissionManager
- func (m *PermissionManager) Approve(ctx context.Context, id int64, by string) (*PermissionRequest, error)
- func (m *PermissionManager) Create(ctx context.Context, taskID int64, sessionID string, operation Operation) (*PermissionRequest, error)
- func (m *PermissionManager) Deny(ctx context.Context, id int64, by string) (*PermissionRequest, error)
- func (m *PermissionManager) Get(ctx context.Context, id int64) (*PermissionRequest, error)
- func (m *PermissionManager) GetPending(ctx context.Context, taskID int64) ([]*PermissionRequest, error)
- func (m *PermissionManager) Page(ctx context.Context, offset, limit int, taskID int64, ...) ([]*PermissionRequest, int64, error)
- func (m *PermissionManager) Wait(ctx context.Context, id int64) (PermissionDecision, error)
- type PermissionPolicy
- type PermissionRepository
- type PermissionRequest
- type PermissionStatus
- type Profile
- type ProfileManager
- func (m *ProfileManager) Delete(ctx context.Context, userID string, id int64) error
- func (m *ProfileManager) Get(ctx context.Context, userID string, id int64) (*Profile, error)
- func (m *ProfileManager) List(ctx context.Context, userID string) ([]*Profile, error)
- func (m *ProfileManager) Resolve(ctx context.Context, userID, name string) (*Profile, error)
- func (m *ProfileManager) Save(ctx context.Context, p *Profile) error
- type ProfileRepository
- type ProjectContextProvider
- type Provider
- type ReasoningBlock
- type Registry
- type Request
- type Result
- type Runtime
- type ServiceConfig
- type SkillCall
- type SkillCallProvider
- type SkillLoop
- type SkillPermissionResolver
- type SkillResultEvent
- type SkillRunner
- type StreamEvent
- type StreamEventType
- type StreamHandler
- type Task
- type TaskRepository
- type TaskStatus
- type ToolCall
- type ToolCallProvider
- type ToolLoop
- type ToolPermissionResolver
- type ToolResultEvent
- type ToolRunner
- type TurnBlock
- type TurnInput
- type Usage
Constants ¶
const ( ProviderMock = "mock" // 自研 mock,用于保证链路可跑通 ProviderClaudeCode = "claude_code" // Anthropic Claude Code CLI ProviderCodex = "codex" // OpenAI Codex CLI ProviderCopilot = "copilot" // GitHub Copilot CLI ProviderCustom = "custom" // 预留:后续自研 Agent )
Provider 名称常量。新增第三方 Agent 或自研 Agent 时在此登记一个唯一名称。
const ( RoleSystem = "system" RoleUser = "user" RoleAssistant = "assistant" RoleTool = "tool" )
MessageRole 常量。
const ( DefaultProfileName = "default" // 系统默认 Profile ProfileAnalysisCoder = "analysis_coder" // 撰写分析代码 ProfileArticleWriter = "article_writer" // 撰写科研文章 / 报告 )
内置 AgentProfile 名称常量。新增内置 Profile 时在此登记唯一名称。
const ( BuiltinDefaultProfileID int64 = -1 // 内置默认 Profile BuiltinAnalysisCoderID int64 = -2 // 内置「分析代码编写」Profile BuiltinArticleWriterID int64 = -3 // 内置「科研文章撰写」Profile )
内置 Profile 使用固定的负数 ID,避免与雪花算法生成的正整数主键冲突。
const DefaultProvider = ProviderMock
DefaultProvider 是未配置时的兜底 Provider。
Variables ¶
var ( // ErrMemoryNotFound 表示记忆不存在。 ErrMemoryNotFound = errors.New("agent: memory not found") // ErrMemoryNotConfigured 表示 AgentService 未配置记忆管理器。 ErrMemoryNotConfigured = errors.New("agent: memory manager not configured") )
记忆相关错误。
var ( // ErrPermissionDenied 表示权限请求被拒绝,或策略直接判定为 deny。 ErrPermissionDenied = errors.New("agent: permission denied") // ErrPermissionNotFound 表示权限请求不存在。 ErrPermissionNotFound = errors.New("agent: permission request not found") // ErrPermissionNotPending 表示尝试对非 pending 状态的权限请求做批准 / 拒绝。 ErrPermissionNotPending = errors.New("agent: permission request is not pending") // ErrPermissionExpired 表示等待的权限请求已过期。 ErrPermissionExpired = errors.New("agent: permission request expired") // ErrPermissionCanceled 表示等待的权限请求已取消。 ErrPermissionCanceled = errors.New("agent: permission request canceled") // ErrInvalidPermissionTransition 表示非法的权限状态迁移。 ErrInvalidPermissionTransition = errors.New("agent: invalid permission state transition") )
权限相关错误。
var ( // ErrProfileNotFound 表示 Profile 不存在。 ErrProfileNotFound = errors.New("agent: profile not found") // ErrProfileNameRequired 表示 Profile 名称缺失。 ErrProfileNameRequired = errors.New("agent: profile name is required") )
Profile 相关错误。
var ( // ErrTaskNotFound 表示任务不存在。 ErrTaskNotFound = errors.New("agent: task not found") // ErrTaskAlreadyRunning 表示任务已经在执行中。 ErrTaskAlreadyRunning = errors.New("agent: task already running") // ErrInvalidTaskTransition 表示非法的任务状态迁移。 ErrInvalidTaskTransition = errors.New("agent: invalid task state transition") )
任务相关错误。
var ( // ErrConversationNotFound 表示会话不存在。 ErrConversationNotFound = errors.New("agent: conversation not found") )
会话相关错误。
var ErrNoPermissionResolver = errors.New("agent: no permission resolver in runtime")
ErrNoPermissionResolver 表示当前 Runtime 没有绑定权限解析器(无法等待人工决策)。
var ErrNotImplemented = errors.New("agent: provider not implemented yet")
ErrNotImplemented 表示某个 Provider 尚未实现真实调用。
Functions ¶
func BuildMemoryContext ¶
BuildMemoryContext 把检索到的记忆格式化为注入上下文的文本块。
用于 AgentService 在调用前把相关记忆注入 SystemPrompt,让 Agent「记得」相关背景。 无记忆时返回空字符串。
Types ¶
type Agent ¶
type Agent interface {
// Name 返回 Provider 唯一标识。
Name() string
// Invoke 执行一次性任务并同步返回最终结果。
Invoke(ctx context.Context, req Request, rt Runtime) (*Result, error)
// Stream 执行流式请求,通过 rt.Emit 逐块输出事件,返回最终聚合结果。
Stream(ctx context.Context, req Request, rt Runtime) (*Result, error)
}
Agent 是统一 Agent 调用接口。 每个 Provider(claude_code / codex / copilot / custom ...)都需要实现该接口。
type AgentEvent ¶
type AgentEvent struct {
ID int64 `json:"id,string" gorm:"column:id;primaryKey;type:bigint;autoIncrement:false"`
TaskID int64 `json:"task_id,string" gorm:"column:task_id;type:bigint;index:idx_agent_events_task_seq,priority:1"`
Sequence int64 `json:"sequence" gorm:"column:sequence;index:idx_agent_events_task_seq,priority:2"`
Type AgentEventType `json:"type" gorm:"column:type;type:varchar(32)"`
Payload any `json:"payload,omitempty" gorm:"serializer:json"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
}
AgentEvent 是发布到 EventBus 的单个事件,带单调递增的 sequence。
sequence 使事件可被“增量拉取”(如 GET /tasks/{id}/events?after=3), 因此浏览器刷新后无需依赖 WS 历史即可恢复。
func (*AgentEvent) BeforeCreate ¶ added in v0.1.3
func (e *AgentEvent) BeforeCreate(_ *gorm.DB) error
BeforeCreate 在写入数据库前用雪花 ID 初始化主键。
type AgentEventType ¶
type AgentEventType string
AgentEventType 枚举任务生命周期与实时通知事件。
流式内容事件统一使用 EventStream,具体细分见 StreamEvent.Type; 权限与任务状态变化使用独立类型,便于前端按类型订阅与恢复。
const ( EventTaskCreated AgentEventType = "task.created" // 任务已创建 EventTaskStarted AgentEventType = "task.started" // 任务开始执行 EventTaskWaiting AgentEventType = "task.waiting" // 任务进入等待权限状态 EventTaskCompleted AgentEventType = "task.completed" // 任务完成 EventTaskFailed AgentEventType = "task.failed" // 任务失败 EventTaskCanceled AgentEventType = "task.canceled" // 任务取消 EventPermissionCreated AgentEventType = "permission.created" // 新增待确认权限 EventPermissionResolved AgentEventType = "permission.resolved" // 权限已被批准 / 拒绝 EventMemorySaved AgentEventType = "memory.saved" // 记忆已保存(Payload 为 Memory) EventMemoryDeleted AgentEventType = "memory.deleted" // 记忆已删除(Payload 为 Memory) EventStream AgentEventType = "stream" // 透传的流式事件(Payload 为 StreamEvent) )
type AgentService ¶
type AgentService struct {
// contains filtered or unexported fields
}
AgentService 是 Agent 执行架构的编排层(即 design.md 中的 AgentTaskManager)。
它把 Client(Provider 门面)、TaskRepository、PermissionManager、EventRepository、 EventBus 与 PermissionPolicy 组合成一条完整的调用链路:
RunTask 创建任务 → 启动 goroutine 执行 Agent → Agent 通过 Runtime.Emit 输出事件(持久化 + 广播) → Agent 通过 Runtime.RequestPermission 请求权限(持久化 pending + 任务置为 waiting) → UI 调用 ApprovePermission / DenyPermission(更新 DB + 唤醒 Agent) → Agent 恢复执行,直至 completed / failed
Recover 用于后端重启后重建运行态。
func NewService ¶
func NewService(cfg ServiceConfig) *AgentService
NewService 创建 AgentService,未提供的依赖使用安全的默认值。
func (*AgentService) ApprovePermission ¶
ApprovePermission 批准权限请求(供 UI / HTTP 层调用)。
func (*AgentService) CancelTask ¶
func (s *AgentService) CancelTask(ctx context.Context, taskID int64) error
CancelTask 取消任务:取消执行上下文并置为 canceled。
func (*AgentService) CreateTask ¶
CreateTask 创建任务(不启动执行)。
供 HTTP 层使用:先拿到 taskID 订阅事件,再调用 StartTask 启动,避免错过 task.created 等早期事件。
func (*AgentService) DeleteMemory ¶
func (s *AgentService) DeleteMemory(ctx context.Context, id string) error
DeleteMemory 删除记忆,并广播记忆事件。
func (*AgentService) DeleteProfile ¶
DeleteProfile 删除用户自定义 Profile(内置 Profile 不可删除)。
func (*AgentService) DenyPermission ¶
DenyPermission 拒绝权限请求(供 UI / HTTP 层调用)。
func (*AgentService) GetEvents ¶
func (s *AgentService) GetEvents(ctx context.Context, taskID int64, after int64) ([]*AgentEvent, error)
GetEvents 增量拉取任务事件(after 为上次收到的最大 sequence)。
func (*AgentService) GetPendingPermissions ¶
func (s *AgentService) GetPendingPermissions(ctx context.Context, taskID int64) ([]*PermissionRequest, error)
GetPendingPermissions 查询任务当前待确认的权限请求。
func (*AgentService) GetProfile ¶
GetProfile 按 ID 返回当前用户的自定义 Profile(内置 Profile 按 ID 不可取)。
func (*AgentService) GetTaskRequest ¶ added in v0.1.3
GetTaskRequest 按任务 ID 加载任务,应用 Agent Profile 后返回实际发送给 LLM 的请求内容。
供 UI 调试 / 审计使用:它复用了 run 路径上的 applyProfile(系统提示词合并、技能选择、 记忆 / 项目上下文注入),因此结果与任务实际执行时发给 Provider 的 Request 一致。
func (*AgentService) ListMemory ¶
func (s *AgentService) ListMemory(ctx context.Context, userID string, offset, limit int, kinds ...MemoryKind) ([]*Memory, int64, error)
ListMemory 分页查询某用户的记忆;kinds 为空表示全部类别。
func (*AgentService) ListProfiles ¶
ListProfiles 返回内置与当前用户自定义的 Profile 列表(合并视图)。
func (*AgentService) PageEvents ¶
func (s *AgentService) PageEvents(ctx context.Context, offset, limit int, taskID int64) ([]*AgentEvent, int64, error)
PageEvents 分页查询事件;taskID 为 0 表示全部任务。
func (*AgentService) PagePermissions ¶
func (s *AgentService) PagePermissions(ctx context.Context, offset, limit int, taskID int64, statuses ...PermissionStatus) ([]*PermissionRequest, int64, error)
PagePermissions 分页查询权限请求;taskID 为 0 表示全部任务,statuses 为空表示全部状态。
func (*AgentService) PageTasks ¶
func (s *AgentService) PageTasks(ctx context.Context, offset, limit int, statuses ...TaskStatus) ([]*Task, int64, error)
PageTasks 分页查询任务(offset/limit 由上层根据 types.Pagination 计算)。
func (*AgentService) ProjectContext ¶
ProjectContext 返回当前用户激活项目下的上下文文本块(例如已完成的分析节点)。
未配置项目上下文提供者或用户为空时返回空串;查询失败时返回错误。 供 HTTP 层直接向用户展示注入 Agent 系统提示词的项目背景。
func (*AgentService) Recover ¶
func (s *AgentService) Recover(ctx context.Context) error
Recover 在后端重启后重建运行态(见 design.md 第 6 / 19 节)。
当前内存实现下:
- 没有活跃 goroutine 的 running 任务:无法恢复执行,标记为 failed(interrupted)。
- 没有活跃 goroutine 的 waiting_permission 任务:pending 权限已持久化, UI 仍可通过 GetPendingPermissions 拉取并批准 / 拒绝(更新 DB); 但 Agent 进程已丢失,真正“恢复执行”依赖各 Provider 的 checkpoint / resume 能力。
func (*AgentService) RetrieveMemory ¶
func (s *AgentService) RetrieveMemory(ctx context.Context, userID, query string, limit int) ([]*Memory, error)
RetrieveMemory 检索与 query 相关的记忆。
func (*AgentService) RunTask ¶
func (s *AgentService) RunTask(ctx context.Context, req Request, handler StreamHandler) (*Task, error)
RunTask 创建任务并异步执行(流式语义)。
执行与调用方 ctx 解耦:任务在独立 goroutine 中运行,可跨多次 HTTP 请求存活, 通过权限确认 / 取消 / 恢复驱动其生命周期。返回的任务对象用于前端轮询 / 订阅。
func (*AgentService) RunTaskSync ¶
RunTaskSync 同步执行一次性任务:创建 → 运行 → 返回聚合结果。
供需要一次性拿到结果的业务(如 AISummaryWorker)使用,替代直接调用 agent.Client.Invoke。 与 RunTask / StartTask 不同,它不启动 goroutine,直接在调用方同步执行。
func (*AgentService) SaveMemory ¶
func (s *AgentService) SaveMemory(ctx context.Context, memory *Memory) error
SaveMemory 创建或更新一条记忆,并广播记忆事件(实时通知层)。
func (*AgentService) SaveProfile ¶
func (s *AgentService) SaveProfile(ctx context.Context, profile *Profile) error
SaveProfile 创建或更新用户自定义 Profile。
func (*AgentService) StartTask ¶
func (s *AgentService) StartTask(ctx context.Context, taskID int64, handler StreamHandler) error
StartTask 启动已创建任务的异步执行。
func (*AgentService) Subscribe ¶
func (s *AgentService) Subscribe(taskID int64, handler EventHandler) func()
Subscribe 订阅任务事件(taskID 为 0 表示订阅全部任务),返回取消订阅函数。 供 WS / SSE 实时推送层使用;刷新恢复历史请使用 GetEvents。
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client 是 Agent 调用的统一门面(Facade)。
上层业务(AISummaryWorker、LLMHandler 等)只依赖 Client,不直接感知具体 Provider。 Client 负责:按请求中的 Provider(或默认 Provider)解析 Agent 实例,并转发 Invoke / Stream。
func (*Client) InvokeRuntime ¶
InvokeRuntime 使用调用方提供的 Runtime 执行一次性任务(供 AgentService 任务模式使用)。
func (*Client) SetDefault ¶
SetDefault 动态切换默认 Provider 与默认 Options(用于后续运行时切换能力)。
type ContextConfig ¶
type ContextConfig struct {
InjectMemory bool `json:"inject_memory"`
InjectProject bool `json:"inject_project"`
}
ContextConfig 控制 AgentService 在调用前注入哪些背景。
- InjectMemory:检索长期记忆并拼进 SystemPrompt;
- InjectProject:把当前项目已完成的分析节点等背景拼进 SystemPrompt。 (只有撰写文章 / 报告一类的任务才需要项目背景,因此默认关闭。)
type Conversation ¶
type Conversation struct {
ID int64 `json:"id,string" gorm:"column:id;primaryKey;type:bigint;autoIncrement:false"`
UserID string `json:"user_id" gorm:"column:user_id;type:varchar(64);index"`
Provider string `json:"provider" gorm:"column:provider;type:varchar(64)"`
Model string `json:"model" gorm:"column:model;type:varchar(128)"`
// Messages 保存完整历史(system 提示词之外的 user/assistant 消息)。
// 关系由 Repository 自行维护(独立表 agent_conversation_messages),
// 不使用 GORM 的 HasMany 关联,因此标记为 gorm:"-"。
Messages []Message `json:"messages" gorm:"-"`
// CurrentTaskID 记录当前活跃轮次(running / waiting_permission)的任务 ID;
// 轮次结束时置空。供前端刷新 / 切换会话时恢复实时流。
CurrentTaskID int64 `json:"current_task_id,string" gorm:"column:current_task_id;type:bigint"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
}
Conversation 是一次多轮对话的持久化对象。
Messages 保存完整历史(system 提示词之外的 user/assistant 消息), 每一轮执行前把历史拼进 Request.Messages,执行结束后把 assistant 回复写回历史。
func NewConversation ¶
func NewConversation(userID, provider, model string) *Conversation
NewConversation 创建一个空的会话。
func (*Conversation) BeforeCreate ¶ added in v0.1.3
func (c *Conversation) BeforeCreate(_ *gorm.DB) error
BeforeCreate 在写入数据库前用雪花 ID 初始化主键。
type ConversationMessage ¶
type ConversationMessage struct {
ID int64 `json:"id,string" gorm:"column:id;primaryKey;type:bigint;autoIncrement:false"`
ConversationID int64 `json:"conversation_id,string" gorm:"column:conversation_id;type:bigint;index"`
Seq int `json:"seq" gorm:"column:seq;index"`
Role string `json:"role" gorm:"column:role;type:varchar(32)"`
Content string `json:"content" gorm:"column:content;type:text"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
}
ConversationMessage 是会话中的一条消息,以独立表持久化。
与 Conversation 的关系(ConversationID 外键)由 Repository 自行维护, 不使用 GORM 的 HasMany / Preload 关联机制。
func (*ConversationMessage) BeforeCreate ¶ added in v0.1.3
func (m *ConversationMessage) BeforeCreate(_ *gorm.DB) error
BeforeCreate 在写入数据库前用雪花 ID 初始化主键。
func (ConversationMessage) TableName ¶
func (ConversationMessage) TableName() string
TableName 返回会话消息表的表名。
type ConversationRepository ¶
type ConversationRepository interface {
Get(ctx context.Context, id int64) (*Conversation, error)
Create(ctx context.Context, conv *Conversation) error
Update(ctx context.Context, conv *Conversation) error
// Page 分页查询会话(按 UpdatedAt 降序);userID 为空表示全部用户。
Page(ctx context.Context, userID string, offset, limit int) ([]*Conversation, int64, error)
}
ConversationRepository 持久化会话。
与 TaskRepository 一致:当前提供内存实现保证链路可跑通,后续可替换为 DB 实现。
func NewGormConversationRepository ¶
func NewGormConversationRepository(db *gorm.DB) ConversationRepository
NewGormConversationRepository 创建基于数据库的会话 Repository。
会话与其消息(agent_conversation_messages 表)的关系由本实现自行维护, 不使用 GORM 的 HasMany 关联。
func NewMemoryConversationRepository ¶
func NewMemoryConversationRepository() ConversationRepository
NewMemoryConversationRepository 创建会话的内存实现。
type ConversationService ¶
type ConversationService struct {
// contains filtered or unexported fields
}
ConversationService 编排多轮对话:负责历史拼接 + 复用 AgentService 执行每一轮。
func NewConversationService ¶
func NewConversationService(agent *AgentService, repo ConversationRepository) *ConversationService
NewConversationService 创建 ConversationService;repo 为空时使用内存实现。
func (*ConversationService) CreateTurn ¶
func (s *ConversationService) CreateTurn(ctx context.Context, in TurnInput) (*Task, *Conversation, error)
CreateTurn 准备一轮执行(不启动):
- 取得会话级锁(保证同一会话轮次串行);
- 加载 / 创建会话,追加 user 消息并持久化;
- 用完整历史组装 Request(SessionID = 会话 ID),交给 AgentService.CreateTask;
- 登记本轮中间态,返回 task 供上层(handler)在启动前订阅 WS。
锁在本轮结束时由 finishTurn 释放。
func (*ConversationService) GetConversation ¶
func (s *ConversationService) GetConversation(ctx context.Context, id int64) (*Conversation, error)
GetConversation 查询会话(含完整历史消息)。
func (*ConversationService) PageConversations ¶
func (s *ConversationService) PageConversations(ctx context.Context, userID string, offset, limit int) ([]*Conversation, int64, error)
PageConversations 分页查询会话;userID 为空表示全部用户。
type EventBus ¶
type EventBus interface {
// Publish 发布一个事件给订阅了该任务(或全部任务)的订阅者。
Publish(ctx context.Context, event AgentEvent)
// Subscribe 订阅某任务的事件;taskID 为空表示订阅全部任务。
// 返回的 unsubscribe 用于取消订阅。
Subscribe(taskID int64, handler EventHandler) (unsubscribe func())
}
EventBus 是实时通知层接口:只负责“告诉 UI 状态发生了变化”,不承担状态存储。
数据库(Repository)才是状态源;EventBus 之上可以接 WS / SSE 做实时推送。
type EventHandler ¶
type EventHandler func(ctx context.Context, event AgentEvent) error
EventHandler 是事件订阅回调。 返回 error 表示处理失败;EventBus 目前采用同步分发,回调应避免阻塞。
type EventRepository ¶
type EventRepository interface {
// Append 为事件分配 sequence 并追加到任务事件流。
Append(ctx context.Context, event *AgentEvent) error
// ListByTask 返回任务中 sequence 大于 after 的事件(升序)。
ListByTask(ctx context.Context, taskID int64, after int64) ([]*AgentEvent, error)
// Page 分页查询事件(按 CreatedAt 升序);taskID 为 0 表示全部任务。
Page(ctx context.Context, taskID int64, offset, limit int) ([]*AgentEvent, int64, error)
}
EventRepository 持久化任务事件(带 per-task 单调递增 sequence)。
func NewGormEventRepository ¶
func NewGormEventRepository(db *gorm.DB) EventRepository
NewGormEventRepository 创建基于数据库的事件流 Repository。
func NewMemoryEventRepository ¶
func NewMemoryEventRepository() EventRepository
NewMemoryEventRepository 创建事件流的内存实现。
type Memory ¶
type Memory struct {
ID string `json:"id" gorm:"column:id;primaryKey;type:varchar(64)"`
UserID string `json:"user_id" gorm:"column:user_id;type:varchar(64);index:idx_agent_memories_user_kind,priority:1"`
SessionID string `json:"session_id,omitempty" gorm:"column:session_id;type:varchar(64);index"`
Kind MemoryKind `json:"kind" gorm:"column:kind;type:varchar(32);index:idx_agent_memories_user_kind,priority:2"`
Content string `json:"content" gorm:"column:content;type:text"`
// Importance 表示记忆重要度(0-10),检索排序时权重更高。
Importance int `json:"importance" gorm:"column:importance"`
// Metadata 承载扩展信息(来源、标签等),由序列化为 JSON 持久化。
Metadata map[string]any `json:"metadata,omitempty" gorm:"column:metadata;serializer:json"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
LastAccessedAt *time.Time `json:"last_accessed_at,omitempty" gorm:"column:last_accessed_at"`
}
Memory 是一条可跨轮次 / 跨会话检索的持久化记忆。
UserID 是记忆的主归属维度(长期记忆按用户隔离);SessionID 可选,用于把记忆 与某个具体会话关联(例如该会话的摘要)。
type MemoryConfig ¶
type MemoryConfig struct {
Repo MemoryRepository
Retriever MemoryRetriever
Extractor MemoryExtractor
}
MemoryConfig 是 MemoryManager 的依赖配置。
type MemoryExtractor ¶
type MemoryExtractor interface {
Extract(ctx context.Context, turn MemoryTurn) ([]*Memory, error)
}
MemoryExtractor 从一轮完成的对话 / 任务结果中提取值得长期记住的记忆。
这是一个可选钩子:AgentService 在任务完成后调用,把提取出的记忆写入 Repository。 返回 nil 表示本轮无需写入任何记忆。默认不配置(不提取);可由上层注入基于规则 或基于 LLM 的实现。
func MockMemoryExtractor ¶
func MockMemoryExtractor() MemoryExtractor
MockMemoryExtractor 返回一个模拟的记忆提取器:把本轮的用户提问与助手回复 组合成一条 summary 记忆(内容做截断防止过长)。
用于演示 / 测试「任务完成 → 提取 → 落库」的调用链,不接入真实 LLM 或规则引擎; 生产环境应替换为基于规则或基于 LLM 的 MemoryExtractor 实现。
type MemoryExtractorFunc ¶
type MemoryExtractorFunc func(ctx context.Context, turn MemoryTurn) ([]*Memory, error)
MemoryExtractorFunc 是把普通函数适配为 MemoryExtractor 的辅助类型。
func (MemoryExtractorFunc) Extract ¶
func (f MemoryExtractorFunc) Extract(ctx context.Context, turn MemoryTurn) ([]*Memory, error)
Extract 实现 MemoryExtractor 接口。
type MemoryKind ¶
type MemoryKind string
MemoryKind 描述记忆的类别,用于检索排序与前端展示。
const ( MemoryKindFact MemoryKind = "fact" // 用户偏好 / 事实(长期有效) MemoryKindSummary MemoryKind = "summary" // 会话 / 任务摘要 MemoryKindNote MemoryKind = "note" // 通用备注 MemoryKindEvent MemoryKind = "event" // 事件记录(带时间语义) )
type MemoryManager ¶
type MemoryManager struct {
// contains filtered or unexported fields
}
MemoryManager 负责记忆的创建、查询、检索与提取编排。
它是 memory 域的「门面」:上层(AgentService / HTTP 层)只依赖 MemoryManager, 不直接感知 Repository / Retriever / Extractor 的具体实现。
func NewMemoryManager ¶
func NewMemoryManager(cfg MemoryConfig) *MemoryManager
NewMemoryManager 创建记忆管理器;未提供的依赖使用安全默认值。
func (*MemoryManager) Delete ¶
func (m *MemoryManager) Delete(ctx context.Context, id string) error
Delete 删除记忆。
func (*MemoryManager) Extract ¶
func (m *MemoryManager) Extract(ctx context.Context, turn MemoryTurn) ([]*Memory, error)
Extract 调用已配置的提取器,从一轮执行中提取待写入的记忆。 未配置提取器时返回空(不提取)。
func (*MemoryManager) List ¶
func (m *MemoryManager) List(ctx context.Context, userID string, offset, limit int, kinds ...MemoryKind) ([]*Memory, int64, error)
List 分页查询某用户的记忆;kinds 为空表示全部类别。
func (*MemoryManager) Retrieve ¶
func (m *MemoryManager) Retrieve(ctx context.Context, userID, query string, limit int) ([]*Memory, error)
Retrieve 检索与 query 相关的记忆,并刷新这些记忆的访问时间(Touch)。
type MemoryRepository ¶
type MemoryRepository interface {
Create(ctx context.Context, memory *Memory) error
Get(ctx context.Context, id string) (*Memory, error)
Update(ctx context.Context, memory *Memory) error
Delete(ctx context.Context, id string) error
// ListByUser 分页查询某用户的记忆(按 UpdatedAt 降序);kinds 为空表示全部类别。
ListByUser(ctx context.Context, userID string, offset, limit int, kinds ...MemoryKind) ([]*Memory, int64, error)
// Search 按关键词检索某用户的记忆(返回按相关度 + 重要度排序)。
// 基础实现为子串 / LIKE 匹配,可被更高级的检索器(向量 / 语义)替换。
Search(ctx context.Context, userID, query string, limit int) ([]*Memory, error)
}
MemoryRepository 持久化记忆。
与 TaskRepository / PermissionRepository 一致:当前提供内存实现,后续可替换为 GORM 等基于 DB 的实现(见 repository_gorm.go)。
func NewGormMemoryRepository ¶
func NewGormMemoryRepository(db *gorm.DB) MemoryRepository
NewGormMemoryRepository 创建基于数据库的记忆 Repository。
func NewMemoryRepository ¶
func NewMemoryRepository() MemoryRepository
NewMemoryRepository 创建记忆的内存实现。
type MemoryRetriever ¶
type MemoryRetriever interface {
// Retrieve 返回与 query 相关的记忆,按相关度降序,最多 limit 条。
Retrieve(ctx context.Context, userID, query string, limit int) ([]*Memory, error)
}
MemoryRetriever 从记忆中检索与查询相关的内容。
与 Repository.Search 的区别:Retriever 是可插拔的「检索策略」抽象, 默认实现退化为关键词匹配(委托 Repository.Search);后续可接入向量检索 / 语义检索, 而无须改动 AgentService 的注入逻辑。
type MemoryTurn ¶
MemoryTurn 描述一轮已完成执行的上下文,供 MemoryExtractor 提取记忆。
type Message ¶
type Message struct {
Role string `json:"role"` // system / user / assistant / tool
Content string `json:"content"` // 文本内容
}
Message 是一条对话消息。
type MessageBlock ¶
type MessageBlock struct {
ID string `json:"id"` // messageId
TurnID string `json:"turn_id,omitempty"` // 所属 turn
Content string `json:"content"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
}
MessageBlock 是一条完整的 assistant 消息(对应 AssistantMessageData), 包含它发起的工具调用列表。
type Operation ¶
type Operation struct {
ID string `json:"id,omitempty"`
Type OperationType `json:"type"`
// read / write / delete / move
Path string `json:"path,omitempty"`
// write
Content string `json:"content,omitempty"`
// execute
Command string `json:"command,omitempty"`
// Metadata 承载操作相关的扩展信息(如命令参数、网络地址等)。
Metadata map[string]any `json:"metadata,omitempty"`
}
Operation 描述 Agent 想要执行的一个原子操作。
它刻意与 PermissionRequest 分离:Operation 只描述“要做什么”, PermissionRequest 记录“这个操作是否被允许、当前处于什么状态”。
type OperationType ¶
type OperationType string
OperationType 描述 Agent 想要执行的操作类别。
未来可继续扩展(install_package / git_push / docker / kubernetes ...), 权限策略按类型决定 allow / deny / ask。
const ( OperationRead OperationType = "read" // 读取文件 OperationWrite OperationType = "write" // 写入 / 修改文件 OperationDelete OperationType = "delete" // 删除文件 OperationMove OperationType = "move" // 移动 / 重命名文件 OperationExecute OperationType = "execute" // 执行命令 / 脚本 OperationNetwork OperationType = "network" // 网络访问 )
type Options ¶
type Options struct {
Model string `json:"model"`
BaseURL string `json:"base_url"`
APIKey string `json:"api_key"`
BearerToken string `json:"bearer_token"`
WorkingDir string `json:"working_dir"`
Extra map[string]string `json:"extra"`
// Tools 是本次调用可用的工具注册表。
//
// Provider 据此向模型暴露工具定义(tool.List()),并通过 ToolRunner /
// tool.Executor 执行模型发起的工具调用。为 nil 表示本次调用不启用工具。
Tools *tool.Registry `json:"-"`
// Skills 是本次调用可用的技能注册表。
//
// Provider 据此向模型暴露技能定义(skill.List())与指令正文(skill.Instructions()),
// 并通过 SkillRunner / skill.Invoker 执行模型发起的技能调用。为 nil 表示本次
// 调用不启用技能。
Skills *skill.Registry `json:"-"`
}
Options 是构建 Agent 实例所需的通用配置;具体 Provider 按需读取。 Extra 用于承载 Provider 特有配置,避免为每个 Provider 单独定义结构。
type PermissionDecision ¶
type PermissionDecision string
PermissionDecision 是权限策略 / 决策结果。
const ( DecisionAllow PermissionDecision = "allow" // 允许执行 DecisionDeny PermissionDecision = "deny" // 拒绝执行 DecisionAsk PermissionDecision = "ask" // 需要人工确认 )
type PermissionManager ¶
type PermissionManager struct {
// contains filtered or unexported fields
}
PermissionManager 负责权限请求的创建、持久化与决策流转。
它是“数据库才是状态源”的核心实现:
- Create:把权限请求写入 Repository(pending),等待 UI 确认;
- Approve / Deny:更新 Repository 状态,并唤醒正在阻塞等待的 Agent;
- Wait:Agent 侧阻塞等待决策(内存 channel 只是运行时同步机制,真正状态在 Repository)。
注意:事件广播由上层 AgentService 负责(单一事件出口),PermissionManager 只维护状态。 Approve / Deny 与 Wait 通过互斥锁 + waiter channel 协同,避免“决策先于等待注册”的竞态。
func NewPermissionManager ¶
func NewPermissionManager(repo PermissionRepository) *PermissionManager
NewPermissionManager 创建权限管理器。
func (*PermissionManager) Approve ¶
func (m *PermissionManager) Approve(ctx context.Context, id int64, by string) (*PermissionRequest, error)
Approve 批准权限请求,返回更新后的权限请求;并唤醒正在等待的 Agent。
func (*PermissionManager) Create ¶
func (m *PermissionManager) Create(ctx context.Context, taskID int64, sessionID string, operation Operation) (*PermissionRequest, error)
Create 创建一个 pending 状态的权限请求并返回。
func (*PermissionManager) Deny ¶
func (m *PermissionManager) Deny(ctx context.Context, id int64, by string) (*PermissionRequest, error)
Deny 拒绝权限请求,返回更新后的权限请求;并唤醒正在等待的 Agent。
func (*PermissionManager) Get ¶
func (m *PermissionManager) Get(ctx context.Context, id int64) (*PermissionRequest, error)
Get 按 ID 查询权限请求。
func (*PermissionManager) GetPending ¶
func (m *PermissionManager) GetPending(ctx context.Context, taskID int64) ([]*PermissionRequest, error)
GetPending 返回某任务当前全部待确认的权限请求。
func (*PermissionManager) Page ¶
func (m *PermissionManager) Page(ctx context.Context, offset, limit int, taskID int64, statuses ...PermissionStatus) ([]*PermissionRequest, int64, error)
Page 分页查询权限请求;taskID 为 0 表示全部任务,statuses 为空表示全部状态。
func (*PermissionManager) Wait ¶
func (m *PermissionManager) Wait(ctx context.Context, id int64) (PermissionDecision, error)
Wait 阻塞等待权限请求的决策。
返回:
- DecisionAllow:已批准(批准后立即把请求标记为 consumed);
- DecisionDeny:已拒绝 / 过期 / 取消;
- error:ctx 取消等。
type PermissionPolicy ¶
type PermissionPolicy interface {
Check(ctx context.Context, operation Operation) PermissionDecision
}
PermissionPolicy 判断一个 Operation 应被允许、拒绝,还是需要人工确认。
Agent 在执行前把 Operation 交给策略;策略返回 ask 时,由 PermissionManager 持久化一个 pending 的 PermissionRequest 并等待 UI 确认。
func AllowAllPermissionPolicy ¶
func AllowAllPermissionPolicy() PermissionPolicy
AllowAllPermissionPolicy 返回一个“全部放行”的策略实例。
func DefaultPermissionPolicy ¶
func DefaultPermissionPolicy() PermissionPolicy
DefaultPermissionPolicy 返回框架内置的默认策略实例。
type PermissionRepository ¶
type PermissionRepository interface {
Create(ctx context.Context, permission *PermissionRequest) error
Get(ctx context.Context, id int64) (*PermissionRequest, error)
Update(ctx context.Context, permission *PermissionRequest) error
ListPendingByTask(ctx context.Context, taskID int64) ([]*PermissionRequest, error)
// Page 分页查询权限请求(按 CreatedAt 升序);taskID 为 0 表示全部任务,statuses 为空表示全部状态。
Page(ctx context.Context, offset, limit int, taskID int64, statuses ...PermissionStatus) ([]*PermissionRequest, int64, error)
}
PermissionRepository 持久化权限请求。
func NewGormPermissionRepository ¶
func NewGormPermissionRepository(db *gorm.DB) PermissionRepository
NewGormPermissionRepository 创建基于数据库的权限请求 Repository。
func NewMemoryPermissionRepository ¶
func NewMemoryPermissionRepository() PermissionRepository
NewMemoryPermissionRepository 创建权限请求的内存实现。
type PermissionRequest ¶
type PermissionRequest struct {
ID int64 `json:"id,string" gorm:"column:id;primaryKey;type:bigint;autoIncrement:false"`
TaskID int64 `json:"task_id,string" gorm:"column:task_id;type:bigint;index"`
SessionID string `json:"session_id,omitempty" gorm:"column:session_id;type:varchar(64)"`
Operation Operation `json:"operation" gorm:"serializer:json"`
Status PermissionStatus `json:"status" gorm:"column:status;type:varchar(32);index"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty" gorm:"column:resolved_at"`
ResolvedBy *string `json:"resolved_by,omitempty" gorm:"column:resolved_by;type:varchar(64)"`
}
PermissionRequest 记录一次权限请求及其决策结果,是权限域的持久化对象。
它是“数据库才是状态源”这一原则的载体:Agent 阻塞等待的只是内存中的 channel, 真正的状态始终保存在 Repository 中,因此浏览器刷新 / 后端重启后仍可恢复。
func NewPermissionRequest ¶
func NewPermissionRequest(taskID int64, sessionID string, operation Operation) *PermissionRequest
NewPermissionRequest 构建一个 pending 状态的权限请求。
func (*PermissionRequest) BeforeCreate ¶ added in v0.1.3
func (p *PermissionRequest) BeforeCreate(_ *gorm.DB) error
BeforeCreate 在写入数据库前用雪花 ID 初始化主键。
func (*PermissionRequest) Decision ¶
func (p *PermissionRequest) Decision() PermissionDecision
Decision 把当前状态映射为 Agent 可消费的决策结果。
func (PermissionRequest) TableName ¶
func (PermissionRequest) TableName() string
TableName 返回权限请求表的表名。
func (*PermissionRequest) TransitionTo ¶
func (p *PermissionRequest) TransitionTo(next PermissionStatus) bool
TransitionTo 校验并执行权限状态迁移;非法迁移返回 false 且不改变状态。
type PermissionStatus ¶
type PermissionStatus string
PermissionStatus 是权限请求的生命周期状态。
状态机(详见 design.md 第 8 节):
pending → approved → consumed pending → denied / expired / canceled
const ( PermissionPending PermissionStatus = "pending" // 等待人工确认 PermissionApproved PermissionStatus = "approved" // 已批准 PermissionDenied PermissionStatus = "denied" // 已拒绝 PermissionExpired PermissionStatus = "expired" // 已过期 PermissionCanceled PermissionStatus = "canceled" // 已取消(任务被取消等) PermissionConsumed PermissionStatus = "consumed" // 已消费:Agent 已恢复并继续执行 )
type Profile ¶
type Profile struct {
ID int64 `json:"id,string" gorm:"column:id;primaryKey;type:bigint;autoIncrement:false"`
Name string `json:"name" gorm:"column:name;type:varchar(64);index:idx_agent_profiles_user_name,priority:2"`
DisplayName string `json:"display_name" gorm:"column:display_name;type:varchar(128)"`
Description string `json:"description" gorm:"column:description;type:text"`
UserID string `json:"user_id" gorm:"column:user_id;type:varchar(64);index:idx_agent_profiles_user_name,priority:1"`
IsDefault bool `json:"is_default" gorm:"column:is_default"`
IsBuiltin bool `json:"is_builtin" gorm:"column:is_builtin"`
SystemPrompt string `json:"system_prompt" gorm:"column:system_prompt;type:text"`
Skills []string `json:"skills" gorm:"column:skills;serializer:json"`
Context ContextConfig `json:"context" gorm:"column:context;serializer:json"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
}
Profile 描述一类任务的 Agent 配置(系统提示词 + 技能 + 上下文注入开关)。
与 Options / Request(每次调用的动态参数)不同,Profile 是「按任务类型选择」的静态 配置快照:HTTP 层或前端在发起调用时通过 Request.Profile 指定名称,AgentService 在 调用前解析并应用(合并系统提示词、过滤技能、按开关注入背景)。
UserID 为空表示系统级(内置)Profile;非空表示某用户的自定义 Profile。
func BuiltinProfiles ¶
func BuiltinProfiles() []*Profile
BuiltinProfiles 返回框架内置的 Profile。新增内置 Profile 时在此追加。
内置 Profile 由代码定义(不落库、不可删除),与用户自定义 Profile(落库)合并后 共同构成可选的 Profile 列表。
func DefaultBuiltinProfile ¶
func DefaultBuiltinProfile() *Profile
DefaultBuiltinProfile 返回内置默认 Profile(用于兜底:未配置 ProfileManager 或解析失败时)。
func (*Profile) BeforeCreate ¶ added in v0.1.3
BeforeCreate 在写入数据库前用雪花 ID 初始化主键(仅 ID 为 0 时)。
type ProfileManager ¶
type ProfileManager struct {
// contains filtered or unexported fields
}
ProfileManager 负责 Profile 的解析、列表与增删改查编排。
它把「内置 Profile(代码定义)」与「用户自定义 Profile(持久化)」合并成一个统一的 视图:按名称解析时用户自定义优先,其次内置;未指定名称时回退到默认 Profile。
func NewProfileManager ¶
func NewProfileManager(repo ProfileRepository) *ProfileManager
NewProfileManager 创建 Profile 管理器;repo 为空时使用内存实现。
type ProfileRepository ¶
type ProfileRepository interface {
Create(ctx context.Context, profile *Profile) error
Get(ctx context.Context, id int64) (*Profile, error)
Update(ctx context.Context, profile *Profile) error
Delete(ctx context.Context, id int64) error
// ListByUser 返回某用户全部自定义 Profile(按名称升序)。
ListByUser(ctx context.Context, userID string) ([]*Profile, error)
// GetByName 按名称返回某用户的自定义 Profile。
GetByName(ctx context.Context, userID, name string) (*Profile, error)
// GetDefault 返回某用户的默认自定义 Profile;不存在时返回 (nil, nil)。
GetDefault(ctx context.Context, userID string) (*Profile, error)
// ClearDefault 清除某用户除 exceptID 外的默认标记。
ClearDefault(ctx context.Context, userID string, exceptID int64) error
}
ProfileRepository 持久化用户自定义 AgentProfile。
与 TaskRepository / MemoryRepository 一致:内置 Profile 由代码定义(不落库), 仅用户自定义 Profile 通过该接口持久化。
func NewGormProfileRepository ¶
func NewGormProfileRepository(db *gorm.DB) ProfileRepository
NewGormProfileRepository 创建基于数据库的用户自定义 Profile Repository。
func NewMemoryProfileRepository ¶
func NewMemoryProfileRepository() ProfileRepository
NewMemoryProfileRepository 创建 Profile 的内存实现。
type ProjectContextProvider ¶
type ProjectContextProvider interface {
// ProjectContext 返回当前用户激活项目下的上下文文本块;无可用内容时返回空串。
//
// 返回的文本会作为独立段落追加到 SystemPrompt 末尾。
ProjectContext(ctx context.Context, userID string) (string, error)
}
ProjectContextProvider 是可选的领域上下文提供者。
AgentService 在调用前通过它把当前项目相关的背景(例如已完成的分析节点)注入 SystemPrompt,让 Agent「知道」当前项目的进展与可用结果。它保持 agent 包与领域层 (project / analysis)的解耦:agent 只依赖这个窄接口,具体实现由上层(manager / container)注入。
type Provider ¶
type Provider interface {
// Name 返回 Provider 唯一标识(小写,如 claude_code / codex / copilot / custom)。
Name() string
// New 基于 Options 构建 Agent 实例。
New(opts Options) (Agent, error)
}
Provider 是 Agent 的工厂接口:根据 Options 构建一个 Agent 实例。 这样同一 Provider 可以有不同的配置(不同模型 / 不同 endpoint)。
type ReasoningBlock ¶
type ReasoningBlock struct {
ID string `json:"id"` // reasoningId
Content string `json:"content"` // 完整思考文本
}
ReasoningBlock 是一段完整的思考内容(对应 Provider 的完整 reasoning 事件)。
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry 负责注册与解析 Provider。 容器启动时把全部 Provider 注册进来,运行时按名称解析。
func NewRegistry ¶
NewRegistry 创建 Registry 并注册传入的 Provider。
type Request ¶
type Request struct {
// Provider 可选:强制指定 Provider 名称;为空则使用 Client 的默认 Provider。
Provider string `json:"provider"`
// Model 可选:模型名称,为空时由 Provider 自行决定。
Model string `json:"model"`
// SessionID 可选:会话标识,用于把多次调用关联到同一会话(与权限 / 任务联动)。
SessionID string `json:"session_id"`
// UserID 可选:发起调用的用户,用于记忆(memory)的归属隔离与检索。
UserID string `json:"user_id,omitempty"`
// Profile 可选:AgentProfile 名称,AgentService 据此解析系统提示词、技能与上下文注入开关。
Profile string `json:"profile,omitempty"`
// Skills 可选:本次调用启用的技能名列表;为空表示使用默认全部技能。
Skills []string `json:"skills,omitempty"`
// SystemPrompt 系统提示词。
SystemPrompt string `json:"system_prompt"`
// Messages 对话上下文(不含 SystemPrompt)。
Messages []Message `json:"messages"`
// WorkingDir 可选:Agent 执行的工作目录。
WorkingDir string `json:"working_dir"`
// Env 可选:额外环境变量(也可携带 Provider 特有开关)。
Env map[string]string `json:"env"`
// MaxTokens 可选:最大输出 token 数,0 表示不限制。
MaxTokens int `json:"max_tokens"`
// Stream 可选:任务模式下是否使用流式调用;默认 false 使用 Invoke。
Stream bool `json:"stream"`
// Timeout 可选:单次调用超时,0 表示不限制。
Timeout time.Duration `json:"-"`
}
Request 描述一次 Agent 调用请求,与具体 Provider 无关。
type Result ¶
type Result struct {
Content string `json:"content"`
Usage Usage `json:"usage"`
Raw json.RawMessage `json:"raw,omitempty"` // Provider 原始返回,便于调试与扩展
}
Result 是一次 Invoke / Stream 调用的最终聚合结果。
type Runtime ¶
type Runtime interface {
// Emit 输出一个流式事件。
Emit(ctx context.Context, event StreamEvent) error
// RequestPermission 创建权限请求并阻塞等待决策(allow / deny)。
RequestPermission(ctx context.Context, operation Operation) (PermissionDecision, error)
// WaitPermission 等待一个已存在权限请求(permissionID)的决策。
WaitPermission(ctx context.Context, permissionID int64) (PermissionDecision, error)
}
Runtime 是 Agent 执行期间的运行时环境,由上层(Client 或 AgentService)注入。
Agent 通过它完成三件事:
- Emit:向外输出流式事件(文本 / 推理 / 工具调用 / 权限通知等);
- RequestPermission:创建一个权限请求并阻塞等待用户 / 策略决策;
- WaitPermission:等待一个已存在的权限请求的决策(用于恢复场景)。
该接口把 Agent 与“持久化、通知、权限决策”等业务关注点解耦: Agent 只描述“要做什么”,具体“能不能做”由 Runtime 背后的 PermissionManager / Policy 决定。
func NewStandaloneRuntime ¶
func NewStandaloneRuntime(handler StreamHandler) Runtime
NewStandaloneRuntime 返回一个独立于任务上下文的 Runtime,用于 Client.Invoke / Client.Stream 这类“无任务、无 UI”的一次性调用。
行为约定:
- Emit:直接把事件交给 handler(handler 为 nil 时丢弃);
- RequestPermission:应用默认策略,ask 降级为 allow(宽松放行),保证链路可跑通;
- WaitPermission:无解析器,直接返回 ErrNoPermissionResolver。
type ServiceConfig ¶
type ServiceConfig struct {
Client *Client
Tasks TaskRepository
Perms *PermissionManager
Events EventRepository
Bus EventBus
Policy PermissionPolicy
Memory *MemoryManager
Project ProjectContextProvider
Profiles *ProfileManager
}
ServiceConfig 是 AgentService 的依赖配置。
type SkillCall ¶
type SkillCall struct {
ID string `json:"id"` // skillCallId
Name string `json:"name"` // 技能名
Arguments any `json:"arguments,omitempty"`
}
SkillCall 是一次完整的技能调用(对应模型发起的 skill 调用)。
type SkillCallProvider ¶
SkillCallProvider 由 Provider 提供:根据上一轮结果决定下一批待执行的技能调用。 返回空切片表示不再有技能调用,循环结束。
type SkillLoop ¶
type SkillLoop struct {
// contains filtered or unexported fields
}
SkillLoop 驱动标准的 skill-call 循环:执行 → 回传结果 → 再执行,直至无更多技能调用。
用法与 ToolLoop 对称:
resp := model(messages, skills)
for resp.hasSkillCalls() {
results := loop.Run(ctx, func(ctx, last) ([]agent.SkillCall, error) {
messages = appendSkillResults(messages, last)
resp = model(messages, skills)
return resp.skillCalls(), nil
})
}
type SkillPermissionResolver ¶
SkillPermissionResolver 把一次技能调用映射为需要授权的 Operation。
返回 (op, true) 表示该技能需要权限确认(执行前阻塞等待决策); 返回 (op, false) 表示直接放行。
type SkillResultEvent ¶
type SkillResultEvent struct {
CallID string `json:"call_id"`
Name string `json:"name"`
Content string `json:"content"`
IsError bool `json:"is_error"`
}
SkillResultEvent 是 skill_result 事件的结构化载荷。
type SkillRunner ¶
type SkillRunner struct {
// contains filtered or unexported fields
}
SkillRunner 把 skill.Invoker 与 Runtime 桥接:执行技能调用并输出事件, 同时承载可选的权限门禁(把技能调用映射为 Operation,执行前请求授权)。
func NewSkillRunner ¶
func NewSkillRunner(inv *skill.Invoker, rt Runtime) *SkillRunner
NewSkillRunner 创建技能执行器;inv 为 nil 时使用空注册表的执行器。
func (*SkillRunner) Run ¶
Run 执行一次技能调用:
- 输出 skill_call 事件(完整块,落库);
- 若配置了权限映射,执行前通过 Runtime.RequestPermission 阻塞等待决策;
- 执行技能;
- 输出 skill_result 事件并返回结果。
func (*SkillRunner) SetPermissionResolver ¶
func (r *SkillRunner) SetPermissionResolver(resolver SkillPermissionResolver) *SkillRunner
SetPermissionResolver 设置权限映射(可选),返回自身便于链式调用。
type StreamEvent ¶
type StreamEvent struct {
Type StreamEventType `json:"type"`
Content string `json:"content,omitempty"` // 仅增量事件使用
Data any `json:"data,omitempty"` // 完整块的结构化数据(reasoning/message/tool_call/turn)
Err error `json:"-"` // 仅当 Type == StreamEventError 时有效
}
StreamEvent 是一次流式输出过程中的单个事件。
type StreamEventType ¶
type StreamEventType string
StreamEventType 枚举流式事件类型。
事件分为两类:
- 增量(delta):text / reasoning_delta,用于前端实时渲染,默认不落库(仅走 WS/SSE 广播);
- 完整块(block):turn_start / turn_end / reasoning / message / tool_call / tool_result, 是时间线的 source of truth,会持久化到 EventRepository。
const ( // —— 增量(delta)—— StreamEventText StreamEventType = "text" // 文本增量 StreamEventReasoningDelta StreamEventType = "reasoning_delta" // 思维链/推理增量 // —— 完整块(block)—— StreamEventTurnStart StreamEventType = "turn_start" // 一轮开始(Data 为 TurnBlock) StreamEventTurnEnd StreamEventType = "turn_end" // 一轮结束(Data 为 TurnBlock) StreamEventReasoning StreamEventType = "reasoning" // 完整思考块(Data 为 ReasoningBlock) StreamEventMessage StreamEventType = "message" // 完整 assistant 消息(Data 为 MessageBlock) StreamEventToolCall StreamEventType = "tool_call" // 完整工具调用(Data 为 ToolCall) StreamEventToolResult StreamEventType = "tool_result" // 工具调用结果 StreamEventSkillCall StreamEventType = "skill_call" // 完整技能调用(Data 为 SkillCall) StreamEventSkillResult StreamEventType = "skill_result" // 技能调用结果 StreamEventPermission StreamEventType = "permission" // 权限请求通知(真正状态见 PermissionRequest) StreamEventPermissionResult StreamEventType = "permission_result" // 权限决策结果通知 StreamEventDone StreamEventType = "done" // 正常结束 StreamEventError StreamEventType = "error" // 出错结束 )
type StreamHandler ¶
type StreamHandler func(ctx context.Context, event StreamEvent) error
StreamHandler 消费流式事件;返回非 nil 错误时中断流式调用。
type Task ¶
type Task struct {
ID int64 `json:"id,string" gorm:"column:id;primaryKey;type:bigint;autoIncrement:false"`
SessionID string `json:"session_id,omitempty" gorm:"column:session_id;type:varchar(64);index"`
Provider string `json:"provider" gorm:"column:provider;type:varchar(64)"`
Model string `json:"model,omitempty" gorm:"column:model;type:varchar(128)"`
Status TaskStatus `json:"status" gorm:"column:status;type:varchar(32);index"`
WorkingDir string `json:"working_dir,omitempty" gorm:"column:working_dir;type:text"`
// Request 保存原始请求,用于恢复时重建上下文。
Request Request `json:"request,omitempty" gorm:"serializer:json"`
// Error 保存最近一次错误信息(Status == failed 时有效)。
Error string `json:"error,omitempty" gorm:"column:error;type:text"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
StartedAt *time.Time `json:"started_at,omitempty" gorm:"column:started_at"`
FinishedAt *time.Time `json:"finished_at,omitempty" gorm:"column:finished_at"`
}
Task 是一次 Agent 调用的持久化对象。
它与 PermissionRequest 形成两级状态机:Task 记录“整体执行到哪一步”, PermissionRequest 记录“某个具体操作是否被允许”。后端重启后,可根据 Task.Status 与 pending 的 PermissionRequest 重建运行态(见 Recovery)。
func (*Task) BeforeCreate ¶ added in v0.1.3
BeforeCreate 在写入数据库前用雪花 ID 初始化主键。
func (*Task) TransitionTo ¶
func (t *Task) TransitionTo(next TaskStatus) bool
TransitionTo 校验并执行任务状态迁移;非法迁移返回 false 且不改变状态。
type TaskRepository ¶
type TaskRepository interface {
Create(ctx context.Context, task *Task) error
Get(ctx context.Context, id int64) (*Task, error)
Update(ctx context.Context, task *Task) error
ListByStatus(ctx context.Context, statuses ...TaskStatus) ([]*Task, error)
// Page 分页查询任务(按 CreatedAt 升序);statuses 为空表示全部状态。
Page(ctx context.Context, offset, limit int, statuses ...TaskStatus) ([]*Task, int64, error)
}
TaskRepository 持久化 Agent 任务。
func NewGormTaskRepository ¶
func NewGormTaskRepository(db *gorm.DB) TaskRepository
NewGormTaskRepository 创建基于数据库的任务 Repository。
func NewMemoryTaskRepository ¶
func NewMemoryTaskRepository() TaskRepository
NewMemoryTaskRepository 创建任务的内存实现。
type TaskStatus ¶
type TaskStatus string
TaskStatus 是 Agent 任务的生命周期状态。
状态机(详见 design.md 第 7 节):
created → running → completed
↘ failed / canceled
running → waiting_permission → running
const ( TaskCreated TaskStatus = "created" // 已创建,尚未开始 TaskRunning TaskStatus = "running" // 正在执行 TaskWaitingPermission TaskStatus = "waiting_permission" // 等待权限确认 TaskCompleted TaskStatus = "completed" // 已完成 TaskFailed TaskStatus = "failed" // 失败 TaskCanceled TaskStatus = "canceled" // 已取消 )
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"` // toolCallId
Name string `json:"name"` // 工具名
Arguments any `json:"arguments,omitempty"`
}
ToolCall 是一次完整的工具调用(对应 AssistantMessageToolRequest)。
type ToolCallProvider ¶
ToolCallProvider 由 Provider 提供:根据上一轮结果决定下一批待执行的工具调用。 返回空切片表示不再有工具调用,循环结束。
type ToolLoop ¶
type ToolLoop struct {
// contains filtered or unexported fields
}
ToolLoop 驱动标准的 tool-call 循环:执行 → 回传结果 → 再执行,直至无更多工具调用。
Provider 侧通常这样配合:
resp := model(messages, tools)
for resp.hasToolCalls() {
results := loop.Run(ctx, func(ctx, last) ([]agent.ToolCall, error) {
messages = appendToolResults(messages, last) // 把结果回填
resp = model(messages, tools)
return resp.toolCalls(), nil
})
}
type ToolPermissionResolver ¶
ToolPermissionResolver 把一次工具调用映射为需要授权的 Operation。
返回 (op, true) 表示该工具需要权限确认(执行前阻塞等待决策); 返回 (op, false) 表示直接放行。
type ToolResultEvent ¶
type ToolResultEvent struct {
CallID string `json:"call_id"`
Name string `json:"name"`
Content string `json:"content"`
IsError bool `json:"is_error"`
}
ToolResultEvent 是 tool_result 事件的结构化载荷。
type ToolRunner ¶
type ToolRunner struct {
// contains filtered or unexported fields
}
ToolRunner 把 tool.Executor 与 Runtime 桥接:执行工具调用并输出事件, 同时承载可选的权限门禁(把工具调用映射为 Operation,执行前请求授权)。
func NewToolRunner ¶
func NewToolRunner(exec *tool.Executor, rt Runtime) *ToolRunner
NewToolRunner 创建工具执行器;exec 为 nil 时使用空注册表的执行器。
func (*ToolRunner) Run ¶
Run 执行一次工具调用:
- 输出 tool_call 事件(完整块,落库);
- 若配置了权限映射,执行前通过 Runtime.RequestPermission 阻塞等待决策;
- 执行工具;
- 输出 tool_result 事件并返回结果。
func (*ToolRunner) SetPermissionResolver ¶
func (r *ToolRunner) SetPermissionResolver(resolver ToolPermissionResolver) *ToolRunner
SetPermissionResolver 设置权限映射(可选),返回自身便于链式调用。
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package providers 提供 agent.Provider 的内置实现。
|
Package providers 提供 agent.Provider 的内置实现。 |
|
Package skill 定义 Agent 技能(skill)调用框架的基础设施。
|
Package skill 定义 Agent 技能(skill)调用框架的基础设施。 |
|
builtin
Package builtin 提供框架内置的技能(如 echo)。
|
Package builtin 提供框架内置的技能(如 echo)。 |
|
Package tool 定义 Agent 工具调用(function calling)的基础设施。
|
Package tool 定义 Agent 工具调用(function calling)的基础设施。 |
|
builtin
Package builtin 提供框架内置的工具(如 get_weather)。
|
Package builtin 提供框架内置的工具(如 get_weather)。 |