package types import ( "context" ) // ======================================================================== // 公共类型定义(types 包) // ======================================================================== // 为什么需要独立的 types 包? // 原结构中 llm 包用 agent.Message/agent.Tool,agent 包又用 llm.ModelRouter, // 形成 llm <-> agent 的循环依赖(Go 不允许)。 // // 解决方案: // 把 LLM 调用所需的"消息/工具/工具调用"等纯数据类型抽到 types 包, // agent 和 llm 都依赖 types,单向依赖:agent → types ← llm,agent → llm。 // // 迁移范围: // - Message(原 agent.Message) // - Tool 接口(原 agent.Tool) // - ToolCallInfo(原 agent.ToolCallInfo) // // 兼容策略: // agent 包用 type 别名保留旧 API(agent.Message = types.Message), // 老调用方无需改 import;llm 包改用 types.Xxx。 // ======================================================================== // Message 单条对话消息(system / user / assistant / tool) type Message struct { Role string `json:"role"` // 角色:system/user/assistant/tool Content string `json:"content"` // 消息正文 Timestamp int64 `json:"timestamp"` // 时间戳 ToolCall *ToolCallInfo `json:"tool_call,omitempty"` // 工具调用信息(assistant 触发工具时) // ToolCallID tool 结果帧回传时对应的 tool_calls[].id // // OpenAI Function Calling 协议要求: // assistant 帧的 tool_calls[].id 必须与后续 tool 帧的 tool_call_id 一一对应, // 否则部分厂商(讯飞 10003 / OpenAI 400)会直接拒绝请求。 // 只在 Role=="tool" 时有意义。 ToolCallID string `json:"tool_call_id,omitempty"` } // Tool Agent 可调用的工具接口 // // 实现此接口的对象注册到 Runner 后,LLM 可通过 Function Calling 自主决定调用 type Tool interface { Name() string Description() string Execute(ctx context.Context, params map[string]any) (string, error) } // ToolCallInfo 一次工具调用的完整信息 type ToolCallInfo struct { // ID 厂商返回的 tool_calls[].id(回放对话历史时必须原样带回, // 供 tool 结果帧的 tool_call_id 对应;厂商未返回时由客户端生成) ID string `json:"id,omitempty"` ToolName string `json:"tool_name"` // 工具名 Params map[string]any `json:"params"` // 调用参数 Result string `json:"result"` // 调用结果 Error string `json:"error,omitempty"` // 错误信息(失败时) } // ======================================================================== // 统一 chat 结果(供 LLM 客户端与上层共享) // ======================================================================== // 含 token 用量与计时,便于 Agent 上层把每一步落到 xk_ai_generation_step // ======================================================================== // ChatResult LLM 调用统一返回结构 // // 各 provider(DeepSeek/Spark/Qwen 等)调用 LLM 后,把内容、token 用量、耗时 // 等打包到本结构,方便 KnowledgeEnhancer 把每一步记入 step 子表 type ChatResult struct { Content string `json:"content"` // 助手文本(choices[0].message.content) Provider string `json:"provider"` // 供应商标识 Model string `json:"model"` // 实际使用的模型名 APIKeyID int `json:"api_key_id"` // 使用的密钥 ID(env 回落为 0) PromptTokens int `json:"prompt_tokens"` // 输入 token 数 CompletionTokens int `json:"completion_tokens"` // 输出 token 数 TotalTokens int `json:"total_tokens"` // 总 token 数 Usage map[string]any `json:"usage"` // 完整 usage 原始对象 DurationMs int `json:"duration_ms"` // 耗时毫秒 FinishReason string `json:"finish_reason"` // 终止原因:stop/length/content_filter/tool_calls;length=被 max_tokens 截断 ToolCall *ToolCallInfo `json:"tool_call,omitempty"` // 模型触发的工具调用(Function Calling) Raw any `json:"-"` // 供应商原始响应(不入 JSON) }