docs(comments): 注释中文化 · internal/runtime/model + internal/services/backthink(54 文件,纯替换)
- 只翻注释/文档字符串:`go/scanner` 剥注释后按 token 序列+literal 逐 token 比对,**54/54 文件 SAME**;
改动文件总行数与 HEAD 漂移 = 0(严格 1:1,无合并/拆行)
- 裁决编号与 design 节号逐字保留(03.4.1/03.4.2/03.4.3/14.4.1/14.4.5/07.4.2-4、design/04 §3.1/§3.2 等);
`chat_template_kwargs` / `enable_thinking` / `reasoning_effort` / `thinking:{type}` 字段名与形状说明未动
- 存疑译法(已登记):`persona` 在叙事语境用「角色」、标识符语境保留 `persona`(仓库既有模块本身混用);
`rung`→「级」;`provider` 存在「提供商/提供者」两种落笔(可按需一键统一)
- 复核:build/vet 绿 + 两包测试绿;gofmt 干净;残留英文注释 0 条
- 既有存量(未修,只报告):`model/anthropic_test.go` 612 行 >500;`applyAnthropicEvent` 115 行 >80
This commit is contained in:
1 parent
f5cf117482
commit
3dc1232bc2
54 files changed
+1923
-1923
No files matched your search
@@ -9,21 +9,21 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/config"
|
||||
)
|
||||
|
||||
// newDeepSeekAdapter builds an OpenAI-compatible adapter pointed at a stub server
|
||||
// but classified as DeepSeek by its model name, so the DeepSeek mapping is
|
||||
// exercised against the real request body.
|
||||
// newDeepSeekAdapter 构建一个 OpenAI 兼容适配器,指向 stub 服务器
|
||||
// 但按其模型名归类为 DeepSeek,从而让 DeepSeek 映射
|
||||
// 针对真实请求体被验证。
|
||||
func newDeepSeekAdapter(t *testing.T, ch chan<- capturedRequest, opts ...OpenAIOption) *OpenAIChatAdapter {
|
||||
t.Helper()
|
||||
srv := newCompletionServer(t, http.StatusOK, "application/json", okCompletion, ch)
|
||||
return NewOpenAIChat(config.LLMConfig{BaseURL: srv.URL, Model: deepSeekModel}, opts...)
|
||||
}
|
||||
|
||||
// deepSeekModel is the current DeepSeek model name (the old deepseek-chat /
|
||||
// deepseek-reasoner names were discontinued on 2026-07-24).
|
||||
// deepSeekModel 是当前的 DeepSeek 模型名(旧的 deepseek-chat /
|
||||
// deepseek-reasoner 名称已于 2026-07-24 停用)。
|
||||
const deepSeekModel = "deepseek-flash"
|
||||
|
||||
// deepSeekThinkingType reads body.thinking.type, reporting whether the switch was
|
||||
// sent at all.
|
||||
// deepSeekThinkingType 读取 body.thinking.type,报告该开关是否
|
||||
// 被发出。
|
||||
func deepSeekThinkingType(body map[string]any) (string, bool) {
|
||||
block, ok := body["thinking"].(map[string]any)
|
||||
if !ok {
|
||||
@@ -33,12 +33,12 @@ func deepSeekThinkingType(body map[string]any) (string, bool) {
|
||||
return value, true
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekReasoningEffortMatrix pins the official value set end to
|
||||
// end at the request body: none/low/high/max pass through untouched and the four
|
||||
// compatibility aliases are normalized to the tier DeepSeek applies
|
||||
// (minimal→low, medium/xhigh→high, ultra→max). The old behavior — grading "none"
|
||||
// down to "low" — turned thinking off into thinking on, so "none" must arrive as
|
||||
// "none".
|
||||
// TestOpenAIChat_DeepSeekReasoningEffortMatrix 钉住官方取值集合,端到
|
||||
// 端落到请求体上:none/low/high/max 原样通过,四个
|
||||
// 兼容别名被归一化为 DeepSeek 采用的档位
|
||||
// (minimal→low、medium/xhigh→high、ultra→max)。旧行为——把 "none"
|
||||
// 降级到 "low"——把关闭思考变成了开启思考,所以 "none" 必须
|
||||
// 以 "none" 到达。
|
||||
func TestOpenAIChat_DeepSeekReasoningEffortMatrix(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := []struct{ sent, want string }{
|
||||
@@ -74,9 +74,9 @@ func TestOpenAIChat_DeepSeekReasoningEffortMatrix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekReasoningEffortInvalidDropped asserts an unrecognized
|
||||
// value is dropped and reported — never replaced by a nearby tier, which is how
|
||||
// the original "round down" logic inverted the caller's intent.
|
||||
// TestOpenAIChat_DeepSeekReasoningEffortInvalidDropped 断言无法识别的
|
||||
// 取值会被丢弃并上报——绝不会被替换成邻近档位,正是那套
|
||||
// 「向下取整」逻辑颠倒了调用方的意图。
|
||||
func TestOpenAIChat_DeepSeekReasoningEffortInvalidDropped(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := make(chan capturedRequest, 1)
|
||||
@@ -105,10 +105,10 @@ func TestOpenAIChat_DeepSeekReasoningEffortInvalidDropped(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekThinkingSwitch asserts the DeepSeek thinking switch is
|
||||
// really sent: an explicit off must reach the wire (DeepSeek defaults to enabled,
|
||||
// so staying silent would leave thinking ON), and nil must not be turned into
|
||||
// either value.
|
||||
// TestOpenAIChat_DeepSeekThinkingSwitch 断言 DeepSeek 思考开关
|
||||
// 真的被发出:显式关闭必须到达线上(DeepSeek 默认开启,
|
||||
// 所以保持沉默会让思考保持开启),而 nil 不得被变成
|
||||
// 任何一个取值。
|
||||
func TestOpenAIChat_DeepSeekThinkingSwitch(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := []struct {
|
||||
@@ -147,9 +147,9 @@ func TestOpenAIChat_DeepSeekThinkingSwitch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekEffortNoneAloneKeepsTheOfficialOffSwitch asserts the
|
||||
// official reasoning_effort "none" path is used verbatim when no thinking switch
|
||||
// was requested — that is the documented way to close thinking.
|
||||
// TestOpenAIChat_DeepSeekEffortNoneAloneKeepsTheOfficialOffSwitch 断言在未
|
||||
// 请求 thinking 开关时,官方 reasoning_effort "none" 路径被原样
|
||||
// 使用——那是关闭思考的记录在案的做法。
|
||||
func TestOpenAIChat_DeepSeekEffortNoneAloneKeepsTheOfficialOffSwitch(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := make(chan capturedRequest, 1)
|
||||
@@ -171,9 +171,9 @@ func TestOpenAIChat_DeepSeekEffortNoneAloneKeepsTheOfficialOffSwitch(t *testing.
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekThinkingOffBeatsEffort is the conflict rule documented in
|
||||
// resolveOpenAIReasoning: the provider states no precedence, so the off side wins
|
||||
// and the dropped tier is reported — never silently applied.
|
||||
// TestOpenAIChat_DeepSeekThinkingOffBeatsEffort 是 resolveOpenAIReasoning 里
|
||||
// 记录的冲突规则:提供商未说明优先级,所以关闭一侧获胜,
|
||||
// 被丢弃的档位会被上报——绝不静默套用。
|
||||
func TestOpenAIChat_DeepSeekThinkingOffBeatsEffort(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := make(chan capturedRequest, 1)
|
||||
@@ -200,9 +200,9 @@ func TestOpenAIChat_DeepSeekThinkingOffBeatsEffort(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekEffortNoneBeatsThinkingEnabled covers the opposite
|
||||
// conflict: reasoning_effort "none" and thinking enabled cannot both be honoured,
|
||||
// so the off side wins and the request carries exactly one switch.
|
||||
// TestOpenAIChat_DeepSeekEffortNoneBeatsThinkingEnabled 覆盖相反的
|
||||
// 冲突:reasoning_effort "none" 与 thinking 开启无法同时被
|
||||
// 尊重,所以关闭一侧获胜,请求只携带一个开关。
|
||||
func TestOpenAIChat_DeepSeekEffortNoneBeatsThinkingEnabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := make(chan capturedRequest, 1)
|
||||
@@ -229,9 +229,9 @@ func TestOpenAIChat_DeepSeekEffortNoneBeatsThinkingEnabled(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekThinkingBudgetReportedIgnored asserts a token budget
|
||||
// (an Anthropic-style directive) is reported as unmappable on the DeepSeek
|
||||
// chat-completions endpoint instead of opening or closing the switch by guess.
|
||||
// TestOpenAIChat_DeepSeekThinkingBudgetReportedIgnored 断言 token 预算
|
||||
// (Anthropic 风格的指令)在 DeepSeek chat-completions 端点上
|
||||
// 会被上报为无法映射,而不是靠猜去开或关开关。
|
||||
func TestOpenAIChat_DeepSeekThinkingBudgetReportedIgnored(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := make(chan capturedRequest, 1)
|
||||
@@ -257,10 +257,10 @@ func TestOpenAIChat_DeepSeekThinkingBudgetReportedIgnored(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestOpenAIChat_DeepSeekForcedToolChoiceWithThinkingWarns covers the DeepSeek
|
||||
// 400 trap: a forcing tool_choice while thinking is on is rejected, and thinking
|
||||
// is on by default. The adapter only warns — it must never close thinking by
|
||||
// itself.
|
||||
// TestOpenAIChat_DeepSeekForcedToolChoiceWithThinkingWarns 覆盖 DeepSeek
|
||||
// 400 陷阱:思考开启时强制型 tool_choice 会被拒绝,而思考
|
||||
// 默认就是开启。适配器只警告——它绝不能自行
|
||||
// 关闭思考。
|
||||
func TestOpenAIChat_DeepSeekForcedToolChoiceWithThinkingWarns(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := []struct {
|
||||
|
||||
Reference in new issue
Block a user