feat/inter-agent-communication #10

Merged
JohnCosta27 merged 9 commits from feat/inter-agent-communication into main 2025-04-17 17:51:57 +01:00
8 changed files with 116 additions and 24 deletions
Showing only changes of commit fa127c2331 - Show all commits

View File

@ -73,6 +73,8 @@ type AgentClient struct {
Log *log.Logger Log *log.Logger
Reply string
Do func(req *http.Request) (*http.Response, error) Do func(req *http.Request) (*http.Response, error)
} }
@ -186,7 +188,7 @@ func (client AgentClient) ToolLoop(info ToolHandlerInfo, req *AgentRequestBody)
var FinishedCall = errors.New("Last tool tool was called") var FinishedCall = errors.New("Last tool tool was called")
func (client AgentClient) Process(info ToolHandlerInfo, req *AgentRequestBody) error { func (client *AgentClient) Process(info ToolHandlerInfo, req *AgentRequestBody) error {
var err error var err error
message, err := req.Chat.GetLatest() message, err := req.Chat.GetLatest()
@ -211,6 +213,10 @@ func (client AgentClient) Process(info ToolHandlerInfo, req *AgentRequestBody) e
toolResponse := client.ToolHandler.Handle(info, toolCall) toolResponse := client.ToolHandler.Handle(info, toolCall)
if toolCall.Function.Name == "reply" {
client.Reply = toolCall.Function.Arguments
}
client.Log.SetLevel(log.DebugLevel) client.Log.SetLevel(log.DebugLevel)
client.Log.Debugf("Response: %s", toolResponse.Content) client.Log.Debugf("Response: %s", toolResponse.Content)
@ -249,9 +255,10 @@ func (client AgentClient) RunAgent(systemPrompt string, jsonTools string, endToo
} }
toolHandlerInfo := ToolHandlerInfo{ toolHandlerInfo := ToolHandlerInfo{
ImageId: imageId, ImageId: imageId,
UserId: userId, ImageName: imageName,
Image: &imageData, UserId: userId,
Image: &imageData,
} }
return client.ToolLoop(toolHandlerInfo, &request) return client.ToolLoop(toolHandlerInfo, &request)

View File

@ -8,8 +8,9 @@ import (
) )
type ToolHandlerInfo struct { type ToolHandlerInfo struct {
UserId uuid.UUID UserId uuid.UUID
ImageId uuid.UUID ImageId uuid.UUID
ImageName string
// Pointer because we don't want to copy this around too much. // Pointer because we don't want to copy this around too much.
Image *[]byte Image *[]byte

View File

@ -27,6 +27,9 @@ Lists the users already existing events.
createEvent createEvent
Use this to create a new events. Use this to create a new events.
getEventLocationId
Use this if the image contains a location or place. This tool will return the locationId.
finish finish
Call when there is nothing else to do. Call when there is nothing else to do.
` `
@ -68,6 +71,18 @@ const eventTools = `
"required": ["name"] "required": ["name"]
} }
} }
},
{
"type": "function",
"function": {
"name": "getEventLocationId",
"description": "Get the ID of the location on the image, only use if the event contains a location or place.",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}, },
{ {
"type": "function", "type": "function",
@ -180,9 +195,11 @@ func NewEventAgent(eventsModel models.EventModel, locationAgent LocationAgent) (
return "Saved", nil return "Saved", nil
}) })
agentClient.ToolHandler.AddTool("getLocationId", func(info client.ToolHandlerInfo, args string, call client.ToolCall) (any, error) { agentClient.ToolHandler.AddTool("getEventLocationId", func(info client.ToolHandlerInfo, args string, call client.ToolCall) (any, error) {
// locationAgent.client.RunAgent() query := "Can you get me the ID of the location present in this image?"
return "no location found", nil locationAgent.client.RunAgent(locationPrompt, locationTools, "finish", &query, info.UserId, info.ImageId, info.ImageName, *info.Image)
return locationAgent.client.Reply, nil
}) })
return agent, nil return agent, nil

View File

@ -27,6 +27,9 @@ Lists the users already existing locations.
createLocation createLocation
Use this to create a new location, when you don't see a matching one from listLocations call. 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 finish
Call when there is nothing else to do. Call when there is nothing else to do.
` `
@ -63,6 +66,22 @@ const locationTools = `
"required": ["name"] "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", "type": "function",
@ -157,5 +176,10 @@ func NewLocationAgent(locationModel models.LocationModel) (LocationAgent, error)
return "Saved", nil return "Saved", nil
}) })
agentClient.ToolHandler.AddTool("reply", func(info client.ToolHandlerInfo, args string, call client.ToolCall) (any, error) {
agent.client.Log.Debug(args)
return "ok", nil
})
return agent, nil return agent, nil
} }

View File

@ -57,7 +57,7 @@ func ListenNewImageEvents(db *sql.DB, eventManager *EventManager) {
panic(err) panic(err)
} }
eventAgent, err := agents.NewEventAgent(eventModel) eventAgent, err := agents.NewEventAgent(eventModel, locationAgent)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -82,7 +82,7 @@ func ListenNewImageEvents(db *sql.DB, eventManager *EventManager) {
// Still need to find some way to hide this complexity away. // Still need to find some way to hide this complexity away.
// I don't think wrapping agents in structs actually works too well. // I don't think wrapping agents in structs actually works too well.
err = orchestrator.Client.RunAgent(agents.OrchestratorPrompt, agents.OrchestratorTools, "noAction", image.UserID, image.ImageID, image.Image.ImageName, image.Image.Image) err = orchestrator.Client.RunAgent(agents.OrchestratorPrompt, agents.OrchestratorTools, "noAction", nil, image.UserID, image.ImageID, image.Image.ImageName, image.Image.Image)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }