Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,4 +758,19 @@ const (

// ArgSignature is a byoip prefix argument.
ArgSignature = "signature"

// ArgAgentParentID is the ID for the parent agent.
ArgParentAgentId = "parent-agent-id"

// ArgChildAgentID is the ID for the child agent.
ArgChildAgentId = "child-agent-id"

// ArgAgentRouteId is the UUID for the agent linkage.
ArgAgentRouteId = "route-id"

// ArgAgentRouteName is the name of the route.
ArgAgentRouteName = "route-name"

// ArgAgentRouteIfCase is the if-case condition for the route.
ArgAgentRouteIfCase = "if-case"
Comment thread
SSharma-10 marked this conversation as resolved.
)
47 changes: 47 additions & 0 deletions commands/displayers/genai.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,50 @@ func (v *KnowledgeBaseDataSource) KV() []map[string]any {

return out
}

type AgentRoute struct {
AgentRouteResponses []do.AgentRouteResponse
}

var _ Displayable = &AgentRoute{}

func (a *AgentRoute) JSON(out io.Writer) error {
return writeJSON(a.AgentRouteResponses, out)
}

func (a *AgentRoute) Cols() []string {
return []string{
"Id",
"ParentAgentId",
"ChildAgentId",
"Rollback",
}
}

func (a *AgentRoute) ColMap() map[string]string {
return map[string]string{
"Id": "Id",
"ParentAgentId": "Parent Agent Id",
"ChildAgentId": "Child Agent Id",
"Rollback": "Rollback",
}
}

func (a *AgentRoute) KV() []map[string]any {
if a == nil || a.AgentRouteResponses == nil {
return []map[string]any{}
}
out := make([]map[string]any, 0, len(a.AgentRouteResponses))

for _, response := range a.AgentRouteResponses {
o := map[string]any{
"Id": response.UUID,
"ParentAgentId": response.ParentAgentUuid,
"ChildAgentId": response.ChildAgentUuid,
"Rollback": response.Rollback,
}
out = append(out, o)
}

return out
}
3 changes: 3 additions & 0 deletions commands/genai_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func AgentCmd() *Command {
},
}

// Add the agent route command as a subcommand to genai agent
cmd.AddCommand(AgentRouteCmd())

