package orchestration import ( "context" "fmt" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/memory" ) // This file owns the scheduler's long-term-memory half: handing a sub-agent's task // memory to the injected *memory.Store. It sits next to persona.go because the role // a sub-agent runs as (design/22 §8-2) is exactly the scope its memory is filed // under. // SinkMemory persists a task memory item for a sub-agent through the injected // *memory.Store. The role the sub-agent ran as is used as the persona/role key — // the dispatched target persona when one was named, otherwise the legacy RoleID // binding — so a sub-agent standing in for another role writes that role's memory // domain, never the spawning session's (design/22 §8-2/§8-5). Content and the // scope/kind classification (user/persona/project) are supplied by the caller, // keeping scope policy at the call site. It returns ErrNoMemory when no store was // injected. func (s *Scheduler) SinkMemory(ctx context.Context, sub *SubAgent, content string, scope memory.Scope, kind memory.Kind) (memory.MemoryItem, error) { if s.memory == nil { return memory.MemoryItem{}, fmt.Errorf("orchestration: sink memory: %w", ErrNoMemory) } if sub == nil { return memory.MemoryItem{}, fmt.Errorf("orchestration: sink memory: %w", ErrAgentNotFound) } role := sub.PersonaID if role == "" { role = sub.RoleID } item := memory.MemoryItem{ PersonaID: role, RoleID: role, Scope: scope, Kind: kind, Content: content, } return s.memory.Add(ctx, item) }