bots

package
v0.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PermissionChat           = "chat"
	PermissionWorkspaceRead  = "workspace_read"
	PermissionWorkspaceWrite = "workspace_write"
	PermissionWorkspaceExec  = "workspace_exec"
	PermissionManage         = "manage"
)

Grant permission scopes. manage implies every scoped permission; workspace_write implies workspace_read.

View Source
const (
	GrantSubjectUser     = "user"
	GrantSubjectEveryone = "everyone"
)

Grant subject types.

View Source
const (
	NameReasonInvalid  = "invalid"
	NameReasonReserved = "reserved"
	NameReasonTaken    = "taken"
)

reasons returned by ValidateName / CheckNameAvailability.

View Source
const (
	BotStatusCreating = "creating"
	BotStatusReady    = "ready"
	BotStatusDeleting = "deleting"
)
View Source
const (
	BotCheckStateOK      = "ok"
	BotCheckStateIssue   = "issue"
	BotCheckStateUnknown = "unknown"
)
View Source
const (
	BotCheckStatusOK      = "ok"
	BotCheckStatusWarn    = "warn"
	BotCheckStatusError   = "error"
	BotCheckStatusUnknown = "unknown"
)
View Source
const (
	BotCheckTypeContainerInit   = "container.init"
	BotCheckTypeContainerRecord = "container.record"
	BotCheckTypeContainerTask   = "container.task"
	BotCheckTypeContainerData   = "container.data_path"
	BotCheckTypeDelete          = "bot.delete"
	BotCheckTypeMCPConnection   = "mcp.connection"
	BotCheckTypeChannelConn     = "channel.connection"
)

Variables

View Source
var (
	// ErrGrantNotFound indicates the grant does not exist for the bot.
	ErrGrantNotFound = errors.New("bot user grant not found")
	// ErrInvalidPermission indicates an unknown or empty permission set.
	ErrInvalidPermission = errors.New("invalid permission")
	// ErrInvalidGrantSubject indicates an unknown subject type.
	ErrInvalidGrantSubject = errors.New("invalid grant subject")
	// ErrGrantUserRequired indicates a user grant is missing its user id.
	ErrGrantUserRequired = errors.New("user id is required for a user grant")
	// ErrGrantOwnerConflict indicates an attempt to grant access to the bot owner.
	ErrGrantOwnerConflict = errors.New("the bot owner already has full access")
	// ErrGrantExists indicates a grant for the subject already exists.
	ErrGrantExists = errors.New("a grant for this subject already exists")
)
View Source
var (
	ErrBotNotFound       = errors.New("bot not found")
	ErrBotAccessDenied   = errors.New("bot access denied")
	ErrOwnerUserNotFound = errors.New("owner user not found")
	ErrBotNameTaken      = errors.New("bot name already taken")
	ErrBotNameInvalid    = errors.New("bot name is invalid")
	ErrBotNameReserved   = errors.New("bot name is reserved")
)

Functions

func HasPermission

func HasPermission(granted []string, required string) bool

HasPermission reports whether the granted set satisfies the required scope.

Types

type Bot

type Bot struct {
	ID              string `json:"id"`
	OwnerUserID     string `json:"owner_user_id"`
	Name            string `json:"name"`
	DisplayName     string `json:"display_name"`
	AvatarURL       string `json:"avatar_url,omitempty"`
	Timezone        string `json:"timezone,omitempty"`
	IsActive        bool   `json:"is_active"`
	Status          string `json:"status"`
	CheckState      string `json:"check_state"`
	CheckIssueCount int32  `json:"check_issue_count"`
	// CurrentUserPermissions lists the effective access permissions of the
	// requesting user on this bot (e.g. "chat", "manage"). It is populated by
	// the API layer per request and is not persisted.
	CurrentUserPermissions []string       `json:"current_user_permissions,omitempty"`
	Metadata               map[string]any `json:"metadata,omitempty"`
	CreatedAt              time.Time      `json:"created_at"`
	UpdatedAt              time.Time      `json:"updated_at"`
}

Bot represents a bot entity.

type BotCheck

type BotCheck struct {
	ID       string         `json:"id"`
	Type     string         `json:"type"`
	TitleKey string         `json:"title_key"`
	Subtitle string         `json:"subtitle,omitempty"`
	Status   string         `json:"status"`
	Summary  string         `json:"summary"`
	Detail   string         `json:"detail,omitempty"`
	Metadata map[string]any `json:"metadata,omitempty"`
}

BotCheck represents one resource check row for a bot.

type ConnectorLifecycle

type ConnectorLifecycle interface {
	CleanupBotConnectors(ctx context.Context, botID string) error
}

ConnectorLifecycle removes external connector credentials before the local bot row and its bindings are deleted.

type ContainerLifecycle

type ContainerLifecycle interface {
	SetupBotContainer(ctx context.Context, botID string) error
	CleanupBotContainer(ctx context.Context, botID string, preserveData bool) error
}

