// Command agent demonstrates the agent loop: model + system prompt + // toolbox, run to completion with step observation. package main import ( "context" "encoding/json" "flag" "fmt" "log" "os" "gitea.stevedudenhoeffer.com/steve/majordomo" "gitea.stevedudenhoeffer.com/steve/majordomo/agent" ) func main() { model := flag.String("model", "ollama-cloud/minimax-m3:cloud", "model spec") flag.Parse() files := majordomo.NewToolbox("files", majordomo.Tool{ Name: "list_dir", Description: "List the files in a directory.", Parameters: json.RawMessage(`{"type":"object","properties":{"path":{"type":"string"}},"required":["path"]}`), Handler: func(_ context.Context, args json.RawMessage) (any, error) { var p struct { Path string `json:"path"` } if err := json.Unmarshal(args, &p); err != nil { return nil, err } entries, err := os.ReadDir(p.Path) if err != nil { return nil, err } names := make([]string, 0, len(entries)) for _, e := range entries { names = append(names, e.Name()) } return names, nil }, }, ) m, err := majordomo.Parse(*model) if err != nil { log.Fatalf("parse: %v", err) } a := agent.New(m, "You are a filesystem assistant. Use your tools; never invent file names.", agent.WithToolbox(files), agent.WithMaxSteps(6), agent.WithStepObserver(func(s agent.Step) { for _, call := range s.Response.ToolCalls { fmt.Printf(" step %d: %s(%s)\n", s.Index, call.Name, call.Arguments) } }), ) res, err := a.Run(context.Background(), "What Go files are in the current directory?") if err != nil { log.Fatalf("run: %v", err) } fmt.Printf("\n%s\n(%d steps, %d tokens)\n", res.Output, len(res.Steps), res.Usage.Total()) }