feat(orchestration,runtime): subagent_spawn 支持指定目标角色(以该角色 instructions + 记忆域运行)
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:
1 parent
c7ecc3a249
commit
05d34853f0
14 files changed
+857
-36
No files matched your search
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user