+ l.runs = &SubagentRuns{
+ agent: agent,
+ memory: memory,
+ subagents: subagents,
+ layout: layout,
+ client: client,
+ state: l.state,
+ report: l.Report,
+ note: l.note,
+ fail: l.fail,
+ logger: logger,
+ notify: notify,
+ running: make(map[string]*SubagentRun),
+ }
+
+ if agent.config.Parent != "" {
+ whatsapp = nil
+ }
+
+ l.tools = &Toolbox{
+ log: l,
+ chat: memory,
+ subagents: subagents,
+ runs: l.runs,
+ whatsapp: whatsapp,
+ schedules: schedules,
+ workdir: agent.config.Workdir,
+ agentName: agent.config.Name,
+ images: agent.Images(),
+ }
+
+ if agent.config.Parent == "" {
+ l.tools.imageShow = &ImageShow{store: agent.Images()}
+ }
+
+ return l, nil
+}
+
+// state returns the per-turn state: the end of the view, and the date and time
+// of the turn, then the names and responsibilities of its children.
+func (l *TurnLoop) state() string {
+ state := "</chat>\n\nNow: " + l.clock().Format("Monday 2006-01-02 15:04 -07:00")
+ if l.messages != nil {
+ state += l.messages.ChildState(l.agent.config.Name)
+ }
+
+ return state
+}
+
+// Report logs the report text of the subagent name as a work message and tells
+// the clients, with the status of the run. Unless the subagent was stopped, the
+// report joins the waiting messages and wakes the loop, as a user message of
+// Submit does. A failed write stops the loop, because the log refuses all
+// writes after it.
+func (l *TurnLoop) Report(name, text, status string) {
+ message, err := l.Work(name, text, status)
+ switch {
+ case err != nil:
+ l.fail(fmt.Errorf("%w: %w", errChainLogWrite, err))
+ case status != subagentStopped:
+ l.Wake(message)