feat(orchestration,runtime): subagent_spawn 支持指定目标角色(以该角色 instructions + 记忆域运行)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

design/22 §8-2(主人 2026-10-03 拍板):跨角色协作 = 把其他角色以子代理形式派出去,
该子代理以目标角色的 instructions 运行、并按目标角色的记忆作用域读写。

- AgentSpec / SubAgent / SubAgentResult 新增 PersonaID;Options.PersonaExists 作角色解析器
- scheduler:派发前校验角色(ErrUnknownPersona),批量 all-or-nothing;
  run ctx 经 withPersonaEnv 只覆盖 SessionEnv.PersonaID —— ActorEnv/MemWritable 原样复制
  (身份识别靠 channel 元数据,persona 决定她怎么答、不决定她能碰什么:项目红线)
- 记忆归属键改为 PersonaID 优先(回落 RoleID)→ 替班者写的是目标角色的记忆域
- spawntool:schema 顶层与 tasks[] 新增可选 persona;省略 = 与旧行为逐字节一致
- 分支根节点新增 props.persona(可观测性);SinkMemory 移入 memory.go(守 500 行红线)
- 组合根:personaExists(agent 池);cmd/cyrene/wire.go +5 行

契约:Docs/api-client.md -> v0.47(graph_update 新增可选 props.persona,纯增量)

验证:go build/vet ./... 绿;internal/runtime/orchestration + cmd/cyrene 测试绿;
      go test -race ./internal/runtime/orchestration -run Persona 绿;
      linux/amd64 + darwin/arm64 交叉编译绿
变异验证:① 目标角色换回父/默认角色(3 处断言 FAIL)② 关调度器侧角色校验 ③ 关工具侧预检
This commit is contained in:
AskaEth committed 2026-10-03 21:30:45 +08:00
1 parent c7ecc3a249
commit 05d34853f0
14 files changed
+857 -36

No files matched your search

+10 -4
View File
@@ -11,10 +11,10 @@ import (
)
// SubAgent is a single spawned sub-agent instance. The identity fields (ID, Goal,
// RoleID, Mode, AttachInfo, ParentSession, Data, Context, WorkingMemory) are set
// once at Spawn and never mutated. The lifecycle fields (Status, Summary, Result,
// Err) are written by the sub-agent's background goroutine and read through the
// synchronized accessors below, so reading them before the sub-agent finishes is
// RoleID, PersonaID, Mode, AttachInfo, ParentSession, Data, Context, WorkingMemory)
// are set once at Spawn and never mutated. The lifecycle fields (Status, Summary,
// Result, Err) are written by the sub-agent's background goroutine and read through
// the synchronized accessors below, so reading them before the sub-agent finishes is
// safe. A sub-agent is terminal exactly once its Done reports true; Join returns
// once every sub-agent is terminal, Wait once the named ids are.
//
@@ -26,6 +26,11 @@ type SubAgent struct {
Goal string
// RoleID is the bound role/persona.
RoleID string
// PersonaID is the target role the sub-agent runs as: its instructions and its
// memory scope (design/22 §8-2). Blank means "run as the spawning turn's role",
// the pre-existing behavior. The dispatch tool fills it (validated against the
// per-role agent pool) and Spawn stamps it onto the run's session env.
PersonaID string
// Mode is the bound behavior mode.
Mode string
// AttachInfo is the free-form attachment text supplied at spawn.
@@ -130,6 +135,7 @@ func (s *SubAgent) Snapshot() SubAgentResult {
ID: s.ID,
Goal: s.Goal,
RoleID: s.RoleID,
PersonaID: s.PersonaID,
Mode: s.Mode,
AttachInfo: s.AttachInfo,
Status: s.status,