Documentation
¶
Index ¶
- Variables
- func CountMessageTokens(msg map[string]any) (int, error)
- func CountMessagesTokens(messages []map[string]any) (total int, byRole map[string]int, err error)
- func CountTokens(text string) (int, error)
- func Merge(builtin map[string]Provider, user *UserLLMConfig) map[string]Provider
- func SaveUserConfig(path string, cfg *UserLLMConfig) error
- type APIError
- type AvailableModel
- type CallOptions
- type CallToolOptions
- type CallToolStatus
- type Client
- func (c *Client) CallTool(ctx context.Context, providerName, modelID string, messages []map[string]any, ...) (json.RawMessage, error)
- func (c *Client) ChatStream(ctx context.Context, providerName string, messages []map[string]any, ...) <-chan StreamEvent
- func (c *Client) GenerateText(ctx context.Context, providerName string, messages []map[string]any, ...) (string, error)
- func (c *Client) ProviderModel(providerName, modelID string) (*ModelInfo, bool)
- func (c *Client) Providers() map[string]Provider
- func (c *Client) Reload(providers map[string]Provider)
- type LLMConfigView
- type ModelInfo
- type Provider
- type ProviderView
- type SourceItem
- type StreamEvent
- type StreamEventType
- type TestConnectionInput
- type TestConnectionResult
- type ToolCallDelta
- type UserLLMConfig
- type WebSearchResult
Constants ¶
This section is empty.
Variables ¶
var Builtin = map[string]Provider{ "deepseek": { Name: "DeepSeek", ChatURL: "https://api.deepseek.com/v1/chat/completions", PlatformURL: "https://platform.deepseek.com", HelpText: "使用邮箱或手机号注册。完成实名认证后,进入「API Keys」创建密钥。预付费模式,最低充值 ¥1。", Temperature: floatPtr(0.7), Models: []ModelInfo{ { ID: "deepseek-v4-flash", Name: "DeepSeek V4 Flash", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, ReasoningLevels: []string{"high", "max"}, SupportsVision: false, }, { ID: "deepseek-v4-pro", Name: "DeepSeek V4 Pro", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, ReasoningLevels: []string{"high", "max"}, SupportsVision: false, }, }, BuildRequest: nil, }, "opencode": { Name: "OpenCode Zen", ChatURL: "https://opencode.ai/zen/v1/chat/completions", PlatformURL: "https://opencode.ai/auth", HelpText: "OpenCode Zen 是 opencode.ai 的按量付费网关,提供 DeepSeek/GLM/Kimi/MiniMax 等精选模型及多个免费模型(均兼容 OpenAI chat/completions)。在 opencode.ai/auth 注册、添加账单信息后复制 API Key 填入。OpenCode 网关要求携带 x-opencode-session 会话头与自定义 User-Agent,Goink 已自动处理,无需额外配置。模型列表随时变动,可用下方「自动发现模型」拉取最新。", Temperature: floatPtr(0.7), BuildHeaders: opencodeBuildHeaders, Models: []ModelInfo{ { ID: "glm-5.3", Name: "GLM-5.3", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-5.3-flash", Name: "GLM-5.3 Flash", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-5.2", Name: "GLM-5.2", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-5.1", Name: "GLM-5.1", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "kimi-k3", Name: "Kimi K3", ContextWindow: 1_048_576, MaxOutputTokens: 131_072, SupportsThinking: true, ReasoningLevels: []string{"max"}, SupportsVision: true, }, { ID: "kimi-k2.7-code", Name: "Kimi K2.7 Code", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "kimi-k2.6", Name: "Kimi K2.6", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "deepseek-v4-pro", Name: "DeepSeek V4 Pro", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: false, }, { ID: "deepseek-v4-flash", Name: "DeepSeek V4 Flash", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: false, }, { ID: "deepseek-v4-flash-vision-exp", Name: "DeepSeek V4 Flash Vision Exp", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: true, }, { ID: "minimax-m3", Name: "MiniMax M3", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "minimax-m2.7", Name: "MiniMax M2.7", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "big-pickle", Name: "Big Pickle", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: false, SupportsVision: false, }, { ID: "mimo-v2.5-free", Name: "MiMo-V2.5 Free", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "ling-3.0-flash-fin-free", Name: "Ling 3.0 Flash Fin Free", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: false, SupportsVision: false, }, { ID: "nemotron-3-ultra-free", Name: "Nemotron 3 Ultra Free", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: false, SupportsVision: false, }, { ID: "nemotron-3.5-lightning-free", Name: "Nemotron 3.5 Lightning Free", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: false, SupportsVision: false, }, }, }, "opencode-go": { Name: "OpenCode Go", ChatURL: "https://opencode.ai/zen/go/v1/chat/completions", PlatformURL: "https://opencode.ai/auth", HelpText: "OpenCode Go 是 opencode.ai 的订阅制服务($10/月),覆盖 Kimi/GLM/DeepSeek/MiMo/Hy 等开源模型。在 opencode.ai/auth 注册并订阅 Go 后复制 API Key 填入。OpenCode Go 强制要求携带 x-opencode-session 会话头与自定义 User-Agent,Goink 已自动处理,无需额外配置。模型列表随订阅变动,可用下方「自动发现模型」拉取最新。", Temperature: floatPtr(0.7), BuildHeaders: opencodeBuildHeaders, Models: []ModelInfo{ { ID: "kimi-k3", Name: "Kimi K3", ContextWindow: 1_048_576, MaxOutputTokens: 131_072, SupportsThinking: true, ReasoningLevels: []string{"max"}, SupportsVision: true, }, { ID: "glm-5.3", Name: "GLM-5.3", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "deepseek-v4-pro", Name: "DeepSeek V4 Pro", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: false, }, { ID: "deepseek-v4-flash", Name: "DeepSeek V4 Flash", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: false, }, { ID: "deepseek-v4.1-flash", Name: "DeepSeek V4.1 Flash", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: false, }, { ID: "deepseek-v4-flash-vision-exp", Name: "DeepSeek V4 Flash Vision Exp", ContextWindow: 1_000_000, MaxOutputTokens: 384_000, SupportsThinking: true, SupportsVision: true, }, { ID: "glm-5.3-flash", Name: "GLM-5.3 Flash", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "kimi-k2.7-code", Name: "Kimi K2.7 Code", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "glm-5.2", Name: "GLM-5.2", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-5.1", Name: "GLM-5.1", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "kimi-k2.6", Name: "Kimi K2.6", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "longcat-2.0", Name: "LongCat-2.0", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "mimo-v2.5", Name: "MiMo-V2.5", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "mimo-v2.5-pro", Name: "MiMo-V2.5 Pro", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "hy4-preview", Name: "Hy4 preview", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "hy3", Name: "Hy3", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, }, }, "doubao": { Name: "Doubao", ChatURL: "https://ark.cn-beijing.volces.com/api/v3/chat/completions", PlatformURL: "https://console.volcengine.com/ark/", HelpText: "注册火山引擎并实名认证,进入火山方舟控制台。① 在「API 密钥管理」创建 API Key;② 在「开通管理」开通所需模型,每个模型有试用额度。", Temperature: floatPtr(0.1), Models: []ModelInfo{ { ID: "doubao-seed-2-1-pro-260628", Name: "Seed 2.1 Pro", ContextWindow: 256_000, MaxOutputTokens: 256_000, SupportsThinking: true, SupportsVision: true, }, { ID: "doubao-seed-2-1-turbo-260628", Name: "Seed 2.1 Turbo", ContextWindow: 256_000, MaxOutputTokens: 256_000, SupportsThinking: true, SupportsVision: true, }, { ID: "doubao-seed-2-0-lite-260428", Name: "Seed 2.0 Lite", ContextWindow: 256_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "doubao-seed-2-0-code-preview-260215", Name: "Seed 2.0 Code Preview", ContextWindow: 256_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "doubao-seed-character-260628", Name: "Seed Character", ContextWindow: 128_000, MaxOutputTokens: 32_000, SupportsThinking: true, SupportsVision: true, }, }, }, "qwen": { Name: "Qwen", ChatURL: "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions", PlatformURL: "https://platform.qianwenai.com", HelpText: "注册后在「工作台 → API Key 管理」创建密钥。新用户有免费额度,API 地址统一使用 dashscope.aliyuncs.com,无需区分地域。如使用阿里云百炼平台,需自行将上方 Chat URL 替换为百炼地址。", Temperature: floatPtr(0.7), BuildRequest: qwenBuildRequest, Models: []ModelInfo{ { ID: "qwen3.7-max", Name: "Qwen3.7 Max", ContextWindow: 1_000_000, MaxOutputTokens: 64_000, SupportsThinking: true, SupportsVision: true, }, { ID: "qwen3.7-plus", Name: "Qwen3.7 Plus", ContextWindow: 1_000_000, MaxOutputTokens: 64_000, SupportsThinking: true, SupportsVision: true, }, { ID: "qwen3.6-plus", Name: "Qwen3.6 Plus", ContextWindow: 1_000_000, MaxOutputTokens: 64_000, SupportsThinking: true, SupportsVision: true, }, { ID: "qwen3.6-flash", Name: "Qwen3.6 Flash", ContextWindow: 1_000_000, MaxOutputTokens: 64_000, SupportsThinking: true, SupportsVision: true, }, }, }, "zhipu": { Name: "GLM", ChatURL: "https://open.bigmodel.cn/api/paas/v4/chat/completions", PlatformURL: "https://open.bigmodel.cn", HelpText: "手机号或微信注册。注册后点击「控制台」→「API Keys」→「新建」创建密钥。注册赠送体验额度。", Temperature: floatPtr(1.0), Models: []ModelInfo{ { ID: "glm-5.1", Name: "GLM-5.1", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-5", Name: "GLM-5", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-5-turbo", Name: "GLM-5-Turbo", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-4.7", Name: "GLM-4.7", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-4.7-flashx", Name: "GLM-4.7-FlashX", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "glm-4.7-flash", Name: "GLM-4.7 Flash", ContextWindow: 200_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, }, BuildRequest: nil, }, "minimax": { Name: "MiniMax", ChatURL: "https://api.minimaxi.com/v1/chat/completions", PlatformURL: "https://platform.minimaxi.com", HelpText: "手机号注册。赠送 ¥15 体验金。点击控制台 →「接口管理」→「创建 API Key」获取密钥。按量付费需在「余额」页面充值。", Temperature: floatPtr(1.0), BuildRequest: minimaxBuildRequest, Models: []ModelInfo{ { ID: "MiniMax-M3", Name: "MiniMax M3", ContextWindow: 1_000_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "MiniMax-M2.7", Name: "MiniMax M2.7", ContextWindow: 204_800, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "MiniMax-M2.5", Name: "MiniMax M2.5", ContextWindow: 204_800, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, }, }, "mimo": { Name: "MiMo", ChatURL: "https://api.xiaomimimo.com/v1/chat/completions", PlatformURL: "https://platform.xiaomimimo.com", HelpText: "手机号注册。在控制台左侧「邀请有礼」输入邀请码领取 ¥10 体验金(有效期 40 天),然后在「API Keys」创建密钥。", Temperature: floatPtr(1.0), BuildHeaders: mimoBuildHeaders, Models: []ModelInfo{ { ID: "mimo-v2.5-pro", Name: "MiMo V2.5 Pro", ContextWindow: 1_000_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, { ID: "mimo-v2.5", Name: "MiMo V2.5", ContextWindow: 1_000_000, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: false, }, }, BuildRequest: nil, }, "moonshot": { Name: "Kimi", ChatURL: "https://api.moonshot.cn/v1/chat/completions", PlatformURL: "https://platform.kimi.com", HelpText: "手机号或微信登录。在控制台「API Key 管理」创建密钥。新用户赠送 ¥15 体验金,初始 RPM=3。累计充值 ¥50 升 Tier 1(RPM=200)。", BuildRequest: moonshotBuildRequest, Models: []ModelInfo{ { ID: "kimi-k2.7-code", Name: "Kimi K2.7 Code", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "kimi-k2.6", Name: "Kimi K2.6", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "kimi-k2.5", Name: "Kimi K2.5", ContextWindow: 262_144, MaxOutputTokens: 128_000, SupportsThinking: true, SupportsVision: true, }, { ID: "kimi-k3", Name: "Kimi K3", ContextWindow: 1_048_576, MaxOutputTokens: 131_072, SupportsThinking: true, ReasoningLevels: []string{"max"}, SupportsVision: true, }, }, }, }
Builtin 内置 provider 模板。APIKey 留空,运行时由用户配置注入。
Functions ¶
func CountMessageTokens ¶
CountMessageTokens 计算一条 OpenAI 格式消息的 token 数。 与 Python _count_msg_tokens 一致:只算 content + tool_calls + tool_call_id + reasoning_content。
func CountMessagesTokens ¶
CountMessagesTokens 计算消息列表的总 token 数,并按 role 分组计数。
func Merge ¶
func Merge(builtin map[string]Provider, user *UserLLMConfig) map[string]Provider
Merge 合并内置模板和用户配置,返回组装完成的 Provider map。 内置模型全量加入(随代码版本),用户自定义模型去重追加。只产出用户配置过的 Provider。
func SaveUserConfig ¶
func SaveUserConfig(path string, cfg *UserLLMConfig) error
SaveUserConfig 加密并写入用户 LLM 配置到文件。
Types ¶
type APIError ¶
type APIError struct {
StatusCode int
Message string
Retryable bool
RetryAfter time.Duration // 服务商指定的重试等待时间(来自 Retry-After header),0 表示无指定
Kind string // 错误类型标记,用于 agent 层区分处理路径(如 "tool_args_invalid");空字符串=普通错误
}
APIError 表示 LLM API 的调用错误,包含可重试标记。
type AvailableModel ¶
type AvailableModel struct {
Key string // "deepseek/deepseek-v4-pro"
ModelID string // "deepseek-v4-pro"(独立字段,不依赖 Key 拆分)
ProviderKey string // "deepseek"(小写 key,与 ProviderView.Key 一致,供 ProviderIcon 匹配)
ProviderName string // "DeepSeek"
ModelName string // "DeepSeek V4 Pro"
ContextWindow int
MaxOutputTokens int
SupportsThinking bool
ReasoningLevels []string
SupportsVision bool
}
AvailableModel 是前端下拉列表的模型选项。
func Models ¶
func Models(providers map[string]Provider) []AvailableModel
Models 从 Provider map 中提取前端下拉列表。
type CallOptions ¶
type CallOptions struct {
Temperature *float64 // 不传走 Provider 默认
MaxTokens *int // 不传走 ModelInfo 默认
ReasoningEffort *string // 不传从 ModelInfo 取
ThinkingEnabled *bool // 不传从 ModelInfo 判断
ToolChoice any // OpenAI tool_choice payload; nil = provider default
SessionID string // 会话标识(如 Goink session_id),仅需要会话感知的服务商消费;空=无会话上下文(hook 内部兜底)
}
CallOptions LLM 调用的可选参数。nil 时全部使用 Provider/ModelInfo 默认值。
type CallToolOptions ¶
type CallToolOptions struct {
ReasoningEffort string // 空则不设置
MaxTokens int // 0 表示走 ModelInfo 默认
Attempts int // 最大尝试次数,≤1 表示只试一次
OnStatus func(CallToolStatus) // 状态回调,可 nil
}
CallToolOptions 是 CallTool 的可选参数。
type CallToolStatus ¶
type CallToolStatus string
CallToolStatus 描述一次 toolcall 调用过程中的状态,用于 OnStatus 回调推送。
const ( CallToolThinking CallToolStatus = "thinking" // 模型推理中 CallToolGenerating CallToolStatus = "generating" // 模型输出工具参数中 )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client 是 LLM 流式调用的传输层。 持有多 provider,Run 时根据 providerName 选择合适的后端。
func (*Client) CallTool ¶
func (c *Client) CallTool( ctx context.Context, providerName, modelID string, messages []map[string]any, tools []map[string]any, toolName string, opts *CallToolOptions, ) (json.RawMessage, error)
CallTool 请求 LLM 调用指定工具并返回结构化 JSON。
部分供应商的 thinking mode 不兼容 tool_choice,因此只提供 tools, 由提示词约束模型调用目标工具。
tools 数组由调用方组装(通常只含 1 个工具);本函数负责流式接收、 重试、错误聚合。OnStatus 在 LLM 流事件时被调用,nil 时跳过。
返回值是 EventToolCallEnd 的 ArgumentsJSON(json.RawMessage), 调用方按目标类型 json.Unmarshal。
func (*Client) ChatStream ¶
func (c *Client) ChatStream( ctx context.Context, providerName string, messages []map[string]any, tools []map[string]any, model string, opts *CallOptions, ) <-chan StreamEvent
ChatStream 发起流式对话,返回 SSE 事件 channel。
providerName 指明使用哪个 Provider,messages/tools 由调用方按 OpenAI Function Calling 格式组装。 Client 负责拼装完整 payload 并注入流式参数和钩子处理。
ctx 取消时底层 HTTP 连接被中止,channel 随之关闭。
func (*Client) GenerateText ¶
func (c *Client) GenerateText( ctx context.Context, providerName string, messages []map[string]any, model string, ) (string, error)
GenerateText 发起非流式对话,返回模型生成的纯文本。 messages 由调用方自行组装,格式与 ChatStream 一致。
func (*Client) ProviderModel ¶
ProviderModel 在指定 provider 中按 model ID 查找模型元信息。
type LLMConfigView ¶
type LLMConfigView struct {
Providers []ProviderView `json:"providers"`
}
LLMConfigView 是 GetLLMConfig 返回的完整配置视图,合并内置模板和用户配置。
func BuildConfigView ¶
func BuildConfigView(user *UserLLMConfig) *LLMConfigView
BuildConfigView 合并内置模板和用户配置,生成前端可用的完整视图。
func (*LLMConfigView) ToUserConfig ¶
func (v *LLMConfigView) ToUserConfig() *UserLLMConfig
ToUserConfig 将前端视图转换回可持久化的 UserLLMConfig。 只保留有 APIKey 的 provider,无 key 的不写入(内置模板由 Merge 自动提供)。
保存用户填的 URL 原值,不再 normalizeURL:
- 保存前前端已通过 TestConnection 验证 URL,并把探测到的正确 URL 回写到 pv.ChatURL
- 二次 normalizeURL 会破坏已验证的 URL(测试和保存不一致)
- 内置 provider 用户未改 URL 时留空,由 Merge 用 bp.ChatURL 兜底
type ModelInfo ¶
type ModelInfo struct {
ID string `json:"id"` // 模型标识,如 "deepseek-v4-pro"
Name string `json:"name"` // 显示名称,如 "DeepSeek V4 Pro"
ContextWindow int `json:"context_window"` // 上下文窗口大小(token 数)
MaxOutputTokens int `json:"max_output_tokens"` // 最大输出 token 数
SupportsThinking bool `json:"supports_thinking"` // 是否支持思考模式
ReasoningLevels []string `json:"reasoning_levels,omitempty"` // 多级推理等级,如 ["low","high","max"];nil=二值开关
SupportsVision bool `json:"supports_vision"` // 是否支持图片输入
}
ModelInfo 描述一个具体模型的元信息。
func DiscoverModels ¶
func DiscoverModels(ctx context.Context, builtin map[string]Provider, providerName, chatURL, apiKey string) ([]ModelInfo, error)
DiscoverModels 调用 /models 端点自动发现可用模型列表。 从 chatURL 推导 modelsURL(去掉 /chat/completions,拼接 /models), 解析标准 OpenAI 格式及 Kimi 等扩展字段。返回的 ModelInfo 中未获取到的字段留零值。
type Provider ¶
type Provider struct {
Name string `json:"name"` // 供应商名称,如 "DeepSeek"
ChatURL string `json:"chat_url"` // 聊天补全端点
APIKey string `json:"api_key,omitempty"` // API 密钥
PlatformURL string `json:"-"` // 注册平台 URL,仅内置模板使用
HelpText string `json:"-"` // 注册引导文字,仅内置模板使用
Models []ModelInfo `json:"models"` // 可用模型列表
Temperature *float64 `json:"temperature,omitempty"` // 默认创意度 0~2,nil 表示未设置,运行时取内置默认
BuildRequest func(payload map[string]any) map[string]any `json:"-"` // 发送前改造请求体,nil 则原样发送
BuildHeaders func(opts *CallOptions, base map[string]string) map[string]string `json:"-"` // 发送前改造请求头,nil 则使用默认 Bearer 鉴权;opts 可为 nil(无请求级上下文)
ParseError func(body []byte) error `json:"-"` // 解析非标准错误响应体,nil 则使用默认 OpenAI 格式解析
}
Provider 定义一个大模型供应商的完整配置。 默认行为走 OpenAI 兼容格式,钩子函数用于处理供应商差异。 同时用作用户配置的 JSON 格式(Hooks 不参与序列化,反序列化后为 nil)。
type ProviderView ¶
type ProviderView struct {
Key string `json:"key"` // provider 标识符,如 "deepseek"
Name string `json:"name"` // 显示名称
ChatURL string `json:"chat_url"` // API 端点
APIKey string `json:"api_key"` // 用户配置的 key,空表示未配置
PlatformURL string `json:"platform_url"` // 注册平台链接
HelpText string `json:"help_text"` // 注册引导文字
Temperature float64 `json:"temperature"` // 默认创意度 0~2
Source string `json:"source"` // "builtin" | "custom"
BuiltinModels []ModelInfo `json:"builtin_models"` // 内置模型,自定义 provider 为 nil
CustomModels []ModelInfo `json:"custom_models"` // 用户添加的自定义模型
}
ProviderView 是单个 provider 的前端展示视图。
type SourceItem ¶
SourceItem 是单条搜索结果的元信息。
type StreamEvent ¶
type StreamEvent struct {
Type StreamEventType
Data string // EventThinking / EventContent 的文本数据
Delta *ToolCallDelta // EventToolCallStart / EventToolCallArguments / EventToolCallEnd
Usage map[string]any // EventUsage 时,原样透传 API 返回的 usage 对象
Error error // EventError 时的错误信息
}
StreamEvent 流式对话过程中产出的单个事件。 Data 承载 thinking/content 文本,Delta 承载工具调用信息,Usage 承载 token 统计。 错误事件通过 Error 字段传递。
type StreamEventType ¶
type StreamEventType int
StreamEventType 流式事件的类型。
const ( EventThinking StreamEventType = iota // 模型推理/思考内容(DeepSeek reasoning_content) EventContent // 普通文本内容 EventToolCallStart // 工具调用开始(携带名称和 ID) EventToolCallArguments // 工具参数增量(arguments 累计字符串) EventToolCallEnd // 工具调用完成(arguments 已 parse 为 JSON) EventUsage // 本次调用 token 用量 EventError // 错误(HTTP 错误或网络异常) )
type TestConnectionInput ¶
type TestConnectionInput struct {
ProviderName string `json:"provider_name"`
ChatURL string `json:"chat_url"`
APIKey string `json:"api_key"`
ModelID string `json:"model_id"`
}
TestConnectionInput 是连通性测试的参数。
type TestConnectionResult ¶ added in v1.4.2
TestConnectionResult 是连通性测试的结果。 URL 是验证通过的实际端点(可能和入参不同,是 fallback 探测到的)。 Warning 是非致命提示(如 429 限流视为通过但提示用户当前被限速)。
func TestConnection ¶
func TestConnection(ctx context.Context, builtin map[string]Provider, input TestConnectionInput) (TestConnectionResult, error)
TestConnection 发送最小化请求验证 provider 连通性。 多层 fallback:对候选 URL 逐个真测(真 key + model + stream + max_tokens=1), 找到第一个返回 200 + text/event-stream + 有效 SSE chunk(含 choices 字段)的候选, 返回该 URL。全部失败返回 error,附带最后一个候选的错误信息。
返回值:
- (TestConnectionResult{URL:...}, nil):验证通过,URL 是实际可用的端点(可能和入参不同,是 fallback 探测到的)
- (TestConnectionResult{URL:..., Warning:...}, nil):验证通过但有警告(如 429 限流视为通过)
- (TestConnectionResult{}, error):所有候选均失败
设计目标:用户填啥都能 work。
- 裸域名 https://1024token.club → 探测到 /v1/chat/completions
- base URL https://api.deepseek.com/v1 → 探测到 /v1/chat/completions
- 完整端点 https://x.com/proxy/chat → 原样通过
调用方(前端)应将返回的 URL 回写到 provider.chat_url,确保保存的 URL 和测试时一致。 Warning 非空时也应展示给用户(不影响 ok 判定,但提示当前被限流等)。
type ToolCallDelta ¶
type ToolCallDelta struct {
ToolName string // EventToolCallStart 时填充
ToolID string // EventToolCallStart 时填充
ArgumentsText string // EventToolCallArguments 时,累积后的完整 JSON 字符串
ArgumentsJSON json.RawMessage // EventToolCallEnd 时,原始 JSON 字节,由调用方按需反序列化
}
ToolCallDelta 描述一次工具调用的增量信息。 工具调用通过 SSE 流分多次下发:先来 ID 和名称,再逐片来 arguments 字符串。 客户端内部维护按 index 的累积缓冲区,流结束后校验并发送原始 JSON。
type UserLLMConfig ¶
type UserLLMConfig struct {
Providers []Provider `json:"providers"`
}
UserLLMConfig 是用户 LLM 配置的持久化格式(加密 JSON)。 一个 provider 一个 key,内置模型随代码自动更新,自定义模型需完整填写信息。
func LoadUserConfig ¶
func LoadUserConfig(path string) (*UserLLMConfig, error)
LoadUserConfig 从加密文件读取并解密用户 LLM 配置。 文件不存在时返回空的 UserLLMConfig 和 nil error。
type WebSearchResult ¶
type WebSearchResult struct {
Queries []string `json:"queries"`
Summary string `json:"summary"`
Sources []SourceItem `json:"sources"`
}
WebSearchResult 是一次 web 搜索的结果。