GoFlowGoFlow
Examples

Custom Tools

Create custom tools for your agents.

Simple Tool

package main
 
import (
	"context"
	"fmt"
	
	"github.com/nuulab/goflow/pkg/tools"
)
 
func main() {
	// Simple tool with string input/output
	greetTool := tools.NewTool(
		"greet",
		"Greet a person by name",
		func(ctx context.Context, name string) (string, error) {
			return fmt.Sprintf("Hello, %s! Welcome to GoFlow.", name), nil
		},
	)
 
	registry := tools.NewRegistry()
	registry.Register(greetTool)
}

Tool with Structured Input

// Define input schema
type WeatherInput struct {
	City    string `json:"city" description:"City name"`
	Country string `json:"country" description:"Country code (optional)"`
	Units   string `json:"units" description:"celsius or fahrenheit"`
}
 
weatherTool := tools.NewToolWithSchema(
	"get_weather",
	"Get current weather for a city",
	WeatherInput{}, // Schema is derived from struct
	func(ctx context.Context, input WeatherInput) (string, error) {
		// Call weather API
		weather := callWeatherAPI(input.City, input.Country)
		return fmt.Sprintf("Weather in %s: %s, %d°%s", 
			input.City, 
			weather.Condition, 
			weather.Temp,
			input.Units[0:1],
		), nil
	},
)

Async Tool

type ProcessResult struct {
	Status  string
	Records int
}
 
asyncTool := tools.NewAsyncTool(
	"process_large_file",
	"Process a large file in the background",
	func(ctx context.Context, filename string) <-chan tools.Result {
		ch := make(chan tools.Result, 1)
		
		go func() {
			defer close(ch)
			
			// Simulate long processing
			records := processFile(filename)
			
			ch <- tools.Result{
				Output: fmt.Sprintf("Processed %d records", records),
			}
		}()
		
		return ch
	},
)

Tool with Validation

type EmailInput struct {
	To      string `json:"to" validate:"required,email"`
	Subject string `json:"subject" validate:"required,min=1,max=200"`
	Body    string `json:"body" validate:"required"`
}
 
emailTool := tools.NewToolWithSchema(
	"send_email",
	"Send an email",
	EmailInput{},
	func(ctx context.Context, input EmailInput) (string, error) {
		if err := sendEmail(input.To, input.Subject, input.Body); err != nil {
			return "", err
		}
		return "Email sent successfully", nil
	},
)

Tool with Context

type DatabaseTool struct {
	db *sql.DB
}
 
func (d *DatabaseTool) QueryTool() *tools.Tool {
	return tools.NewTool(
		"query_db",
		"Run a SQL query",
		func(ctx context.Context, query string) (string, error) {
			rows, err := d.db.QueryContext(ctx, query)
			if err != nil {
				return "", err
			}
			return formatResults(rows), nil
		},
	)
}
 
// Usage
dbTool := &DatabaseTool{db: database}
registry.Register(dbTool.QueryTool())

Creating a Toolkit

func CRMToolkit(apiClient *crm.Client) *tools.Toolkit {
	return &tools.Toolkit{
		Name: "crm",
		Tools: []*tools.Tool{
			tools.NewTool("crm_get_contact", "Get contact by ID", 
				func(ctx context.Context, id string) (string, error) {
					contact, _ := apiClient.GetContact(id)
					return json.Marshal(contact)
				}),
			tools.NewTool("crm_create_contact", "Create a new contact",
				func(ctx context.Context, data string) (string, error) {
					var contact Contact
					json.Unmarshal([]byte(data), &contact)
					return apiClient.CreateContact(contact)
				}),
			tools.NewTool("crm_search", "Search contacts",
				func(ctx context.Context, query string) (string, error) {
					results, _ := apiClient.Search(query)
					return json.Marshal(results)
				}),
		},
	}
}
 
// Usage
registry.RegisterToolkit(CRMToolkit(crmClient))

On this page