docs(comments): 注释中文化 · internal/runtime/orchestration(29 文件,纯替换)
- 只翻注释/文档字符串:剥离注释后代码行逐字节不变(机械校验只剩允许的行尾注释形态) - 裁决编号与 design 节号(02.4.3 / 11.4.2 / design/05 §9 等)逐字保留 - 复核:go build 绿;orchestration 及其子包(audit/comm)测试绿;gofmt 干净
This commit is contained in:
1 parent
fe90f64a56
commit
eb1828ee7a
29 files changed
+751
-949
No files matched your search
@@ -7,33 +7,28 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/loop"
|
||||
)
|
||||
|
||||
// This file owns the "派出去的子代理以目标角色身份运行" half of design/22 §8-2: a
|
||||
// sub-agent dispatched with a target persona must answer with that role's
|
||||
// instructions and use that role's memory scope, and a role this process cannot run
|
||||
// must be rejected loudly instead of silently degrading into the default role.
|
||||
// 本文件持有 design/22 §8-2 里「派出去的子代理以目标角色身份运行」那一半:带目标
|
||||
// 角色派发的子代理必须以那个角色的指令作答、使用那个角色的记忆作用域,而本进程跑
|
||||
// 不了的角色必须明确报错,不得静默降级为默认角色。
|
||||
//
|
||||
// The resolution itself stays in the loop (internal/runtime/loop/persona.go): every
|
||||
// role-scoped read — prompt (agent pool), memory namespace, emotion, thinking knobs
|
||||
// — is derived from the session env's PersonaID, one input, so the four can never
|
||||
// disagree. The orchestration layer therefore has exactly two jobs: validate the id,
|
||||
// and stamp it onto the sub-agent's run context. Neither touches the identity lane
|
||||
// (ActorEnv / MemWritable), which is decided structurally by the channel layer and
|
||||
// is never a persona's business (project red line: 身份识别靠元数据).
|
||||
// 解析本身留在循环里(internal/runtime/loop/persona.go):每一处按角色作用域的读取
|
||||
// —— 提示词(agent 池)、记忆命名空间、情绪、思考旋钮 —— 都派生自会话 env 的
|
||||
// PersonaID 这一个输入,因此四者不可能互相矛盾。编排层因此只有两件事要做:校验
|
||||
// id,并把它盖到子代理的运行上下文上。两者都不碰身份车道(ActorEnv / MemWritable),
|
||||
// 那条车道由渠道层从结构上决定,从来不是角色的分内事(项目红线:身份识别靠元数据)。
|
||||
|
||||
// PersonaKnown reports whether personaID is a role this process can run with its
|
||||
// own instructions (Options.PersonaExists). A blank id is trivially known: the
|
||||
// caller is naming no role, which is the pre-existing single-role dispatch. A nil
|
||||
// resolver makes every named role unknown, so a role-naming dispatch fails instead
|
||||
// of quietly running as the default role.
|
||||
// PersonaKnown 报告 personaID 是否为本进程能以自身指令运行的角色
|
||||
// (Options.PersonaExists)。空 id 平凡已知:调用方没有指名任何角色,即既有的单角色
|
||||
// 派发。resolver 为 nil 时所有具名角色都算未知,因此指名角色的派发会失败,而不是
|
||||
// 悄悄按默认角色运行。
|
||||
func (s *Scheduler) PersonaKnown(personaID string) bool {
|
||||
return personaID == "" || (s.personaExists != nil && s.personaExists(personaID))
|
||||
}
|
||||
|
||||
// effectiveRole returns the role to record on the sub-agent as its binding. A
|
||||
// dispatched persona IS the binding (the sub-agent answers as that role), so it fills
|
||||
// a blank RoleID; an explicit RoleID that names no persona is left as the caller set
|
||||
// it. The recorded role is what the progress events and the ws subagent_event frame
|
||||
// report, so the frontend never shows a sub-agent running as yuki with an empty role.
|
||||
// effectiveRole 返回记在子代理上的绑定角色。被派发的 persona 就是绑定本身(子代理
|
||||
// 以该角色身份作答),因此它填补空的 RoleID;指名了不存在的 persona 的显式 RoleID
|
||||
// 则保持调用方所设。记录下来的角色正是进度事件与 ws subagent_event 帧所报告的内容,
|
||||
// 所以前端不会看到「以 yuki 身份运行却角色为空」的子代理。
|
||||
func effectiveRole(spec AgentSpec) string {
|
||||
if spec.RoleID == "" {
|
||||
return spec.PersonaID
|
||||
@@ -41,8 +36,8 @@ func effectiveRole(spec AgentSpec) string {
|
||||
return spec.RoleID
|
||||
}
|
||||
|
||||
// checkPersona rejects a role the process cannot run, wrapping ErrUnknownPersona so
|
||||
// a caller can classify it with errors.Is.
|
||||
// checkPersona 拒绝本进程跑不了的角色,包装 ErrUnknownPersona,使调用方能以
|
||||
// errors.Is 归类。
|
||||
func (s *Scheduler) checkPersona(personaID string) error {
|
||||
if s.PersonaKnown(personaID) {
|
||||
return nil
|
||||
@@ -50,10 +45,9 @@ func (s *Scheduler) checkPersona(personaID string) error {
|
||||
return fmt.Errorf("orchestration: spawn: persona %q: %w", personaID, ErrUnknownPersona)
|
||||
}
|
||||
|
||||
// CheckPersonas validates every spec's target role before a batch is spawned, so one
|
||||
// unknown id rejects the whole dispatch instead of leaving the earlier sub-agents of
|
||||
// the batch running with no result ever reported. The dispatch tool calls it right
|
||||
// after decoding the arguments, where the ids are known but nothing has started yet.
|
||||
// CheckPersonas 在整批派发前校验每个 spec 的目标角色,因此一个未知 id 会拒绝整批
|
||||
// 派发,而不会留下批次里先建好的、结果永远不上报的子代理。派发工具在解码参数后立即
|
||||
// 调用它:那时 id 已知,但什么都还没启动。
|
||||
func (s *Scheduler) CheckPersonas(specs []AgentSpec) error {
|
||||
for _, spec := range specs {
|
||||
if err := s.checkPersona(spec.PersonaID); err != nil {
|
||||
@@ -63,12 +57,10 @@ func (s *Scheduler) CheckPersonas(specs []AgentSpec) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// withPersonaEnv returns ctx with the target role stamped onto the session env, so
|
||||
// the loop resolves that role's prompt and memory scope for every step of the
|
||||
// sub-agent's run. The rest of the env (the identity lane and the memory-write gate)
|
||||
// is copied unchanged — a persona decides how she answers, never what she may touch.
|
||||
// A blank id returns ctx untouched, so a persona-less dispatch keeps inheriting the
|
||||
// spawning turn's env exactly as before.
|
||||
// withPersonaEnv 返回把目标角色盖到会话 env 上的 ctx,使循环为子代理运行的每一步
|
||||
// 解析该角色的提示词与记忆作用域。env 的其余部分(身份车道与记忆写入门)原样拷贝
|
||||
// —— 角色决定她怎么回答,绝不决定她能碰什么。空 id 返回未改动的 ctx,因此无角色
|
||||
// 的派发同之前一样继续继承派发回合的 env。
|
||||
func withPersonaEnv(ctx context.Context, personaID string) context.Context {
|
||||
if personaID == "" {
|
||||
return ctx
|
||||
|
||||
Reference in new issue
Block a user