Files
Cyrene_v2/internal/runtime/loop/turn.go
T
AskaEth 91e8d7a029 docs(runtime): internal/runtime/loop 44 个文件注释改中文(逐行 1:1,代码零字节改动)
主人 2026-10-03 拍板「注释一律中文」;本模块按长期分批协议(一个模块一次派工)执行。
注释行数 1329 → 1329 逐行 1:1(含中文 33 → 1304);行尾注释 5 条一并译。
校验:机械校验(非注释改动行)= 空;独立 Go AST 程序(剥注释复渲)证明 44/44 文件代码全等;
全树 go test ./... 58 包 ok / 0 FAIL;交叉编译绿。
gofmt:capacity_loop_test.go / flow.go 改动前即未格式化,按铁律保留原样未动。
2026-10-03 22:28:21 +08:00

65 lines
2.7 KiB
Go
Raw 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 loop
import (
"context"
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
)
// 本文件拥有循环的 turn 边界:一个用户 turn 落定之处
// (Run 产出了 Result),以及紧随人格的状态 ——
// 情绪与好感度,design/01 §2 —— 在循环之外推进。循环
// 本身保持不感知人格与情绪(design/16 §3.3:引擎
// 生成文本;状态与持久化属于其外围分层),因此它
// 只上报该 turn 并记录钩子回传的情绪标签。
// TurnEnd 向循环的 OnTurnEnd 钩子描述一个已落定的 turn。它携带
// 观察者所需的全部信息,而循环无需知道观察者做什么。
type TurnEnd struct {
// SessionID 是该 turn 所属的会话。
SessionID string
// PersonaID 是该 turn 发言所作为的角色:调用方提供了会话环境
// 解析出的角色时用它,否则用循环配置的默认角色
// (design/22 §4.2)。它使观察者保持人格作用域(design/01 §2):该角色
// 的情绪机与好感度 —— 且仅该角色 —— 推进。
PersonaID string
// UserText 是该 turn 最新的用户消息(该 turn 未携带用户文本时
// 为 "",例如恢复的工具轮)。
UserText string
// AssistantText 是该 turn 最终的 assistant 文本。
AssistantText string
// StopReason 归类该 turn 如何结束。
StopReason string
// Steps 是该 turn 经过的模型步数。
Steps int
// Env 是会话解析出的隔离环境(owner / group /
// stranger),使钩子能让受限会话保持只读。
Env SessionEnv
}
// TurnEndHook 观察一个已落定的 turn 并返回该 turn 的人格情绪标签
// (调用方不追踪情绪时为 "")。它每个落定的 turn 运行一次 —— 而非
// 每个模型步一次 —— 因此多步工具 turn 的效果恰好应用
// 一次。它不得阻塞:它在答案完成后于 Run 路径上运行,
// 其返回值经 Result.Mood 携带至持久化层。
type TurnEndHook func(TurnEnd) string
// settleTurn 把落定的 turn 上报给钩子(已接线时),并把
// 返回的情绪标签记录到结果上,使持久化的 assistant 消息携带
// 该 turn 的情绪(design/16 §3.3)。会话环境经 ctx 传递,
// 因此群聊/陌生人 turn 以受限身份到达钩子。
func (l *Loop) settleTurn(ctx context.Context, sessionID string, msgs []model.Message, res *Result) {
if l.onTurnEnd == nil {
return
}
res.Mood = l.onTurnEnd(TurnEnd{
SessionID: sessionID,
PersonaID: l.personaFor(ctx),
UserText: lastUserText(msgs),
AssistantText: res.Text,
StopReason: res.StopReason,
Steps: res.Steps,
Env: sessionEnvFrom(ctx),
})
}