cmdAgentCreate := CmdBuilder(
cmd,
RunAgentCreate,
Expand Down
152 changes: 152 additions & 0 deletions commands/genai_agent_route.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package commands

import (
"github.com/digitalocean/doctl"
"github.com/digitalocean/doctl/commands/displayers"
"github.com/digitalocean/doctl/do"
"github.com/digitalocean/godo"
"github.com/spf13/cobra"
)

// AgentRouteCmd creates the agent route command and its subcommands.
func AgentRouteCmd() *Command {
cmd := &Command{
Command: &cobra.Command{
Use: "route",
Aliases: []string{"routes", "r"},
Short: "Display commands for working with GenAI agent routes",
Long: "The subcommands of `doctl genai agent route` manage your GenAI agent routes.",
},
}

cmdAddAgentRoute := CmdBuilder(
cmd,
RunAgentRouteAdd,
"add",
"Adds an agent route to an agent",
"Use this command to add an agent route to an agent. The command requires values for the "+"`"+"--parent-agent-id"+"` and "+"`"+"--child-agent-id"+"`"+" flags.",
Writer,
aliasOpt("c"),
displayerType(&displayers.AgentRoute{}),
)
AddStringFlag(cmdAddAgentRoute, doctl.ArgParentAgentId, "", "", "Parent agent ID (required)", requiredOpt())
AddStringFlag(cmdAddAgentRoute, doctl.ArgChildAgentId, "", "", "Child agent ID (required)", requiredOpt())
AddStringFlag(cmdAddAgentRoute, doctl.ArgAgentRouteId, "", "", "Unique id of linkage")
AddStringFlag(cmdAddAgentRoute, doctl.ArgAgentRouteName, "", "", "Route name")
AddStringFlag(cmdAddAgentRoute, doctl.ArgAgentRouteIfCase, "", "", "Describes the case in which the child agent should be used")
cmdAddAgentRoute.Example = `doctl genai agent route add --parent-agent-id "12345678-1234-1234-1234-123456789012" --child-agent-id "12345678-1234-1234-1234-123456789013"`

cmdUpdateAgentRoute := CmdBuilder(
cmd,
RunAgentRouteUpdate,
"update",
"Updates an agent route to an agent",
"Use this command to updates an agent route to an agent.The command requires values for the "+"`"+"--parent-agent-id"+"` and "+"`"+"--child-agent-id"+"`"+" flags.",
Writer,
aliasOpt("u"),
displayerType(&displayers.AgentRoute{}),
)
AddStringFlag(cmdUpdateAgentRoute, doctl.ArgParentAgentId, "", "", "Parent agent ID (required)", requiredOpt())
AddStringFlag(cmdUpdateAgentRoute, doctl.ArgChildAgentId, "", "", "Child agent ID (required)", requiredOpt())
AddStringFlag(cmdUpdateAgentRoute, doctl.ArgAgentRouteId, "", "", "Unique id of linkage")
AddStringFlag(cmdUpdateAgentRoute, doctl.ArgAgentRouteName, "", "", "Route name")
AddStringFlag(cmdUpdateAgentRoute, doctl.ArgAgentRouteIfCase, "", "", "Describes the case in which the child agent should be used")
cmdUpdateAgentRoute.Example = `doctl genai agent route update --parent-agent-id "12345678-1234-1234-1234-123456789012" --child-agent-id "12345678-1234-1234-1234-123456789013" --route-name "test_route" --if-case "use this to get test information"`

cmdDeleteAgentRoute := CmdBuilder(
cmd,
RunAgentRouteDelete,
"delete",
"Deletes an agent route to an agent",
"Use this command to delete an agent route to an agent. The command requires values for the "+"`"+"--parent-agent-id"+"` and "+"`"+"--child-agent-id"+"`"+" flags.",
Writer,
aliasOpt("d", "del", "rm"),
)
AddStringFlag(cmdDeleteAgentRoute, doctl.ArgParentAgentId, "", "", "Parent agent ID (required)", requiredOpt())
AddStringFlag(cmdDeleteAgentRoute, doctl.ArgChildAgentId, "", "", "Child agent ID (required)", requiredOpt())
AddBoolFlag(cmdDeleteAgentRoute, doctl.ArgForce, doctl.ArgShortForce, false, "Force route deletion without confirmation")
cmdDeleteAgentRoute.Example = `doctl genai agent route delete --parent-agent-id "12345678-1234-1234-1234-123456789012" --child-agent-id "12345678-1234-1234-1234-123456789013"`

return cmd
}

// RunAgentRouteAdd adds a route to an agent.
func RunAgentRouteAdd(c *CmdConfig) error {
parentAgentID, err := c.Doit.GetString(c.NS, doctl.ArgParentAgentId)
if err != nil {
return err
}

childAgentID, err := c.Doit.GetString(c.NS, doctl.ArgChildAgentId)
if err != nil {
return err
}

routeResponse, err := c.GenAI().AddAgentRoute(parentAgentID, childAgentID)
if err != nil {
return err
}

return c.Display(&displayers.AgentRoute{AgentRouteResponses: []do.AgentRouteResponse{*routeResponse}})
}

// RunAgentRouteUpdate updates a route to an agent.
func RunAgentRouteUpdate(c *CmdConfig) error {
parentAgentID, err := c.Doit.GetString(c.NS, doctl.ArgParentAgentId)
if err != nil {
return err
}

childAgentID, err := c.Doit.GetString(c.NS, doctl.ArgChildAgentId)
if err != nil {
return err
}

routeUUID, _ := c.Doit.GetString(c.NS, doctl.ArgAgentRouteId)
routeName, _ := c.Doit.GetString(c.NS, doctl.ArgAgentRouteName)
ifCase, _ := c.Doit.GetString(c.NS, doctl.ArgAgentRouteIfCase)

req := &godo.AgentRouteUpdateRequest{
ChildAgentUuid: childAgentID,
IfCase: ifCase,
ParentAgentUuid: parentAgentID,
RouteName: routeName,
UUID: routeUUID,
}

routeResponse, err := c.GenAI().UpdateAgentRoute(parentAgentID, childAgentID, req)
if err != nil {
return err
}

return c.Display(&displayers.AgentRoute{AgentRouteResponses: []do.AgentRouteResponse{*routeResponse}})
}

// RunAgentRouteDelete deletes a route to an agent.
func RunAgentRouteDelete(c *CmdConfig) error {
parentAgentID, err := c.Doit.GetString(c.NS, doctl.ArgParentAgentId)
if err != nil {
return err
}

childAgentID, err := c.Doit.GetString(c.NS, doctl.ArgChildAgentId)
if err != nil {
return err
}

force, err := c.Doit.GetBool(c.NS, doctl.ArgForce)
if err != nil {
return err
}

if force || AskForConfirmDelete("Agent Route", 1) == nil {
err := c.GenAI().DeleteAgentRoute(parentAgentID, childAgentID)
if err != nil {
return err
}
notice("Agent route deleted successfully")
return nil
}

return c.GenAI().DeleteAgentRoute(parentAgentID, childAgentID)
}
79 changes: 79 additions & 0 deletions commands/genai_agent_route_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package commands

import (
"testing"

"github.com/digitalocean/doctl"
"github.com/digitalocean/doctl/do"
"github.com/digitalocean/godo"
"github.com/stretchr/testify/assert"
)

var (
testParentAgentID = "12345678-1234-1234-1234-123456789012"
testChildAgentID = "12345678-1234-1234-1234-123456789013"
testRouteUUID = "12345678-1234-1234-1234-123456789014"

testAgentRouteResponse = &do.AgentRouteResponse{
AgentRouteResponse: &godo.AgentRouteResponse{
ParentAgentUuid: testParentAgentID,
ChildAgentUuid: testChildAgentID,
UUID: testRouteUUID,
Rollback: false,
},
}
)

func TestAgentRouteAdd(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
tm.genAI.EXPECT().AddAgentRoute(testParentAgentID, testChildAgentID).Return(testAgentRouteResponse, nil)

config.Args = []string{}
config.Doit.Set(config.NS, doctl.ArgParentAgentId, testParentAgentID)
config.Doit.Set(config.NS, doctl.ArgChildAgentId, testChildAgentID)
config.Doit.Set(config.NS, doctl.ArgAgentRouteId, testRouteUUID)
config.Doit.Set(config.NS, doctl.ArgAgentRouteName, "test_route")
config.Doit.Set(config.NS, doctl.ArgAgentRouteIfCase, "test if case")

err := RunAgentRouteAdd(config)
assert.NoError(t, err)
})
}

