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
// active belongs to the running turn. The mutex protects pending, cancel, and
// failure.
type TurnLoop struct {
- agent *Agent
- memory *Memory
- client ChainClient
- tools *Toolbox
- runs *SubagentRuns
- layout *ViewLayout
- clock func() time.Time
- logger *slog.Logger
- notify func(Event)
- wake chan struct{}
- messages *DaemonMessages
- active []Message
+ agent *Agent
+ memory *Memory
+ client ChainClient
+ tools *Toolbox
+ runs *SubagentRuns
+ layout *ViewLayout
+ clock func() time.Time
+ logger *slog.Logger
+ notify func(Event)
+ wake chan struct{}
+ messages *DaemonMessages
+ openChild func(context.Context, *Agent) (*DaemonAgent, error)
+ active []Message
mutex sync.Mutex
pending []Message
Instructions: instructions,
Tools: l.agent.Tools(),
},
- take: l.take,
+ take: l.take,
+ images: l.agent.Images(),
}
- reply, err := chain.Run(ctx, turnInput(view, l.state(), messages))
+ input := turnInput(view, l.state(), messages)
+ for n, message := range messages {
+ input[len(input)-len(messages)+n], err = imageUserMessage(l.agent.Images(), message.Text)
+ if err != nil {
+ return "", fmt.Errorf("read turn images: %w", err)
+ }
+ }
+
+ reply, err := chain.Run(ctx, input)
if err != nil {
return "", fmt.Errorf("run turn chain: %w", err)
}
}
// state returns the per-turn state: the end of the view, and the date and time
-// of the turn.
+// of the turn, then the names and responsibilities of its children.
func (l *TurnLoop) state() string {
- return "</chat>\n\nNow: " + l.clock().Format("Monday 2006-01-02 15:04 -07:00")
+ 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
}
// turnError returns the text of the error that ended a turn.