add: finalize logic

This commit is contained in:
2026-02-15 21:25:17 -08:00
parent 6ad52121d3
commit 964544bd82
4 changed files with 284 additions and 61 deletions

View File

@@ -0,0 +1,42 @@
// Package tools collects tools
package tools
import (
"context"
"fmt"
"github.com/ollama/ollama/api"
"tipsy.codes/charles/mc-god/v2/internal/pkg/rcon"
)
type Tool interface {
Do(ctx context.Context, toolCall api.ToolCall, client *rcon.Client) error
Desc() api.Tool
Name() string
}
type Tools map[string]Tool
func New(tools ...Tool) Tools {
ret := make(map[string]Tool)
for _, tool := range tools {
ret[tool.Name()] = tool
}
return ret
}
func (t Tools) AsAPI() api.Tools {
var ret api.Tools
for _, tool := range t {
ret = append(ret, tool.Desc())
}
return ret
}
func (t Tools) Do(ctx context.Context, toolCall api.ToolCall, client *rcon.Client) error {
tool, found := t[toolCall.Function.Name]
if !found {
return fmt.Errorf("unknown tool %q", toolCall.Function.Name)
}
return tool.Do(ctx, toolCall, client)
}

View File

@@ -0,0 +1,59 @@
/*
* Package weather provides a Ollama tool to control the weather.
*/
package weather
import (
"context"
"fmt"
"github.com/ollama/ollama/api"
"tipsy.codes/charles/mc-god/v2/internal/pkg/rcon"
)
func Get() *Tool {
return &Tool{}
}
type Tool struct{}
func (t *Tool) Name() string {
return "change_weather"
}
func (t *Tool) Desc() api.Tool {
toolPropertiesMap := api.NewToolPropertiesMap()
toolPropertiesMap.Set("weather", api.ToolProperty{
Type: api.PropertyType{"string"},
Description: "What to set the weather too",
Enum: []any{"clear", "rain", "thunder"},
})
return api.Tool{
Type: "function",
Function: api.ToolFunction{
Name: Get().Name(),
Description: "Changes the weather on the server",
Parameters: api.ToolFunctionParameters{
Type: "object",
Properties: &api.ToolPropertiesMap{},
Required: []string{"weather"},
},
},
}
}
func (t *Tool) Do(ctx context.Context, toolCall api.ToolCall, client *rcon.Client) error {
weather, found := toolCall.Function.Arguments.Get("weather")
if !found {
return fmt.Errorf("missing weather argument")
}
weatherString, ok := weather.(string)
if !ok {
return fmt.Errorf("incorrect data type %v; want string", weather)
}
if _, err := client.Execute("/weather " + weatherString); err != nil {
return fmt.Errorf("failed to call tool")
}
return nil
}

View File

@@ -0,0 +1,73 @@
/*
* Package zombie provides a Ollama tool to summon zombies.
*/
package zombie
import (
"context"
"fmt"
"github.com/ollama/ollama/api"
"tipsy.codes/charles/mc-god/v2/internal/pkg/rcon"
)
func Get() *Tool {
return &Tool{}
}
type Tool struct{}
func (t *Tool) Name() string {
return "summon_zombies"
}
func (t *Tool) Desc() api.Tool {
toolPropertiesMap := api.NewToolPropertiesMap()
toolPropertiesMap.Set("player", api.ToolProperty{
Type: api.PropertyType{"string"},
Description: "Player to target with zombie summons",
})
toolPropertiesMap.Set("count", api.ToolProperty{
Type: api.PropertyType{"int"},
Description: "Number of zombies to summon, between 1 and 3. If omitted, 1 zombie is spawned",
})
return api.Tool{
Type: "function",
Function: api.ToolFunction{
Name: Get().Name(),
Description: "Changes the weather on the server",
Parameters: api.ToolFunctionParameters{
Type: "object",
Properties: &api.ToolPropertiesMap{},
Required: []string{"player"},
},
},
}
}
func (t *Tool) Do(ctx context.Context, toolCall api.ToolCall, client *rcon.Client) error {
player, found := toolCall.Function.Arguments.Get("player")
if !found {
return fmt.Errorf("missing weather argument")
}
playerString, ok := player.(string)
if !ok {
return fmt.Errorf("incorrect data type %v; want string", player)
}
zombieCount := 1
if count, found := toolCall.Function.Arguments.Get("count"); found {
countInt, ok := count.(int)
if !ok {
return fmt.Errorf("incorrect data type %v; want int", countInt)
}
zombieCount = countInt
}
if zombieCount > 4 {
zombieCount = 4
}
for i := 0; i < zombieCount; i += 1 {
client.Execute(fmt.Sprintf("/execute at %q run summon zombie ~ ~ ~", playerString))
}
return nil
}