Documentation
¶
Index ¶
- Constants
- Variables
- func HasPermission(granted []string, required string) bool
- type Bot
- type BotCheck
- type ConnectorLifecycle
- type ContainerLifecycle
- type CreateBotRequest
- type CreateUserGrantRequest
- type ListBotsResponse
- type ListChecksResponse
- type NameAvailability
- type RuntimeChecker
- type Service
- func (s *Service) AddRuntimeChecker(c RuntimeChecker)
- func (s *Service) AuthorizeAccess(ctx context.Context, userID, botID string, isAdmin bool) (Bot, error)
- func (s *Service) AuthorizeAccessWithPermission(ctx context.Context, userID, botID string, isAdmin bool, required string) (Bot, error)
- func (s *Service) CheckNameAvailability(ctx context.Context, name, excludeBotID string) (NameAvailability, error)
- func (s *Service) ClearContainerSetupFailure(ctx context.Context, botID string) error
- func (s *Service) Create(ctx context.Context, ownerUserID string, req CreateBotRequest) (Bot, error)
- func (s *Service) CreateUserGrant(ctx context.Context, botID, createdByUserID string, req CreateUserGrantRequest) (UserGrant, error)
- func (s *Service) Delete(ctx context.Context, botID string) error
- func (s *Service) DeleteUserGrant(ctx context.Context, botID, grantID string) error
- func (s *Service) Get(ctx context.Context, identifier string) (Bot, error)
- func (s *Service) GetForAccess(ctx context.Context, identifier string) (Bot, error)
- func (s *Service) ListAccessible(ctx context.Context, channelIdentityID string) ([]Bot, error)
- func (s *Service) ListByOwner(ctx context.Context, ownerUserID string) ([]Bot, error)
- func (s *Service) ListChecks(ctx context.Context, botID string) ([]BotCheck, error)
- func (s *Service) ListUserGrants(ctx context.Context, botID string) ([]UserGrant, error)
- func (s *Service) MarkReady(ctx context.Context, botID string) (Bot, error)
- func (s *Service) PublishRuntimeConfig(ctx context.Context, botID string, publish func(context.Context) error) error
- func (s *Service) RecordContainerSetupFailure(ctx context.Context, botID, phase string, setupErr error) error
- func (s *Service) ResolveUserPermissions(ctx context.Context, botID, userID string, isAdmin bool) ([]string, error)
- func (s *Service) ResolveUserPermissionsForBot(ctx context.Context, bot Bot, userID string, isAdmin bool) ([]string, error)
- func (s *Service) SetConnectorLifecycle(lc ConnectorLifecycle)
- func (s *Service) SetContainerLifecycle(lc ContainerLifecycle)
- func (s *Service) SetContainerReachability(fn func(ctx context.Context, botID string) error)
- func (s *Service) TransferOwner(ctx context.Context, botID string, ownerUserID string) (Bot, error)
- func (s *Service) Update(ctx context.Context, botID string, req UpdateBotRequest) (Bot, error)
- func (s *Service) UpdateReplacingMetadata(ctx context.Context, botID string, req UpdateBotRequest) (Bot, error)
- func (s *Service) UpdateUserGrant(ctx context.Context, botID, grantID string, req UpdateUserGrantRequest) (UserGrant, error)
- func (s *Service) ValidateUpdate(ctx context.Context, botID string, req UpdateBotRequest) error
- type TransferBotRequest
- type UpdateBotRequest
- type UpdateUserGrantRequest
- type UserGrant
Constants ¶
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.
const ( GrantSubjectUser = "user" GrantSubjectEveryone = "everyone" )
Grant subject types.
const ( NameReasonInvalid = "invalid" NameReasonReserved = "reserved" NameReasonTaken = "taken" )
reasons returned by ValidateName / CheckNameAvailability.
const ( BotStatusCreating = "creating" BotStatusReady = "ready" BotStatusDeleting = "deleting" )
const ( BotCheckStateOK = "ok" BotCheckStateIssue = "issue" BotCheckStateUnknown = "unknown" )
const ( BotCheckStatusOK = "ok" BotCheckStatusWarn = "warn" BotCheckStatusError = "error" BotCheckStatusUnknown = "unknown" )
const ( BotCheckTypeContainerInit = "container.init" BotCheckTypeContainerRecord = "container.record" BotCheckTypeContainerTask = "container.task" BotCheckTypeContainerData = "container.data_path" BotCheckTypeDelete = "bot.delete" BotCheckTypeMCPConnection = "mcp.connection" BotCheckTypeChannelConn = "channel.connection" )
Variables ¶
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") )
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 ¶
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 ¶
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 ¶
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 ¶
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) DeleteUserGrant ¶
DeleteUserGrant removes a grant from a bot.
func (*Service) Get ¶
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 ¶
GetForAccess returns a bot row for hot authorization paths without attaching runtime check summaries.
func (*Service) ListAccessible ¶
ListAccessible returns all bots owned by the user.
func (*Service) ListByOwner ¶
ListByOwner returns bots owned by the given user.
func (*Service) ListChecks ¶
ListChecks evaluates runtime resource checks for a bot.
func (*Service) ListUserGrants ¶
ListUserGrants returns all workspace user access grants for a bot, with the owner prepended as an implicit full-access entry.
func (*Service) MarkReady ¶
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 ¶
SetContainerReachability registers a function that checks whether a bot's container is reachable via gRPC. Returns nil on success, error otherwise.
func (*Service) TransferOwner ¶
TransferOwner transfers bot ownership to another user.
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 ¶
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.