docs(comments): 注释中文化 · internal/runtime/model + internal/services/backthink(54 文件,纯替换)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 只翻注释/文档字符串:`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:
AskaEth committed 2026-10-04 16:27:54 +08:00
1 parent f5cf117482
commit 3dc1232bc2
54 files changed
+1923 -1923

No files matched your search

+32 -32
View File
@@ -5,27 +5,27 @@ import (
"strings"
)
// Anthropic extended-thinking protocol bounds (design/04 §3.2).
// Anthropic 扩展思考协议的边界(design/04 §3.2)。
const (
// anthropicMinThinkingBudget is the smallest budget_tokens the Messages API
// accepts for thinking.type=enabled; anything below it is rejected with a
// 400, so a lower non-zero budget is raised and reported rather than sent.
// anthropicMinThinkingBudget 是 Messages API 在 thinking.type=enabled 时
// 接受的最小 budget_tokens;低于它会被 400 拒绝,
// 因此更低但非零的预算会被抬高并上报,而不是照发。
anthropicMinThinkingBudget = 1024
// anthropicDefaultThinkingBudget is used when thinking is switched on without
// an explicit budget.
// anthropicDefaultThinkingBudget 在开启思考但未给
// 显式预算时使用。
anthropicDefaultThinkingBudget = 4096
// anthropicThinkingBodyReserve is the body room kept on top of the thinking
// budget: max_tokens is shared by thinking and the visible answer, so the
// budget must never be allowed to consume it all (design/04 §3.2 red line:
// anthropicThinkingBodyReserve 是在思考预算之上留给正文的空间:
// max_tokens 由思考与可见答案共享,所以
// 预算绝不允许把它全部吃光(design/04 §3.2 红线:
// "预算与正文不得互相吃光").
anthropicThinkingBodyReserve = 2048
)
// deepSeekAnthropicEndpoint reports whether an Anthropic-protocol request is
// really served by DeepSeek's /anthropic endpoint. The base URL is checked first
// because the endpoint — not the model name — decides whether budget_tokens is
// honoured, and a DeepSeek endpoint is commonly configured with a non-DeepSeek
// model name (the service silently maps unknown names onto deepseek-flash).
// deepSeekAnthropicEndpoint 报告一次 Anthropic 协议请求是否
// 真的由 DeepSeek 的 /anthropic 端点服务。先检查 base URL,
// 因为是端点——而不是模型名——决定 budget_tokens 是否
// 被尊重,而 DeepSeek 端点常常配着一个非 DeepSeek 的
// 模型名(该服务会把未知名称静默映射到 deepseek-flash)。
func deepSeekAnthropicEndpoint(model, baseURL string) bool {
if strings.Contains(strings.ToLower(baseURL), "deepseek") {
return true
@@ -33,16 +33,16 @@ func deepSeekAnthropicEndpoint(model, baseURL string) bool {
return reasoningVendorFor(model, baseURL) == vendorDeepSeek
}
// anthropicThinkingFor resolves the extended-thinking directive together with the
// max_tokens it requires. It returns the (possibly raised) max_tokens and the
// wire block; a nil block means "do not send thinking" (no directive, or an
// explicit off). Because max_tokens is shared by thinking and the visible answer,
// the returned budget always leaves anthropicThinkingBodyReserve for the body,
// and a request whose budget would eat the answer raises max_tokens instead — the
// adjustment is logged so it is never a silent rewrite.
// anthropicThinkingFor 解出扩展思考指令以及它所需的
// max_tokens。它返回(可能已被抬高的)max_tokens 与
// 线格式块;块为 nil 表示「不发送思考」(无指令,或
// 显式关闭)。由于 max_tokens 由思考与可见答案共享,
// 返回的预算总会为正文留下 anthropicThinkingBodyReserve,
// 而预算会吃光答案的请求则改为抬高 max_tokens——该
// 调整会被记录,因此绝不是一次静默改写。
//
// This is the Anthropic endpoint's rule only. A DeepSeek /anthropic endpoint
// ignores budget_tokens, so it must not go through here (design/04 §3.2 fact 6).
// 这条规则只适用于 Anthropic 端点。DeepSeek 的 /anthropic 端点
// 会忽略 budget_tokens,所以它绝不能走这里(design/04 §3.2 事实 6)。
func anthropicThinkingFor(th *Thinking, maxTokens int, log *slog.Logger) (int, *anthropicThinking) {
if th == nil || (th.Enable != nil && !*th.Enable) {
return maxTokens, nil
@@ -67,12 +67,12 @@ func anthropicThinkingFor(th *Thinking, maxTokens int, log *slog.Logger) (int, *
return maxTokens, &anthropicThinking{Type: anthropicThinkingTypeEnabled, BudgetTokens: budget}
}
// anthropicDeepSeekReasoning resolves the reasoning knobs for a DeepSeek
// /anthropic request. Two differences from the Anthropic endpoint drive it: that
// endpoint ignores budget_tokens, so max_tokens is left untouched (raising it
// would misreport the budget the provider actually applies), and strength is
// controlled by output_config.effort, which has no "none" value — there the "off"
// intent is carried by the thinking switch itself (design/04 §3.2 facts 2 and 6).
// anthropicDeepSeekReasoning 解出 DeepSeek /anthropic 请求的
// 推理旋钮。与 Anthropic 端点的两点差异决定了它:该
// 端点忽略 budget_tokens,所以 max_tokens 保持不动(抬高它
// 会错误反映提供商实际采用的预算),而强度由
// output_config.effort 控制,它没有 "none" 取值——在那里「关闭」
// 意图由 thinking 开关自身承载(design/04 §3.2 事实 2 与 6)。
func anthropicDeepSeekReasoning(log *slog.Logger, model string, th *Thinking, effort string) (*anthropicThinking, *anthropicOutputConfig) {
var block *anthropicThinking
if th != nil {
@@ -118,9 +118,9 @@ func anthropicDeepSeekReasoning(log *slog.Logger, model string, th *Thinking, ef
return block, &anthropicOutputConfig{Effort: tier}
}
// anthropicThinkingOn reports the effective thinking state of a resolved DeepSeek
// /anthropic request: an omitted switch leaves the provider default in place, and
// DeepSeek's default is enabled.
// anthropicThinkingOn 报告一个已解出的 DeepSeek /anthropic 请求的
// 实际思考状态:省略开关会保留提供商默认值,而
// DeepSeek 的默认是开启。
func anthropicThinkingOn(th *anthropicThinking) bool {
return th == nil || th.Type != thinkingTypeDisabled
}