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
@@ -14,8 +14,8 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
|
||||
)
|
||||
|
||||
// fakeRecent is a recentProvider stub returning a fixed tail/error for the
|
||||
// main-session context read.
|
||||
// fakeRecent 是 recentProvider 的 stub,为
|
||||
// 主会话语境读取返回固定的尾部/错误。
|
||||
type fakeRecent struct {
|
||||
msgs []history.Message
|
||||
err error
|
||||
@@ -25,8 +25,8 @@ func (f *fakeRecent) Recent(context.Context, string, int) ([]history.Message, er
|
||||
return f.msgs, f.err
|
||||
}
|
||||
|
||||
// captureAdapter is a model.Adapter that records every request it is handed so a
|
||||
// test can assert on the messages the loop actually fed to the model.
|
||||
// captureAdapter 是一个 model.Adapter,记录交给它的每个请求,好让
|
||||
// 测试能对 loop 实际喂给模型的消息做断言。
|
||||
type captureAdapter struct {
|
||||
reqs []model.Request
|
||||
}
|
||||
@@ -42,9 +42,9 @@ func (c *captureAdapter) ChatStream(_ context.Context, req model.Request, _ func
|
||||
return c.Chat(context.Background(), req, model.Options{})
|
||||
}
|
||||
|
||||
// newThinkLoop builds a real loop over ad with a working manual memory-extraction
|
||||
// path so a test can prove the owner environment is in effect (extractMemory runs
|
||||
// only when MemWritable=true).
|
||||
// newThinkLoop 在 ad 之上构建一个真实 loop,并带一条可用的手动记忆抽取
|
||||
// 路径,好让测试能证明 owner 环境确实生效(extractMemory 只在
|
||||
// MemWritable=true 时运行)。
|
||||
func newThinkLoop(t *testing.T, ad model.Adapter) (*loop.Loop, *memory.Store) {
|
||||
t.Helper()
|
||||
a, err := agent.New("You are Cyrene.", nil, nil, agent.WithModel(ad, nil))
|
||||
@@ -61,7 +61,7 @@ func newThinkLoop(t *testing.T, ad model.Adapter) (*loop.Loop, *memory.Store) {
|
||||
return l, store
|
||||
}
|
||||
|
||||
// newMemoryStore opens an isolated in-memory memory store for one test.
|
||||
// newMemoryStore 为单个测试打开一个隔离的内存记忆存储。
|
||||
func newMemoryStore(t *testing.T) *memory.Store {
|
||||
t.Helper()
|
||||
d, err := db.Open(context.Background(), ":memory:", nil)
|
||||
@@ -76,7 +76,7 @@ func newMemoryStore(t *testing.T) *memory.Store {
|
||||
return s
|
||||
}
|
||||
|
||||
// modelText returns the concatenated text of a model message's text parts.
|
||||
// modelText 返回一条 model 消息各文本片段拼接后的文本。
|
||||
func modelText(m model.Message) string {
|
||||
var b strings.Builder
|
||||
for _, c := range m.Content {
|
||||
@@ -87,9 +87,9 @@ func modelText(m model.Message) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// TestGuidancePrompt_EncouragesProactiveWithoutSuppression guards the rewrite:
|
||||
// the guidance must drop the old suppression phrases and push warm, targeted
|
||||
// proactive expression (design/20 §2).
|
||||
// TestGuidancePrompt_EncouragesProactiveWithoutSuppression 守护这次改写:
|
||||
// 引导必须去掉旧的抑制措辞,并推动温暖、有针对性的
|
||||
// 主动表达(design/20 §2)。
|
||||
func TestGuidancePrompt_EncouragesProactiveWithoutSuppression(t *testing.T) {
|
||||
t.Parallel()
|
||||
p := guidancePrompt("heartbeat")
|
||||
@@ -105,8 +105,8 @@ func TestGuidancePrompt_EncouragesProactiveWithoutSuppression(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMainContext_MapsRecentMessages proves the recent main-session tail is
|
||||
// converted in order with roles mapped and image parts preserved.
|
||||
// TestMainContext_MapsRecentMessages 证明主会话最近尾部被
|
||||
// 按序转换、角色被映射、图片片段被保留。
|
||||
func TestMainContext_MapsRecentMessages(t *testing.T) {
|
||||
t.Parallel()
|
||||
prov := &fakeRecent{msgs: []history.Message{
|
||||
@@ -129,8 +129,8 @@ func TestMainContext_MapsRecentMessages(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMainContext_Degrades ensures a nil provider or a failed read yields a nil
|
||||
// tail so the think runs on the guidance prompt alone rather than failing.
|
||||
// TestMainContext_Degrades 确保提供者为 nil 或读取失败都得到 nil
|
||||
// 尾部,因此该次思考仅凭引导提示词运行,而不是失败。
|
||||
func TestMainContext_Degrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := mainContext(context.Background(), nil); got != nil {
|
||||
@@ -141,8 +141,8 @@ func TestMainContext_Degrades(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestThinkInput_AppendsGuidanceLast verifies the assembled input is the recent
|
||||
// context followed by a single guidance turn.
|
||||
// TestThinkInput_AppendsGuidanceLast 验证拼装出的输入是最近
|
||||
// 语境后跟单个引导回合。
|
||||
func TestThinkInput_AppendsGuidanceLast(t *testing.T) {
|
||||
t.Parallel()
|
||||
in := thinkInput([]model.Message{model.TextMessage(model.RoleUser, "hi")}, "heartbeat")
|
||||
@@ -154,10 +154,10 @@ func TestThinkInput_AppendsGuidanceLast(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestLoopThinker_Think_UsesMainContextAndOwnerEnv drives a real think and asserts
|
||||
// three things from design/20 P1: the model saw the main-session recent message,
|
||||
// the guidance prompt carries no suppression, and the think ran under the owner
|
||||
// environment (the manual extractor persists only when MemWritable=true).
|
||||
// TestLoopThinker_Think_UsesMainContextAndOwnerEnv 驱动一次真实思考并
|
||||
// 断言 design/20 P1 的三件事:模型看到了主会话的最近消息、
|
||||
// 引导提示词不携带抑制措辞,且该次思考跑在 owner
|
||||
// 环境之下(手动抽取器只在 MemWritable=true 时持久化)。
|
||||
func TestLoopThinker_Think_UsesMainContextAndOwnerEnv(t *testing.T) {
|
||||
ad := &captureAdapter{}
|
||||
l, store := newThinkLoop(t, ad)
|
||||
@@ -194,7 +194,7 @@ func TestLoopThinker_Think_UsesMainContextAndOwnerEnv(t *testing.T) {
|
||||
t.Fatalf("input missing the guidance prompt: %+v", last.Messages)
|
||||
}
|
||||
|
||||
// Owner env proved: ManualExtractor only persists under MemWritable=true.
|
||||
// 已证明 owner 环境:ManualExtractor 只在 MemWritable=true 时持久化。
|
||||
items, err := store.ListByPersona(context.Background(), "persona-a")
|
||||
if err != nil {
|
||||
t.Fatalf("ListByPersona: %v", err)
|
||||
@@ -207,8 +207,8 @@ func TestLoopThinker_Think_UsesMainContextAndOwnerEnv(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestLoopThinker_NilHistoryDegrades keeps the pre-existing backpressure: with no
|
||||
// history provider the think still runs (guidance prompt only) and never panics.
|
||||
// TestLoopThinker_NilHistoryDegrades 保持既有的背压行为:没有
|
||||
// 历史提供者时该次思考仍会运行(只用引导提示词)且绝不 panic。
|
||||
func TestLoopThinker_NilHistoryDegrades(t *testing.T) {
|
||||
ad := &captureAdapter{}
|
||||
l, _ := newThinkLoop(t, ad)
|
||||
@@ -221,9 +221,9 @@ func TestLoopThinker_NilHistoryDegrades(t *testing.T) {
|
||||
t.Fatal("no model request captured")
|
||||
}
|
||||
last := ad.reqs[len(ad.reqs)-1]
|
||||
// With no history provider the input carries the guidance prompt and no
|
||||
// main-session messages. (The agent prepends its own instruction system message,
|
||||
// so we assert presence rather than an exact count.)
|
||||
// 没有历史提供者时,输入携带引导提示词、不含
|
||||
// 主会话消息。(agent 会自行前置一条指令系统消息,
|
||||
// 所以我们断言存在性而非精确条数。)
|
||||
foundGuidance := false
|
||||
for _, m := range last.Messages {
|
||||
if strings.Contains(modelText(m), guidancePrompt("heartbeat")) {
|
||||
|
||||
Reference in new issue
Block a user