// Package llm 提供与具体 provider 解耦的 LLM 抽象层。 // 所有 provider 实现都把 SDK 的 message/event 形态映射到本包定义的中立类型。 package llm import "context" // Role 标识消息发送方。 type Role string const ( RoleUser Role = "user" RoleAssistant Role = "assistant" ) // ContentBlock 是消息内容的最小单元。MVP 仅 text/image/document;tool_use/tool_result 为 mcp 预留。 type ContentBlock struct { Type string // "text" | "image" | "document" | "tool_use" | "tool_result" Text string // type=text MimeType string // type=image|document Data []byte // type=image|document(原始字节,未编码;各 provider 实现内部 base64) } // Message 是一轮对话的中立表示。 type Message struct { Role Role Blocks []ContentBlock } // ToolSpec 为 mcp 模块预留;MVP 始终空切片。 type ToolSpec struct { Name string Description string InputSchema map[string]any } // Request 是 Stream/CountTokens 共用的输入。 type Request struct { SystemPrompt string Messages []Message MaxOutputTokens int Reasoning bool Tools []ToolSpec // mcp 预留 } // StreamEventType 枚举所有流事件。 type StreamEventType string const ( EventTextDelta StreamEventType = "text_delta" EventThinkingDelta StreamEventType = "thinking_delta" EventToolCall StreamEventType = "tool_call" // 预留 EventUsage StreamEventType = "usage" EventDone StreamEventType = "done" EventError StreamEventType = "error" ) // Usage 携带本次调用的 token 计数。 type Usage struct { PromptTokens int CompletionTokens int ThinkingTokens int } // StreamEvent 是流通道里的统一事件结构。 type StreamEvent struct { Type StreamEventType Text string // text_delta / thinking_delta Usage *Usage // usage Err error // error Reason string // done.finish_reason } // LLMClient 是 Anthropic / OpenAI / Gemini 各自实现的统一接口。 type LLMClient interface { Provider() string // Stream 启动一次流式请求,返回事件 channel。channel 关闭即表示流结束。 // ctx 取消时实现层须立即终止上游 stream。 Stream(ctx context.Context, modelID string, req Request) (<-chan StreamEvent, error) // CountTokens 返回精确 token 数(远程接口);仅 admin 离线场景使用。 CountTokens(ctx context.Context, modelID string, req Request) (int, error) }