func TestAgentRouteUpdate(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
expectedReq := &godo.AgentRouteUpdateRequest{
ParentAgentUuid: testParentAgentID,
ChildAgentUuid: testChildAgentID,
UUID: testRouteUUID,
RouteName: "test_route",
IfCase: "test if case",
}

tm.genAI.EXPECT().UpdateAgentRoute(testParentAgentID, testChildAgentID, expectedReq).Return(testAgentRouteResponse, nil)

config.Args = []string{}
config.Doit.Set(config.NS, doctl.ArgParentAgentId, testParentAgentID)
config.Doit.Set(config.NS, doctl.ArgChildAgentId, testChildAgentID)
config.Doit.Set(config.NS, doctl.ArgAgentRouteId, testRouteUUID)
config.Doit.Set(config.NS, doctl.ArgAgentRouteName, "test_route")
config.Doit.Set(config.NS, doctl.ArgAgentRouteIfCase, "test if case")

err := RunAgentRouteUpdate(config)
assert.NoError(t, err)
})
}

func TestAgentRouteDelete(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
tm.genAI.EXPECT().DeleteAgentRoute(testParentAgentID, testChildAgentID).Return(nil)

config.Args = []string{}
config.Doit.Set(config.NS, doctl.ArgParentAgentId, testParentAgentID)
config.Doit.Set(config.NS, doctl.ArgChildAgentId, testChildAgentID)
config.Doit.Set(config.NS, doctl.ArgForce, true)

err := RunAgentRouteDelete(config)
assert.NoError(t, err)
})
}
2 changes: 1 addition & 1 deletion commands/genai_knowledge_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func KnowledgeBaseCmd() *Command {
RunKnowledgeBaseCreate,
"create",
"Creates a knowledge base",
"Creates a knowledge base and returns the following information \n"+knowledgebaseDetails+" \nFor more information about datasources, see the [datasources reference](https://docs.digitalocean.com/reference/api/digitalocean/#tag/GenAI-Platform-(Public-Preview)/operation/genai_create_knowledge_base)\n",
"Creates a knowledge base and returns the following information \n"+knowledgebaseDetails+" \nFor more information about datasources, see the [datasources reference](https://docs.digitalocean.com/reference/api/digitalocean/#tag/GradientAI-Platform/operation/genai_create_knowledge_base)\n",
Writer, aliasOpt("c"),
displayerType(&displayers.KnowledgeBase{}),
)
Expand Down
34 changes: 34 additions & 0 deletions do/genai.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type KnowledgeBaseDataSource struct {
*godo.KnowledgeBaseDataSource
}

