Files
AskaEth 3dc1232bc2
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
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
2026-10-04 16:27:54 +08:00

70 lines
2.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package model
import (
"context"
"fmt"
"net/http"
"strings"
"testing"
"git.yeij.top/AskaEth/Cyrene_v2/internal/config"
)
// TestAnthropicChat_Chat_DefaultMaxTokensLargeEnoughForThinking 守护思考
// 模型的修复:其推理与可见答案共享 max_tokens 预算时,
// 零值默认必须给两者都留出空间。它还断言显式的
// Request.MaxTokens 绝不会被该默认覆盖
// (anthropic_test.go 里既有的 64-token 用例就是兼容性证明)。
func TestAnthropicChat_Chat_DefaultMaxTokensLargeEnoughForThinking(t *testing.T) {
t.Parallel()
ch := make(chan anthropicCaptured, 1)
srv := newAnthropicServer(t, http.StatusOK, "application/json", anthropicTextResponse, ch)
ad := NewAnthropicChat(config.LLMConfig{AnthropicBaseURL: srv.URL, AnthropicModel: "claude-test"})
if _, err := ad.Chat(context.Background(),
Request{Messages: []Message{TextMessage(RoleUser, "hi")}}, Options{}); err != nil {
t.Fatalf("Chat error: %v", err)
}
if got := (<-ch).body["max_tokens"]; got != float64(anthropicDefaultMaxTokens) {
t.Errorf("default body.max_tokens = %v, want %d", got, anthropicDefaultMaxTokens)
}
if anthropicDefaultMaxTokens < 4096 {
t.Errorf("anthropicDefaultMaxTokens = %d, too small for a long thinking turn plus its answer", anthropicDefaultMaxTokens)
}
}
// TestAnthropicChat_Chat_LongThinkingThenShortText 断言思考块
// 远长于文本块的响应仍会浮出文本,且
// 绝不把思考泄漏进 Content(思考不是答案的
// 红线)。这就是预算足够大时思考模型产出的形状,
// 与旧 1024 上限造成的截断形成对照。
func TestAnthropicChat_Chat_LongThinkingThenShortText(t *testing.T) {
t.Parallel()
thinking := strings.Repeat("推理", 1500) // 3000 runes, far longer than the answer
body := fmt.Sprintf(`{
"id":"msg_think","model":"claude-test",
"content":[
{"type":"thinking","thinking":%q},
{"type":"text","text":"现在是下午三点。"}
],
"usage":{"input_tokens":20,"output_tokens":900}
}`, thinking)
srv := newAnthropicServer(t, http.StatusOK, "application/json", body, nil)
ad := NewAnthropicChat(config.LLMConfig{AnthropicBaseURL: srv.URL, AnthropicModel: "claude-test"})
out, err := ad.Chat(context.Background(),
Request{Messages: []Message{TextMessage(RoleUser, "几点了?")}}, Options{})
if err != nil {
t.Fatalf("Chat error: %v", err)
}
if out.Content != "现在是下午三点。" {
t.Errorf("Content = %q, want the text block", out.Content)
}
if strings.Contains(out.Content, "推理") {
t.Errorf("Content leaked thinking: %q", out.Content)
}
if out.Message.Role != RoleAssistant || len(out.Message.Content) != 1 || out.Message.Content[0].Text != "现在是下午三点。" {
t.Errorf("Message = %+v, want a single assistant text part", out.Message)
}
}