Implement interactive CLI for LLM providers with chat, tools, and image support
- Add Bubble Tea-based CLI interface for LLM interactions. - Implement `.env.example` for environment variable setup. - Add provider, model, and tool selection screens. - Include support for API key configuration. - Enable chat interactions with optional image and tool support. - Introduce core utility functions: image handling, tool execution, chat request management, and response rendering. - Implement style customization with Lip Gloss.
This commit is contained in:
105
cmd/llm/tools.go
Normal file
105
cmd/llm/tools.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
llm "gitea.stevedudenhoeffer.com/steve/go-llm"
|
||||
)
|
||||
|
||||
// TimeParams is the parameter struct for the GetTime function
|
||||
type TimeParams struct{}
|
||||
|
||||
// GetTime returns the current time
|
||||
func GetTime(_ *llm.Context, _ TimeParams) (any, error) {
|
||||
return time.Now().Format("Monday, January 2, 2006 3:04:05 PM MST"), nil
|
||||
}
|
||||
|
||||
// CalcParams is the parameter struct for the Calculate function
|
||||
type CalcParams struct {
|
||||
A float64 `json:"a" description:"First number"`
|
||||
B float64 `json:"b" description:"Second number"`
|
||||
Op string `json:"op" description:"Operation: add, subtract, multiply, divide, power, sqrt, mod"`
|
||||
}
|
||||
|
||||
// Calculate performs basic math operations
|
||||
func Calculate(_ *llm.Context, params CalcParams) (any, error) {
|
||||
switch strings.ToLower(params.Op) {
|
||||
case "add", "+":
|
||||
return params.A + params.B, nil
|
||||
case "subtract", "sub", "-":
|
||||
return params.A - params.B, nil
|
||||
case "multiply", "mul", "*":
|
||||
return params.A * params.B, nil
|
||||
case "divide", "div", "/":
|
||||
if params.B == 0 {
|
||||
return nil, fmt.Errorf("division by zero")
|
||||
}
|
||||
return params.A / params.B, nil
|
||||
case "power", "pow", "^":
|
||||
return math.Pow(params.A, params.B), nil
|
||||
case "sqrt":
|
||||
if params.A < 0 {
|
||||
return nil, fmt.Errorf("cannot take square root of negative number")
|
||||
}
|
||||
return math.Sqrt(params.A), nil
|
||||
case "mod", "%":
|
||||
return math.Mod(params.A, params.B), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown operation: %s", params.Op)
|
||||
}
|
||||
}
|
||||
|
||||
// WeatherParams is the parameter struct for the GetWeather function
|
||||
type WeatherParams struct {
|
||||
Location string `json:"location" description:"City name or location"`
|
||||
}
|
||||
|
||||
// GetWeather returns mock weather data (for demo purposes)
|
||||
func GetWeather(_ *llm.Context, params WeatherParams) (any, error) {
|
||||
// This is a demo function - returns mock data
|
||||
weathers := []string{"sunny", "cloudy", "rainy", "partly cloudy", "windy"}
|
||||
temps := []int{65, 72, 58, 80, 45}
|
||||
|
||||
// Use location string to deterministically pick weather
|
||||
idx := len(params.Location) % len(weathers)
|
||||
|
||||
return map[string]any{
|
||||
"location": params.Location,
|
||||
"temperature": strconv.Itoa(temps[idx]) + "F",
|
||||
"condition": weathers[idx],
|
||||
"humidity": "45%",
|
||||
"note": "This is mock data for demonstration purposes",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RandomNumberParams is the parameter struct for the RandomNumber function
|
||||
type RandomNumberParams struct {
|
||||
Min int `json:"min" description:"Minimum value (inclusive)"`
|
||||
Max int `json:"max" description:"Maximum value (inclusive)"`
|
||||
}
|
||||
|
||||
// RandomNumber generates a pseudo-random number (using current time nanoseconds)
|
||||
func RandomNumber(_ *llm.Context, params RandomNumberParams) (any, error) {
|
||||
if params.Min > params.Max {
|
||||
return nil, fmt.Errorf("min cannot be greater than max")
|
||||
}
|
||||
// Simple pseudo-random using time
|
||||
n := time.Now().UnixNano()
|
||||
rangeSize := params.Max - params.Min + 1
|
||||
result := params.Min + int(n%int64(rangeSize))
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// createDemoToolbox creates a toolbox with demo tools for testing
|
||||
func createDemoToolbox() llm.ToolBox {
|
||||
return llm.NewToolBox(
|
||||
llm.NewFunction("get_time", "Get the current date and time", GetTime),
|
||||
llm.NewFunction("calculate", "Perform basic math operations (add, subtract, multiply, divide, power, sqrt, mod)", Calculate),
|
||||
llm.NewFunction("get_weather", "Get weather information for a location (demo data)", GetWeather),
|
||||
llm.NewFunction("random_number", "Generate a random number between min and max", RandomNumber),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user