package agents import ( "context" "encoding/json" "screenmark/screenmark/.gen/haystack/haystack/model" "screenmark/screenmark/agents/client" "screenmark/screenmark/models" "github.com/charmbracelet/log" "github.com/google/uuid" ) const locationPrompt = ` You are an agent. The user will send you images and you have to identify if they have any location or a place. This could a picture of a real place, an address, or it's name. There are various tools you can use to perform this task. listLocations Lists the users already existing locations. createLocation Use this to create a new location, when you don't see a matching one from listLocations call. reply Use this only if the user has asked a question about a location. finish Call when there is nothing else to do. ` const locationTools = ` [ { "type": "function", "function": { "name": "listLocations", "description": "List the locations the user already has.", "parameters": { "type": "object", "properties": {}, "required": [] } } }, { "type": "function", "function": { "name": "createLocation", "description": "Use to create a new location", "parameters": { "type": "object", "properties": { "name": { "type": "string" }, "address": { "type": "string" } }, "required": ["name"] } } }, { "type": "function", "function": { "name": "reply", "description": "Reply to a user query, only if the user has asked something", "parameters": { "type": "object", "properties": { "locationId": { "type": "string" } }, "required": ["locationId"] } } }, { "type": "function", "function": { "name": "finish", "description": "Call this when there is nothing left to do.", "parameters": { "type": "object", "properties": {}, "required": [] } } } ]` type listLocationArguments struct{} type createLocationArguments struct { Name string `json:"name"` Address *string `json:"address"` } type linkLocationArguments struct { LocationID string `json:"locationId"` } func NewLocationAgent(log *log.Logger, locationModel models.LocationModel) (client.AgentClient, error) { agentClient := client.CreateAgentClient(client.CreateAgentClientOptions{ SystemPrompt: locationPrompt, JsonTools: locationTools, Log: log, EndToolCall: "finish", }) agentClient.ToolHandler.AddTool("listLocations", func(info client.ToolHandlerInfo, args string, call client.ToolCall) (any, error) { return locationModel.List(context.Background(), info.UserId) }) agentClient.ToolHandler.AddTool("createLocation", func(info client.ToolHandlerInfo, _args string, call client.ToolCall) (any, error) { args := createLocationArguments{} err := json.Unmarshal([]byte(_args), &args) if err != nil { return model.Locations{}, err } ctx := context.Background() location, err := locationModel.Save(ctx, info.UserId, model.Locations{ Name: args.Name, Address: args.Address, }) if err != nil { return model.Locations{}, err } _, err = locationModel.SaveToImage(ctx, info.ImageId, location.ID) if err != nil { return model.Locations{}, err } return location, nil }) agentClient.ToolHandler.AddTool("linkLocation", func(info client.ToolHandlerInfo, _args string, call client.ToolCall) (any, error) { args := linkLocationArguments{} err := json.Unmarshal([]byte(_args), &args) if err != nil { return "", err } ctx := context.Background() contactUuid, err := uuid.Parse(args.LocationID) if err != nil { return "", err } locationModel.SaveToImage(ctx, info.ImageId, contactUuid) return "Saved", nil }) agentClient.ToolHandler.AddTool("reply", func(info client.ToolHandlerInfo, args string, call client.ToolCall) (any, error) { agentClient.Log.Debug(args) return "ok", nil }) return agentClient, nil }