package tools import ( "context" "encoding/json" "fmt" "strings" "ollie/toolsrv" ) // ToolList lists all available tools from the global registry. func ToolList(ctx context.Context, srv *toolsrv.Server, args json.RawMessage) (string, error) { reg := srv.ToolRegistry() if reg == nil { return "", fmt.Errorf("tool_list: no registry available") } // Refresh loaded tool schemas from disk so the model sees current definitions. sid := srv.SessionID() if sid != "" { reg.RefreshLoaded(sid) } summaries := reg.Summaries() if len(summaries) == 0 { return "(no tools found)", nil } var out strings.Builder for _, s := range summaries { out.WriteString(s.Name) if s.Description != "" { out.WriteString(" — ") out.WriteString(s.Description) } out.WriteString("\n") } // Notify the agent that the tool listing may have changed so the // preamble stays in sync with the directory contents. if srv.OnToolsChanged != nil { var listing strings.Builder for _, s := range summaries { if s.Description != "" { fmt.Fprintf(&listing, "- **%s** — %s\n", s.Name, s.Description) } } srv.OnToolsChanged(listing.String()) } return strings.TrimRight(out.String(), "\n"), nil } // ToolLoad loads a tool into the current session. func ToolLoad(ctx context.Context, srv *toolsrv.Server, args json.RawMessage) (string, error) { var a struct { Name string `json:"name"` } if err := json.Unmarshal(args, &a); err != nil { return "", fmt.Errorf("tool_load: bad args: %w", err) } if a.Name == "" { return "", fmt.Errorf("tool_load: name is required") } reg := srv.ToolRegistry() sid := srv.SessionID() if reg == nil || sid == "" { return "", fmt.Errorf("tool_load: no session registry") } if err := reg.Load(sid, a.Name); err != nil { return "", fmt.Errorf("tool_load: %w", err) } return fmt.Sprintf("loaded: %s", a.Name), nil } // ToolActive lists tools currently loaded (promoted) in this session. func ToolActive(ctx context.Context, srv *toolsrv.Server, args json.RawMessage) (string, error) { reg := srv.ToolRegistry() sid := srv.SessionID() if reg == nil || sid == "" { return "(no tools loaded)", nil } loaded := reg.Loaded(sid) if len(loaded) == 0 { return "(no tools loaded)", nil } var out strings.Builder for _, t := range loaded { out.WriteString(t.Name) if t.Description != "" { out.WriteString(" — ") out.WriteString(t.Description) } out.WriteString("\n") } return strings.TrimRight(out.String(), "\n"), nil }