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

+38 -38
View File
@@ -14,25 +14,25 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/config"
)
// Wire constraints for the OpenAI-compatible /chat/completions protocol.
// OpenAI 兼容 /chat/completions 协议的线格式约束。
const (
// sseDataPrefix marks an SSE event line carrying a JSON payload.
// sseDataPrefix 标记携带 JSON 负载的 SSE 事件行。
sseDataPrefix = "data: "
// sseDone is the terminal SSE sentinel.
// sseDone 是终止用的 SSE 哨兵。
sseDone = "[DONE]"
// sseBufInit is the initial bufio.Scanner read buffer size.
// sseBufInit 是 bufio.Scanner 的初始读缓冲大小。
sseBufInit = 64 * 1024
// maxSSELineBytes caps a single SSE event line.
// maxSSELineBytes 限制单条 SSE 事件行的长度。
maxSSELineBytes = 1024 * 1024
// errBodyCap bounds how much of an error body is read for the message.
// errBodyCap 限制为取出消息而读取的错误响应体大小。
errBodyCap = 512
// defaultHTTPTimeout bounds a single provider call when Options.Timeout is 0.
// defaultHTTPTimeout 在 Options.Timeout 为 0 时约束单次提供商调用。
defaultHTTPTimeout = 180 * time.Second
)
// OpenAIChatAdapter calls an OpenAI-compatible /chat/completions endpoint. It is
// constructed from a config.LLMConfig and implements Adapter for both
// non-streaming and token-level SSE streaming.
// OpenAIChatAdapter 调用 OpenAI 兼容的 /chat/completions 端点。它由
// config.LLMConfig 构建,同时实现非流式与 token 级 SSE 流式的
// Adapter。
type OpenAIChatAdapter struct {
name string
baseURL string
@@ -40,39 +40,39 @@ type OpenAIChatAdapter struct {
model string
client *http.Client
recorder Recorder
// reasoningKind is this endpoint's configured reasoning-switch shape
// (models.json group reasoning.kind / LLM_REASONING_KIND, 裁决 03.4.2/08.4.1).
// Empty means "auto": infer the vendor from the model name/base URL and send
// nothing when the shape is ambiguous.
// reasoningKind 是本端点已配置的推理开关形状
// (models.json 组的 reasoning.kind / LLM_REASONING_KIND,裁决 03.4.2/08.4.1)。
// 为空表示 "auto":按模型名/base URL 推断厂商,
// 形状含糊时什么都不发。
reasoningKind string
// log reports reasoning_effort validation and ignored thinking directives. It
// is never nil: a discard logger tagged with this adapter's source is
// installed when the caller supplies none, so a decision is always traceable.
// log 上报 reasoning_effort 校验与被忽略的思考指令。它
// 永不为 nil:调用方未提供时,会装入一个带有本适配器来源
// 标记的丢弃式日志器,因此每个决定都可追溯。
log *slog.Logger
}
// OpenAIOption configures an OpenAIChatAdapter.
// OpenAIOption 用于配置 OpenAIChatAdapter。
type OpenAIOption func(*OpenAIChatAdapter)
// WithHTTPClient overrides the default HTTP client (used to inject mocks or a
// tuned transport in tests and production).
// WithHTTPClient 覆盖默认 HTTP 客户端(用于在测试与生产中
// 注入 mock 或调优过的 transport)。
func WithHTTPClient(c *http.Client) OpenAIOption {
return func(a *OpenAIChatAdapter) { a.client = c }
}
// WithRecorder wires a per-call Recorder for CallRecord accounting.
// WithRecorder 装入按调用计账的 Recorder,用于 CallRecord 统计。
func WithRecorder(r Recorder) OpenAIOption {
return func(a *OpenAIChatAdapter) { a.recorder = r }
}
// WithModel overrides the adapter's default model name.
// WithModel 覆盖适配器的默认模型名。
func WithModel(m string) OpenAIOption {
return func(a *OpenAIChatAdapter) { a.model = m }
}
// WithOpenAILogger attaches the logger used to report reasoning_effort
// validation and ignored thinking directives. A nil logger is ignored so the
// discard default stays in place.
// WithOpenAILogger 挂上用于上报 reasoning_effort 校验与
// 被忽略思考指令的日志器。nil 日志器会被忽略,
// 从而保留丢弃式的默认值。
func WithOpenAILogger(l *slog.Logger) OpenAIOption {
return func(a *OpenAIChatAdapter) {
if l != nil {
@@ -81,12 +81,12 @@ func WithOpenAILogger(l *slog.Logger) OpenAIOption {
}
}
// NewOpenAIChat builds an adapter from a supplier config. baseURL is trimmed of
// any trailing slash before the /chat/completions path is appended. The
// endpoint's configured reasoning shape (cfg.ReasoningKind) travels with the
// adapter so every chain built from the same config — the group's chain, its
// per-persona chain and the local rung — resolves its reasoning switches the
// same way.
// NewOpenAIChat 由供应商配置构建适配器。baseURL 会先去掉
// 末尾斜杠,再拼接 /chat/completions 路径。
// 端点已配置的推理形状(cfg.ReasoningKind)随
// 适配器一起走,因此由同一份配置构建的每条链——组链、
// 它的按角色链以及本地级——都以
// 相同方式解出自己的推理开关。
func NewOpenAIChat(cfg config.LLMConfig, opts ...OpenAIOption) *OpenAIChatAdapter {
a := &OpenAIChatAdapter{
name: "openai",
@@ -106,10 +106,10 @@ func NewOpenAIChat(cfg config.LLMConfig, opts ...OpenAIOption) *OpenAIChatAdapte
return a
}
// Name returns the adapter identifier.
// Name 返回适配器标识。
func (a *OpenAIChatAdapter) Name() string { return a.name }
// Chat performs a non-streaming completion.
// Chat 执行一次非流式补全。
func (a *OpenAIChatAdapter) Chat(ctx context.Context, req Request, opts Options) (Response, error) {
start := time.Now()
if a.baseURL == "" {
@@ -147,8 +147,8 @@ func (a *OpenAIChatAdapter) Chat(ctx context.Context, req Request, opts Options)
return out, nil
}
// ChatStream streams structured events via onEvent and returns the aggregated
// response with usage when the provider reports it in the final chunk.
// ChatStream 通过 onEvent 流出结构化事件,并在提供商于
// 末块上报用量时返回带用量的聚合响应。
func (a *OpenAIChatAdapter) ChatStream(ctx context.Context, req Request, onEvent func(StreamEvent)) (Response, error) {
start := time.Now()
if a.baseURL == "" {
@@ -184,7 +184,7 @@ func (a *OpenAIChatAdapter) ChatStream(ctx context.Context, req Request, onEvent
return out, nil
}
// withCallTimeout wraps ctx with opts.Timeout when it is positive.
// withCallTimeout 在 opts.Timeout 为正时用该超时包裹 ctx。
func withCallTimeout(parent context.Context, opts Options) (context.Context, context.CancelFunc) {
if opts.Timeout > 0 {
return context.WithTimeout(parent, opts.Timeout)
@@ -192,7 +192,7 @@ func withCallTimeout(parent context.Context, opts Options) (context.Context, con
return parent, func() {}
}
// resolveModel returns the effective model name.
// resolveModel 返回实际生效的模型名。
func (a *OpenAIChatAdapter) resolveModel(req Request) (string, error) {
if req.Model != "" {
return req.Model, nil
@@ -203,7 +203,7 @@ func (a *OpenAIChatAdapter) resolveModel(req Request) (string, error) {
return "", ErrNoModel
}
// endpoint returns the full /chat/completions URL.
// endpoint 返回完整的 /chat/completions URL。
func (a *OpenAIChatAdapter) endpoint() string {
return a.baseURL + "/chat/completions"
}