X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/1e7f78e7b12d3881a6c345d191dfef6e42d9b01f..e737005f89c7c663e1636830001730ad79396bdc:/tools.go diff --git a/tools.go b/tools.go index af500ba..009e331 100644 --- a/tools.go +++ b/tools.go @@ -49,11 +49,19 @@ type ToolChat interface { // the log as it happens: the call as a tool message, the result as an echo // message. The call is durable before its tool runs, so the log never misses an // action outside the agent. Commands and files run as the user in the working -// directory, with no sandbox. +// directory, with no sandbox. Zoom with a name reads the log of a subagent. The +// toolbox of the agent has the runs of its subagents for spawn and tell, the +// WhatsApp link for the WhatsApp tools, and the schedules for the schedule +// tools. The toolbox of a subagent has none of them, so these are unknown tools +// there. type Toolbox struct { - log ToolLog - chat ToolChat - workdir string + log ToolLog + chat ToolChat + subagents *Subagents + runs *SubagentRuns + whatsapp *WhatsApp + schedules *Schedules + workdir string } // Call logs the call of the tool name with its JSON arguments, makes the log @@ -92,7 +100,11 @@ func (b *Toolbox) run(ctx context.Context, name, arguments string) string { case "zoom": var args ToolZoomArguments err = toolDecodeArguments(arguments, &args) - if err == nil { + switch { + case err != nil: + case args.Name != nil: + output, err = b.zoomAgent(ctx, *args.Name) + default: output, err = b.zoom(args.ID, args.N) } case "date": @@ -125,6 +137,68 @@ func (b *Toolbox) run(ctx context.Context, name, arguments string) string { if err == nil { output, err = b.edit(args.Path, args.Old, args.New) } + case "spawn": + var args ToolSpawnArguments + err = toolDecodeArguments(arguments, &args) + switch { + case b.runs == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output, err = b.runs.Spawn(ctx, args.Tasks, args.Effort) + } + case "tell": + var args ToolTellArguments + err = toolDecodeArguments(arguments, &args) + switch { + case b.runs == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output, err = b.runs.Tell(ctx, args.Name, args.Message) + } + case "whatsapp_find": + var args ToolWhatsAppFindArguments + err = toolDecodeArguments(arguments, &args) + switch { + case b.whatsapp == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output, err = b.whatsapp.Find(ctx, args.Name) + } + case "whatsapp_send": + var args ToolWhatsAppSendArguments + err = toolDecodeArguments(arguments, &args) + switch { + case b.whatsapp == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output, err = b.whatsapp.Send(ctx, args.ID, args.Chat, args.Text) + } + case "schedule_set": + var args ToolScheduleSetArguments + err = toolDecodeArguments(arguments, &args) + switch { + case b.schedules == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output, err = b.schedules.Set(args.Text, args.At, args.Cron) + } + case "schedule_list": + err = toolDecodeArguments(arguments, &struct{}{}) + switch { + case b.schedules == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output = b.schedules.List() + } + case "schedule_remove": + var args ToolScheduleRemoveArguments + err = toolDecodeArguments(arguments, &args) + switch { + case b.schedules == nil: + err = fmt.Errorf("unknown tool %q", name) + case err == nil: + output, err = b.schedules.Remove(args.ID) + } default: err = fmt.Errorf("unknown tool %q", name) } @@ -136,6 +210,16 @@ func (b *Toolbox) run(ctx context.Context, name, arguments string) string { return output } +// zoomAgent returns the whole log of the subagent name. +func (b *Toolbox) zoomAgent(ctx context.Context, name string) (string, error) { + subagent, err := b.subagents.Get(ctx, name) + if err != nil { + return "", err + } + + return subagent.Show() +} + // zoom returns message id whole for n = 1, or else the two lines under the line // id+n. func (b *Toolbox) zoom(id, n int) (string, error) { @@ -307,10 +391,12 @@ func (b *Toolbox) path(path string) string { return filepath.Join(b.workdir, path) } -// ToolZoomArguments are the arguments of zoom. +// ToolZoomArguments are the arguments of zoom. A Name that is not nil names +// the subagent whose whole log zoom gives, and then ID and N are not used. type ToolZoomArguments struct { - ID int `json:"id"` - N int `json:"n"` + ID int `json:"id"` + N int `json:"n"` + Name *string `json:"name"` } // ToolDateArguments are the arguments of date. @@ -341,6 +427,44 @@ type ToolEditArguments struct { New string `json:"new"` } +// ToolSpawnArguments are the arguments of spawn. A nil Effort is the effort of +// the agent. +type ToolSpawnArguments struct { + Tasks []string `json:"tasks"` + Effort *string `json:"effort"` +} + +// ToolTellArguments are the arguments of tell. +type ToolTellArguments struct { + Name string `json:"name"` + Message string `json:"message"` +} + +// ToolWhatsAppFindArguments are the arguments of whatsapp_find. +type ToolWhatsAppFindArguments struct { + Name string `json:"name"` +} + +// ToolWhatsAppSendArguments are the arguments of whatsapp_send. +type ToolWhatsAppSendArguments struct { + ID string `json:"id"` + Chat string `json:"chat"` + Text string `json:"text"` +} + +// ToolScheduleSetArguments are the arguments of schedule_set. Exactly one of At +// and Cron is not nil. +type ToolScheduleSetArguments struct { + Text string `json:"text"` + At *string `json:"at"` + Cron *string `json:"cron"` +} + +// ToolScheduleRemoveArguments are the arguments of schedule_remove. +type ToolScheduleRemoveArguments struct { + ID int `json:"id"` +} + // ToolHeadTail keeps the first and the last toolClipBytes bytes written to it, // and counts the bytes between them that it drops. type ToolHeadTail struct {