Files

87 lines
4.4 KiB
Go
Raw Permalink Normal View History

2026-08-14 21:50:48 +08:00
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)
}