type AgentRouteResponse struct {
*godo.AgentRouteResponse
}

// Agents is a slice of Agent.
type Agents []Agent

Expand Down Expand Up @@ -59,6 +63,9 @@ type GenAIService interface {
DeleteKnowledgeBaseDataSource(knowledgeBaseID string, dataSourceID string) error
AttachKnowledgeBaseToAgent(agentId string, knowledgeBaseID string) (*Agent, error)
DetachKnowledgeBaseToAgent(agentId string, knowledgeBaseID string) (*Agent, error)
AddAgentRoute(parentAgentID string, childAgentID string) (*AgentRouteResponse, error)
UpdateAgentRoute(parentAgentID string, childAgentID string, req *godo.AgentRouteUpdateRequest) (*AgentRouteResponse, error)
DeleteAgentRoute(parentAgentID string, childAgentID string) error
}

var _ GenAIService = &genAIService{}
Expand Down Expand Up @@ -255,3 +262,30 @@ func (a *genAIService) DetachKnowledgeBaseToAgent(agentId string, knowledgeBaseI
}
return &Agent{Agent: agent}, nil
}

func (a *genAIService) AddAgentRoute(parentAgentID string, childAgentID string) (*AgentRouteResponse, error) {
// Create the request object
req := &godo.AgentRouteCreateRequest{
ParentAgentUuid: parentAgentID,
ChildAgentUuid: childAgentID,
}

routeResponse, _, err := a.client.GenAI.AddAgentRoute(context.TODO(), parentAgentID, childAgentID, req)
if err != nil {
return nil, err
}
return &AgentRouteResponse{AgentRouteResponse: routeResponse}, nil
}

func (a *genAIService) UpdateAgentRoute(parentAgentID string, childAgentID string, req *godo.AgentRouteUpdateRequest) (*AgentRouteResponse, error) {
routeResponse, _, err := a.client.GenAI.UpdateAgentRoute(context.TODO(), parentAgentID, childAgentID, req)
if err != nil {
return nil, err
}
return &AgentRouteResponse{AgentRouteResponse: routeResponse}, nil
}

func (a *genAIService) DeleteAgentRoute(parentAgentID string, childAgentID string) error {
_, _, err := a.client.GenAI.DeleteAgentRoute(context.TODO(), parentAgentID, childAgentID)
return err
}
Loading
Loading