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
6 changes: 5 additions & 1 deletion internal/server/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func toProtoComputeResources(resources store.ComputeResources) *agentsv1.Compute
}

func toProtoAgent(agent store.Agent) *agentsv1.Agent {
return &agentsv1.Agent{
protoAgent := &agentsv1.Agent{
Meta: toProtoEntityMeta(agent.Meta),
OrganizationId: agent.OrganizationID.String(),
Name: agent.Name,
Expand All @@ -36,6 +36,10 @@ func toProtoAgent(agent store.Agent) *agentsv1.Agent {
InitImage: agent.InitImage,
Resources: toProtoComputeResources(agent.Resources),
}
if agent.IdleTimeout != nil {
protoAgent.IdleTimeout = agent.IdleTimeout
}
return protoAgent
}

func toProtoVolume(volume store.Volume) *agentsv1.Volume {
Expand Down
37 changes: 35 additions & 2 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"regexp"
"time"

agentsv1 "github.com/agynio/agents/.gen/go/agynio/api/agents/v1"
identityv1 "github.com/agynio/agents/.gen/go/agynio/api/identity/v1"
Expand All @@ -21,7 +22,10 @@ type Server struct {
identity IdentityWriter
}

const maxMcpNameLength = 63
const (
maxMcpNameLength = 63
defaultIdleTimeout = "5m"
)

var mcpNamePattern = regexp.MustCompile(`^[a-z][a-z0-9_]{0,62}$`)

Expand Down Expand Up @@ -58,6 +62,13 @@ func (s *Server) CreateAgent(ctx context.Context, req *agentsv1.CreateAgentReque
if req.GetInitImage() == "" {
return nil, status.Error(codes.InvalidArgument, "init_image is required")
}
idleTimeout := defaultIdleTimeout
if req.IdleTimeout != nil {
idleTimeout = req.GetIdleTimeout()
}
if err := validateDurationString(idleTimeout); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "idle_timeout: %v", err)
}
resources := toStoreComputeResources(req.GetResources())
agent, err := s.store.CreateAgent(ctx, organizationID, store.AgentInput{
Name: req.GetName(),
Expand All @@ -67,6 +78,7 @@ func (s *Server) CreateAgent(ctx context.Context, req *agentsv1.CreateAgentReque
Configuration: req.GetConfiguration(),
Image: req.GetImage(),
InitImage: req.GetInitImage(),
IdleTimeout: &idleTimeout,
Resources: resources,
})
if err != nil {
Expand Down Expand Up @@ -109,7 +121,7 @@ func (s *Server) UpdateAgent(ctx context.Context, req *agentsv1.UpdateAgentReque
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "id: %v", err)
}
if req.Name == nil && req.Role == nil && req.Model == nil && req.Description == nil && req.Configuration == nil && req.Image == nil && req.InitImage == nil && req.Resources == nil {
if req.Name == nil && req.Role == nil && req.Model == nil && req.Description == nil && req.Configuration == nil && req.Image == nil && req.InitImage == nil && req.IdleTimeout == nil && req.Resources == nil {
return nil, status.Error(codes.InvalidArgument, "at least one field must be provided")
}
if req.InitImage != nil && req.GetInitImage() == "" {
Expand Down Expand Up @@ -148,6 +160,13 @@ func (s *Server) UpdateAgent(ctx context.Context, req *agentsv1.UpdateAgentReque
value := req.GetInitImage()
update.InitImage = &value
}
if req.IdleTimeout != nil {
value := req.GetIdleTimeout()
if err := validateDurationString(value); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "idle_timeout: %v", err)
}
update.IdleTimeout = &value
}
if req.Resources != nil {
resources := toStoreComputeResources(req.GetResources())
update.Resources = &resources
Expand Down Expand Up @@ -1152,6 +1171,20 @@ func validateMcpName(name string) error {
return nil
}

func validateDurationString(value string) error {
if value == "" {
return fmt.Errorf("value is empty")
}
duration, err := time.ParseDuration(value)
if err != nil {
return err
Comment thread
noa-lucent marked this conversation as resolved.
}
if duration <= 0 {
return fmt.Errorf("must be a positive duration")
}
return nil
}

func toStoreComputeResources(resources *agentsv1.ComputeResources) store.ComputeResources {
if resources == nil {
return store.ComputeResources{}
Expand Down
13 changes: 10 additions & 3 deletions internal/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

const (
agentColumns = `id, organization_id, name, role, model, description, configuration, image, init_image, resources_requests_cpu, resources_requests_memory, resources_limits_cpu, resources_limits_memory, created_at, updated_at`
agentColumns = `id, organization_id, name, role, model, description, configuration, image, init_image, idle_timeout, resources_requests_cpu, resources_requests_memory, resources_limits_cpu, resources_limits_memory, created_at, updated_at`
volumeColumns = `id, organization_id, persistent, mount_path, size, description, created_at, updated_at`
volumeAttachmentColumns = `id, volume_id, agent_id, mcp_id, hook_id, created_at, updated_at`
imagePullSecretAttachmentColumns = `id, image_pull_secret_id, agent_id, mcp_id, hook_id, created_at, updated_at`
Expand Down Expand Up @@ -50,6 +50,7 @@ func stringPtrFromPg(value pgtype.Text) *string {

func scanAgent(row pgx.Row) (Agent, error) {
var agent Agent
var idleTimeout pgtype.Text
if err := row.Scan(
&agent.Meta.ID,
&agent.OrganizationID,
Expand All @@ -60,6 +61,7 @@ func scanAgent(row pgx.Row) (Agent, error) {
&agent.Configuration,
&agent.Image,
&agent.InitImage,
&idleTimeout,
&agent.Resources.RequestsCPU,
&agent.Resources.RequestsMemory,
&agent.Resources.LimitsCPU,
Expand All @@ -69,6 +71,7 @@ func scanAgent(row pgx.Row) (Agent, error) {
); err != nil {
return Agent{}, err
}
agent.IdleTimeout = stringPtrFromPg(idleTimeout)
return agent, nil
}

Expand Down Expand Up @@ -245,8 +248,8 @@ func scanInitScript(row pgx.Row) (InitScript, error) {

func (s *Store) CreateAgent(ctx context.Context, organizationID uuid.UUID, input AgentInput) (Agent, error) {
row := s.pool.QueryRow(ctx,
fmt.Sprintf(`INSERT INTO agents (organization_id, name, role, model, description, configuration, image, init_image, resources_requests_cpu, resources_requests_memory, resources_limits_cpu, resources_limits_memory)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
fmt.Sprintf(`INSERT INTO agents (organization_id, name, role, model, description, configuration, image, init_image, idle_timeout, resources_requests_cpu, resources_requests_memory, resources_limits_cpu, resources_limits_memory)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
RETURNING %s`, agentColumns),
organizationID,
input.Name,
Expand All @@ -256,6 +259,7 @@ func (s *Store) CreateAgent(ctx context.Context, organizationID uuid.UUID, input
input.Configuration,
input.Image,
input.InitImage,
input.IdleTimeout,
input.Resources.RequestsCPU,
input.Resources.RequestsMemory,
input.Resources.LimitsCPU,
Expand Down Expand Up @@ -306,6 +310,9 @@ func (s *Store) UpdateAgent(ctx context.Context, id uuid.UUID, update AgentUpdat
if update.InitImage != nil {
builder.add("init_image", *update.InitImage)
}
if update.IdleTimeout != nil {
builder.add("idle_timeout", *update.IdleTimeout)
}
if update.Resources != nil {
builder.add("resources_requests_cpu", update.Resources.RequestsCPU)
builder.add("resources_requests_memory", update.Resources.RequestsMemory)
Expand Down
3 changes: 3 additions & 0 deletions internal/store/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Agent struct {
Configuration string
Image string
InitImage string
IdleTimeout *string
Resources ComputeResources
}

Expand Down Expand Up @@ -113,6 +114,7 @@ type AgentInput struct {
Configuration string
Image string
InitImage string
IdleTimeout *string
Resources ComputeResources
}

Expand All @@ -124,6 +126,7 @@ type AgentUpdate struct {
Configuration *string
Image *string
InitImage *string
IdleTimeout *string
Resources *ComputeResources
}

Expand Down
2 changes: 2 additions & 0 deletions migrations/0010_add_idle_timeout.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE agents
ADD COLUMN idle_timeout TEXT;
Loading