ContainerLifecycle handles container lifecycle events bound to bot operations.

type CreateBotRequest

type CreateBotRequest struct {
	Name          string         `json:"name,omitempty"`
	DisplayName   string         `json:"display_name,omitempty"`
	AvatarURL     string         `json:"avatar_url,omitempty"`
	Timezone      *string        `json:"timezone,omitempty"`
	IsActive      *bool          `json:"is_active,omitempty"`
	AclPreset     string         `json:"acl_preset,omitempty"`
	Metadata      map[string]any `json:"metadata,omitempty"`
	WaitForReady  bool           `json:"wait_for_ready,omitempty"`
	SkipLifecycle bool           `json:"-"`
}

CreateBotRequest is the input for creating a bot.

type CreateUserGrantRequest

type CreateUserGrantRequest struct {
	SubjectType string   `json:"subject_type"`
	UserID      string   `json:"user_id,omitempty"`
	Permissions []string `json:"permissions"`
}

CreateUserGrantRequest is the input for adding a user access grant.

type ListBotsResponse

type ListBotsResponse struct {
	Items []Bot `json:"items"`
}

ListBotsResponse wraps a list of bots.

type ListChecksResponse

type ListChecksResponse struct {
	Items []BotCheck `json:"items"`
}

ListChecksResponse wraps a list of bot checks.

type NameAvailability

type NameAvailability struct {
	Available bool   `json:"available"`
	Reason    string `json:"reason,omitempty"`
}

NameAvailability describes whether a bot name can be used.

type RuntimeChecker

type RuntimeChecker interface {
	// ListChecks evaluates dynamic runtime checks for a bot.
	ListChecks(ctx context.Context, botID string) []BotCheck
}

RuntimeChecker produces runtime check items for a bot.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides bot CRUD and membership management.

func NewService

func NewService(log *slog.Logger, queries dbstore.Queries) *Service

NewService creates a new bot service.

func (*Service) AddRuntimeChecker

func (s *Service) AddRuntimeChecker(c RuntimeChecker)

AddRuntimeChecker registers an additional runtime checker.

func (*Service) AuthorizeAccess

func (s *Service) AuthorizeAccess(ctx context.Context, userID, botID string, isAdmin bool) (Bot, error)

AuthorizeAccess checks whether userID may access the given bot (owner or admin only).

func (*Service) AuthorizeAccessWithPermission

func (s *Service) AuthorizeAccessWithPermission(ctx context.Context, userID, botID string, isAdmin bool, required string) (Bot, error)

AuthorizeAccessWithPermission checks whether userID may access the bot with the required permission scope (owner, admin, or a matching grant).

func (*Service) CheckNameAvailability

func (s *Service) CheckNameAvailability(ctx context.Context, name, excludeBotID string) (NameAvailability, error)

CheckNameAvailability validates a candidate name and reports whether it can be used for a new bot. excludeBotID, when non-empty, allows the bot currently owning the name (e.g. during rename) to be ignored.

func (*Service) ClearContainerSetupFailure

func (s *Service) ClearContainerSetupFailure(ctx context.Context, botID string) error

ClearContainerSetupFailure removes stale setup failure diagnostics after a successful workspace setup or manual workspace creation.

func (*Service) Create

func (s *Service) Create(ctx context.Context, ownerUserID string, req CreateBotRequest) (Bot, error)

Create creates a new bot owned by owner user.

func (*Service) CreateUserGrant

func (s *Service) CreateUserGrant(ctx context.Context, botID, createdByUserID string, req CreateUserGrantRequest) (UserGrant, error)

CreateUserGrant adds a new workspace user (or everyone) access grant.

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, botID string) error

Delete removes a bot and its associated resources.

func (*Service) DeleteUserGrant

func (s *Service) DeleteUserGrant(ctx context.Context, botID, grantID string) error

DeleteUserGrant removes a grant from a bot.

func (*Service) Get

func (s *Service) Get(ctx context.Context, identifier string) (Bot, error)

Get returns a bot by its identifier, which may be either a UUID or a name slug. This allows name-oriented URLs (/bot/:name) to resolve through the same path as UUID-based lookups.

func (*Service) GetForAccess

func (s *Service) GetForAccess(ctx context.Context, identifier string) (Bot, error)

GetForAccess returns a bot row for hot authorization paths without attaching runtime check summaries.

func (*Service) ListAccessible

func (s *Service) ListAccessible(ctx context.Context, channelIdentityID string) ([]Bot, error)

ListAccessible returns all bots owned by the user.

func (*Service) ListByOwner

func (s *Service) ListByOwner(ctx context.Context, ownerUserID string) ([]Bot, error)

ListByOwner returns bots owned by the given user.

func (*Service) ListChecks

func (s *Service) ListChecks(ctx context.Context, botID string) ([]BotCheck, error)

ListChecks evaluates runtime resource checks for a bot.

func (*Service) ListUserGrants

func (s *Service) ListUserGrants(ctx context.Context, botID string) ([]UserGrant, error)

