return errors.Join(err, listener.Close())
}
+ if bot != nil {
+ l.tools.imageShow.bot = bot
+ }
+
loops := []*TurnLoop{l}
for _, child := range children {
loop, err := child.Loop(nil, func(Event) {
}
hub.snapshot = func(ctx context.Context, snapshot func() error) error {
- return messages.Snapshot(func() error {
- return daemonSnapshot(ctx, loops, snapshot)
- })
+ return messages.SnapshotAgents(ctx, snapshot)
}
+ runtime := &DaemonChildren{
+ ctx: ctx,
+ cancel: cancel,
+ root: l,
+ messages: messages,
+ }
+ l.tools.children = runtime
+
var workers sync.WaitGroup
childErrors := make([]error, len(children))
hub.CloseAll()
workers.Wait()
- return errors.Join(err, whatsappErr, schedulesErr, botErr, errors.Join(childErrors...))
+ return errors.Join(err, whatsappErr, schedulesErr, botErr, errors.Join(childErrors...), runtime.Close())
}
// daemonRunChild runs a child's turn loop and its schedules until either stops.
_, err := l.Submit(terminalSource, request.Text)
return err
+ case "image":
+ if !filepath.IsAbs(request.Path) {
+ return errors.New("use /image PATH [caption]")
+ }
+
+ data, err := imageReadFile(request.Path)
+ if err != nil {
+ return fmt.Errorf("read terminal image: %w", err)
+ }
+
+ name, err := l.agent.Images().Save(data)
+ if err != nil {
+ return fmt.Errorf("store terminal image: %w", err)
+ }
+
+ _, err = l.Submit(terminalSource, imageText([]string{name}, request.Text))
+ if err != nil {
+ return fmt.Errorf("submit terminal image: %w", err)
+ }
+
+ return nil
case "interrupt":
if !l.Interrupt() {
return errors.New("no turn runs")