package capability // --- 静态 documented 数据表 --- // // 来源:官方文档 + AI 总结(2026-04). // 精妙之处(CLEVER): key 是 "provider:model",能覆盖同一模型经由不同 provider 的差异 // (如 anthropic:claude-opus-4-6 vs openrouter:anthropic/claude-opus-4.6 路由差异). // // 反向思维:是否应该把这表挪到 provider 包内? // 否决--probe 工具是"跨 provider 的元数据聚合器",静态表属于 probe 的私有知识, // 往 provider 包里塞会造成"provider 既是实现者又是 probe 的证据库"的角色混乱. // documentedInfo 是单条静态能力记录. type documentedInfo struct { Vision *bool // nil = 未覆盖 PDF *bool Batch *bool ParallelToolCalls *bool StrictJSON *bool MaxTools *int // nil = 未记录; >0 = 官方文档明确的工具数量上限 (L1175) Note string } // boolPtr 是 bool 字面量转指针的 helper. func boolPtr(b bool) *bool { return &b } // intPtr 是 int 字面量转指针的 helper (L1175: MaxTools 交叉验证). func intPtr(i int) *int { return &i } // documentedCapabilities 是"provider:model" → documented 能力的静态查询表. // // 历史包袱(LEGACY): OpenRouter 路径的 cache_control 不转发给 Anthropic 后端, // 所以 openrouter 的 anthropic/* 条目 Batch 都标 false-- // OpenRouter 本身没有 batch API,只有直连 provider 才能用 batch. var documentedCapabilities = map[string]documentedInfo{ // --- Anthropic 官方 --- "anthropic:claude-opus-4-6": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(true), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(false), // Anthropic 无 strict 字段,tool schema 有格式限制 Note: "官方文档 2026-04", }, "anthropic:claude-sonnet-4-6": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(true), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(false), Note: "官方文档 2026-04", }, "anthropic:claude-haiku-4-5-20251001": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(true), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(false), Note: "官方文档 2026-04", }, // --- MiniMax --- "minimax:MiniMax-M2.7": { Vision: boolPtr(true), PDF: boolPtr(false), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(true), // response_format=json_object 在 Anthropic 兼容端点支持 Note: "MiniMax 平台文档 2026-04", }, "minimax:MiniMax-M2.7-highspeed": { Vision: boolPtr(true), PDF: boolPtr(false), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(true), Note: "MiniMax-M2.7 的 highspeed 变体,能力与 M2.7 基本一致(2026-04)", }, "minimax:MiniMax-M2.5": { Vision: boolPtr(true), PDF: boolPtr(false), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(true), Note: "MiniMax 平台文档 2026-04", }, // --- OpenRouter 路径的 Anthropic 模型(能力受 OpenRouter 网关限制)--- "openrouter:anthropic/claude-opus-4.6": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(false), // OpenRouter 无 batch API ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(false), Note: "经由 OpenRouter 网关,batch 不可用", }, "openrouter:anthropic/claude-sonnet-4.6": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(false), Note: "经由 OpenRouter 网关,batch 不可用", }, "openrouter:anthropic/claude-haiku-4.5": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(false), Note: "经由 OpenRouter 网关,batch 不可用", }, // --- OpenRouter 路径的非 Anthropic 模型 --- "openrouter:openai/gpt-4o": { Vision: boolPtr(true), PDF: boolPtr(false), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(true), // OpenAI Chat API 原生 strict MaxTools: intPtr(128), // OpenAI Chat API OpenAPI spec explicit (L1175) Note: "OpenAI GPT-4o 经由 OpenRouter(2026-04)", }, "openrouter:google/gemini-2.0-flash-001": { Vision: boolPtr(true), PDF: boolPtr(true), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(true), Note: "Google Gemini 经由 OpenRouter(2026-04)", }, "openrouter:deepseek/deepseek-r1": { Vision: boolPtr(false), PDF: boolPtr(false), Batch: boolPtr(false), ParallelToolCalls: boolPtr(false), // R1 thinking 模型,tool use 能力受限 StrictJSON: boolPtr(false), Note: "DeepSeek R1 thinking 模型,tool use 不稳定(2026-04)", }, "openrouter:minimax/minimax-m2.7": { Vision: boolPtr(true), PDF: boolPtr(false), Batch: boolPtr(false), ParallelToolCalls: boolPtr(true), StrictJSON: boolPtr(true), Note: "MiniMax M2.7 经由 OpenRouter(2026-04)", }, } // lookupDocumented 查询静态表返回 documented 能力. // 未命中返回零值(所有 *bool 为 nil),调用方据此填 SourceUntested. func lookupDocumented(providerName, model string) documentedInfo { key := providerName + ":" + model return documentedCapabilities[key] } // boolCap 把 *bool 转为带来源的 Capability-- // nil → SourceUntested,非 nil → SourceDocumented. func boolCap(v *bool, note string) Capability { if v == nil { return Capability{Source: SourceUntested} } return Capability{Value: *v, Source: SourceDocumented, Note: note} }