ListUserGrants returns all workspace user access grants for a bot, with the owner prepended as an implicit full-access entry.

func (*Service) MarkReady

func (s *Service) MarkReady(ctx context.Context, botID string) (Bot, error)

MarkReady marks a bot lifecycle transition as complete and returns the fresh row.

func (*Service) PublishRuntimeConfig

func (s *Service) PublishRuntimeConfig(ctx context.Context, botID string, publish func(context.Context) error) error

PublishRuntimeConfig invalidates the old runtime epoch before publishing bot-scoped workspace files, then holds the reset parent lock for the whole external write. Callers must first acquire a bot-scoped reset lease.

func (*Service) RecordContainerSetupFailure

func (s *Service) RecordContainerSetupFailure(ctx context.Context, botID, phase string, setupErr error) error

RecordContainerSetupFailure persists a sanitized workspace setup failure so runtime diagnostics can explain why a ready bot is unhealthy.

func (*Service) ResolveUserPermissions

func (s *Service) ResolveUserPermissions(ctx context.Context, botID, userID string, isAdmin bool) ([]string, error)

ResolveUserPermissions returns the effective permissions for userID on botID. Owners and admins always receive the full permission set; other users receive the union of their direct grant and any everyone grant.

func (*Service) ResolveUserPermissionsForBot

func (s *Service) ResolveUserPermissionsForBot(ctx context.Context, bot Bot, userID string, isAdmin bool) ([]string, error)

ResolveUserPermissionsForBot resolves permissions using an already-loaded bot row. Hot read paths use this to avoid loading the same bot twice.

func (*Service) SetConnectorLifecycle

func (s *Service) SetConnectorLifecycle(lc ConnectorLifecycle)

SetConnectorLifecycle registers connector cleanup for bot deletion.

func (*Service) SetContainerLifecycle

func (s *Service) SetContainerLifecycle(lc ContainerLifecycle)

SetContainerLifecycle registers a container lifecycle handler for bot operations.

func (*Service) SetContainerReachability

func (s *Service) SetContainerReachability(fn func(ctx context.Context, botID string) error)

SetContainerReachability registers a function that checks whether a bot's container is reachable via gRPC. Returns nil on success, error otherwise.

func (*Service) TransferOwner

func (s *Service) TransferOwner(ctx context.Context, botID string, ownerUserID string) (Bot, error)

TransferOwner transfers bot ownership to another user.

func (*Service) Update

func (s *Service) Update(ctx context.Context, botID string, req UpdateBotRequest) (Bot, error)

Update updates bot profile fields.

func (*Service) UpdateReplacingMetadata

func (s *Service) UpdateReplacingMetadata(ctx context.Context, botID string, req UpdateBotRequest) (Bot, error)

UpdateReplacingMetadata updates bot profile fields and writes metadata exactly as supplied. It is intended for restore/import paths where scrubbed metadata must not preserve existing sensitive fields.

func (*Service) UpdateUserGrant

func (s *Service) UpdateUserGrant(ctx context.Context, botID, grantID string, req UpdateUserGrantRequest) (UserGrant, error)

UpdateUserGrant updates the permission set of an existing grant.

func (*Service) ValidateUpdate

func (s *Service) ValidateUpdate(ctx context.Context, botID string, req UpdateBotRequest) error

ValidateUpdate validates bot profile updates without persisting them.

type TransferBotRequest

type TransferBotRequest struct {
	OwnerUserID string `json:"owner_user_id"`
}

TransferBotRequest is the input for transferring bot ownership.

type UpdateBotRequest

type UpdateBotRequest struct {
	Name        *string        `json:"name,omitempty"`
	DisplayName *string        `json:"display_name,omitempty"`
	AvatarURL   *string        `json:"avatar_url,omitempty"`
	Timezone    *string        `json:"timezone,omitempty"`
	IsActive    *bool          `json:"is_active,omitempty"`
	Metadata    map[string]any `json:"metadata,omitempty"`
}

UpdateBotRequest is the input for updating a bot.

type UpdateUserGrantRequest

type UpdateUserGrantRequest struct {
	Permissions []string `json:"permissions"`
}

UpdateUserGrantRequest is the input for updating a grant's permissions.

type UserGrant

type UserGrant struct {
	ID              string    `json:"id"`
	BotID           string    `json:"bot_id"`
	SubjectType     string    `json:"subject_type"`
	UserID          string    `json:"user_id,omitempty"`
	UserUsername    string    `json:"user_username,omitempty"`
	UserDisplayName string    `json:"user_display_name,omitempty"`
	UserAvatarURL   string    `json:"user_avatar_url,omitempty"`
	Permissions     []string  `json:"permissions"`
	IsOwner         bool      `json:"is_owner,omitempty"`
	CreatedAt       time.Time `json:"created_at"`
	UpdatedAt       time.Time `json:"updated_at"`
}

UserGrant represents a workspace user (or everyone) access grant for a bot.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL