// 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,
+// and the WhatsApp link for the WhatsApp tools. The toolbox of a subagent has
+// neither, 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
+ workdir string
}
// Call logs the call of the tool name with its JSON arguments, makes the log
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":
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)
+ }
default:
err = fmt.Errorf("unknown tool %q", name)
}
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) {
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.
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"`
+}
+
// ToolHeadTail keeps the first and the last toolClipBytes bytes written to it,
// and counts the bytes between them that it drops.
type ToolHeadTail struct {