Documentation
¶
Index ¶
- Constants
- Variables
- func TokensPerSecond(outputTokens, latencyMs, ttftMs int) float64
- type APITokenRecord
- type APITokenStore
- func (s *APITokenStore) CleanupExpiredTokens(olderThan time.Duration) (int64, error)
- func (s *APITokenStore) Close() error
- func (s *APITokenStore) CreateTokenWithTokenID(userID, tokenID, displayName, createdBy string, expiresAt *time.Time) (*APITokenRecord, error)
- func (s *APITokenStore) DeleteToken(tokenID string) error
- func (s *APITokenStore) GetDB() *gorm.DB
- func (s *APITokenStore) GetToken(tokenID string) (*APITokenRecord, error)
- func (s *APITokenStore) ListTokens(userID string, enabled *bool, limit, offset int) ([]APITokenRecord, int64, error)
- func (s *APITokenStore) RevokeToken(tokenID, reason string) error
- func (s *APITokenStore) SetTokenEnabled(tokenID string, enabled bool) error
- func (s *APITokenStore) UpdateLastUsed(tokenID string) error
- func (s *APITokenStore) UpdateTokenString(tokenID, newTokenString string) error
- func (s *APITokenStore) ValidateToken(tokenID string) (*APITokenRecord, error)
- type AggregatedStat
- type BotAccessStore
- func (s *BotAccessStore) AddGroupActor(ctx context.Context, ...) (access.Actor, error)
- func (s *BotAccessStore) AnyCapabilityEnabled(ctx context.Context, botUUID string) (bool, error)
- func (s *BotAccessStore) CreateRoute(ctx context.Context, route access.Route, grantNotify bool) (access.Route, error)
- func (s *BotAccessStore) DeleteDirectChat(ctx context.Context, botUUID, id string) error
- func (s *BotAccessStore) DeleteGroup(ctx context.Context, botUUID, id string) error
- func (s *BotAccessStore) DeleteRoute(ctx context.Context, botUUID, id string) error
- func (s *BotAccessStore) DiscoverDirectChat(ctx context.Context, botUUID, platform, externalChatID string) (access.DirectChat, error)
- func (s *BotAccessStore) DiscoverGroup(ctx context.Context, botUUID, platform, externalGroupID, name string) (access.Group, error)
- func (s *BotAccessStore) GetCapability(ctx context.Context, botUUID string, name access.CapabilityName) (access.BotCapability, bool, error)
- func (s *BotAccessStore) GetDirectChat(ctx context.Context, botUUID, id string) (access.DirectChat, bool, error)
- func (s *BotAccessStore) GetGroup(ctx context.Context, botUUID, id string) (access.Group, bool, error)
- func (s *BotAccessStore) GetRoute(ctx context.Context, botUUID, id string) (access.Route, bool, error)
- func (s *BotAccessStore) ListCapabilities(ctx context.Context, botUUID string) ([]access.BotCapability, error)
- func (s *BotAccessStore) ListDirectChatPermissions(ctx context.Context, botUUID, id string) ([]access.Permission, error)
- func (s *BotAccessStore) ListDirectChats(ctx context.Context, botUUID string) ([]access.DirectChat, error)
- func (s *BotAccessStore) ListGroupActors(ctx context.Context, botUUID, groupID string) ([]access.GroupActor, error)
- func (s *BotAccessStore) ListGroupCapabilities(ctx context.Context, botUUID, id string) (map[access.CapabilityName]access.AccessEffect, error)
- func (s *BotAccessStore) ListGroups(ctx context.Context, botUUID string) ([]access.Group, error)
- func (s *BotAccessStore) ListRoutes(ctx context.Context, botUUID string) ([]access.Route, error)
- func (s *BotAccessStore) PairDirectChat(ctx context.Context, chatID, externalActorID, displayName string) error
- func (s *BotAccessStore) PutCapability(ctx context.Context, capability access.BotCapability) error
- func (s *BotAccessStore) RemoveGroupActor(ctx context.Context, botUUID, groupID, actorID string) error
- func (s *BotAccessStore) ResolveRoute(ctx context.Context, source, event string) (*access.ResolvedRoute, error)
- func (s *BotAccessStore) SetDirectChatBlocked(ctx context.Context, botUUID, id string, blocked bool) error
- func (s *BotAccessStore) SetDirectChatPermission(ctx context.Context, botUUID, id string, capability access.CapabilityName, ...) error
- func (s *BotAccessStore) SetDirectChatPermissions(ctx context.Context, botUUID, id string, perms []access.Permission) error
- func (s *BotAccessStore) SetGroupActorPermission(ctx context.Context, botUUID, groupID, actorID string, ...) error
- func (s *BotAccessStore) SetGroupBlocked(ctx context.Context, botUUID, id string, blocked bool) error
- func (s *BotAccessStore) SetGroupCapability(ctx context.Context, botUUID, id string, capability access.CapabilityName, ...) error
- func (s *BotAccessStore) SetTransportFactsSource(source access.TransportFactsSource)
- func (s *BotAccessStore) Snapshot(ctx context.Context, req access.AuthorizationRequest) (facts access.DecisionFacts, err error)
- func (s *BotAccessStore) UnpairDirectChat(ctx context.Context, botUUID, id string) error
- func (s *BotAccessStore) UpdateRoute(ctx context.Context, route access.Route, grantNotify bool) (access.Route, error)
- func (s *BotAccessStore) UpsertActor(ctx context.Context, actor access.Actor) (access.Actor, error)
- type HealthStatus
- type ImBotSettingsRecord
- type ImBotSettingsStore
- func (s *ImBotSettingsStore) CreateSettings(settings Settings) (Settings, error)
- func (s *ImBotSettingsStore) DeleteSettings(uuid string) error
- func (s *ImBotSettingsStore) GetSettingsByUUID(uuid string) (Settings, error)
- func (s *ImBotSettingsStore) ListEnabledSettings() ([]Settings, error)
- func (s *ImBotSettingsStore) ListSettings() ([]Settings, error)
- func (s *ImBotSettingsStore) SetEnabled(uuid string, enabled bool) error
- func (s *ImBotSettingsStore) ToggleSettings(uuid string) (bool, error)
- func (s *ImBotSettingsStore) UpdateSettings(uuid string, settings Settings) error
- type ModelSource
- type ModelStore
- func (s *ModelStore) Close() error
- func (ms *ModelStore) GetAllModelRecords() []ProviderModelRecord
- func (ms *ModelStore) GetAllProviders() []string
- func (ms *ModelStore) GetModelCount(providerUUID string) int
- func (ms *ModelStore) GetModels(providerUUID string, ttl time.Duration) []string
- func (ms *ModelStore) GetModelsBySource(providerUUID string, source ModelSource, ttl time.Duration) []string
- func (ms *ModelStore) GetProviderInfo(providerUUID string) (apiBase string, lastUpdated string, exists bool)
- func (ms *ModelStore) HasModels(providerUUID string) bool
- func (ms *ModelStore) RemoveProvider(providerUUID string) error
- func (ms *ModelStore) SaveModels(provider *typ.Provider, models []string, source ModelSource) error
- type PerformanceMetricSummary
- type PerformanceSummary
- type ProviderModelRecord
- type ProviderRecord
- type ProviderStore
- func (ps *ProviderStore) Close() error
- func (ps *ProviderStore) Count() (int64, error)
- func (ps *ProviderStore) Delete(uuid string) error
- func (ps *ProviderStore) Exists(uuid string) bool
- func (ps *ProviderStore) GetAccessToken(uuid string) (string, error)
- func (ps *ProviderStore) GetByName(name string) (*typ.Provider, error)
- func (ps *ProviderStore) GetByUUID(uuid string) (*typ.Provider, error)
- func (ps *ProviderStore) GetDB() *gorm.DB
- func (ps *ProviderStore) IsOAuthExpired(uuid string) (bool, error)
- func (ps *ProviderStore) List() ([]*typ.Provider, error)
- func (ps *ProviderStore) ListEnabled() ([]*typ.Provider, error)
- func (ps *ProviderStore) ListOAuth() ([]*typ.Provider, error)
- func (ps *ProviderStore) Save(provider *typ.Provider) error
- func (ps *ProviderStore) UpdateCredential(uuid string, token string, oauthDetail *typ.OAuthDetail) error
- func (ps *ProviderStore) UpdateCredentialBundle(uuid string, bundle *typ.CredentialBundle) error
- func (ps *ProviderStore) UpdateOAuthAccessToken(uuid, accessToken string) error
- type RemoteChatRecord
- type RemoteChatStore
- func (s *RemoteChatStore) AddToWhitelist(chatID, platform, addedBy string) error
- func (s *RemoteChatStore) BindProject(chatID, platform, projectPath, ownerID string) error
- func (s *RemoteChatStore) ClearPaired(chatID string) error
- func (s *RemoteChatStore) DeleteChat(chatID string) error
- func (s *RemoteChatStore) GetBashCwd(chatID string) (string, bool, error)
- func (s *RemoteChatStore) GetChat(chatID string) (*bot.Chat, error)
- func (s *RemoteChatStore) GetCurrentAgent(chatID string) (string, error)
- func (s *RemoteChatStore) GetOrCreateChat(chatID, platform string) (*bot.Chat, error)
- func (s *RemoteChatStore) GetProjectPath(chatID string) (string, bool, error)
- func (s *RemoteChatStore) ImportChat(chat *bot.Chat) error
- func (s *RemoteChatStore) IsChatDisabled(chatID string) bool
- func (s *RemoteChatStore) IsChatPaired(chatID, botUUID string) bool
- func (s *RemoteChatStore) IsWhitelisted(chatID string) bool
- func (s *RemoteChatStore) ListChatProjectPaths(chatID string) ([]string, error)
- func (s *RemoteChatStore) ListChats(platform string, includeDisabled bool) ([]*bot.Chat, error)
- func (s *RemoteChatStore) ListChatsByOwner(ownerID, platform string) ([]*bot.Chat, error)
- func (s *RemoteChatStore) RemoveFromWhitelist(chatID string) error
- func (s *RemoteChatStore) SetBashCwd(chatID, cwd string) error
- func (s *RemoteChatStore) SetChatDisabled(chatID string, disabled bool) error
- func (s *RemoteChatStore) SetCurrentAgent(chatID, platform, agentType string) error
- func (s *RemoteChatStore) SetPaired(chatID, platform, botUUID, senderID string) error
- func (s *RemoteChatStore) UpdateChat(chatID string, fn func(*bot.Chat)) error
- func (s *RemoteChatStore) UpsertChat(chat *bot.Chat) error
- type RemoteSessionRecord
- type RemoteSessionStore
- func (s *RemoteSessionStore) AppendMessage(sessionID string, msg session.Message) error
- func (s *RemoteSessionStore) Delete(sessionID string) error
- func (s *RemoteSessionStore) FindByChatAgentProject(chatID, agent, project string) (*session.Session, error)
- func (s *RemoteSessionStore) Get(sessionID string) (*session.Session, error)
- func (s *RemoteSessionStore) Import(sess *session.Session) error
- func (s *RemoteSessionStore) List() []*session.Session
- func (s *RemoteSessionStore) ListByChat(chatID string) ([]*session.Session, error)
- func (s *RemoteSessionStore) Messages(sessionID string) ([]session.Message, error)
- func (s *RemoteSessionStore) Set(sessionID string, sess *session.Session) error
- type ServiceStatsRecord
- type Settings
- type StatsStore
- func (ss *StatsStore) ClearAll() error
- func (ss *StatsStore) ClearService(provider, model string) error
- func (ss *StatsStore) Get(provider, model string) (loadbalance.ServiceStats, bool)
- func (ss *StatsStore) HydrateRules(rules []typ.Rule) error
- func (ss *StatsStore) RecordUsage(service *loadbalance.Service, inputTokens, outputTokens int) (loadbalance.ServiceStats, error)
- func (ss *StatsStore) ServiceKey(provider, model string) string
- func (ss *StatsStore) Snapshot() map[string]loadbalance.ServiceStats
- func (ss *StatsStore) UpdateFromService(service *loadbalance.Service) error
- type StoreManager
- func (sm *StoreManager) APIToken() *APITokenStore
- func (sm *StoreManager) BaseDir() string
- func (sm *StoreManager) BotAccess() *BotAccessStore
- func (sm *StoreManager) Close() error
- func (sm *StoreManager) HealthCheck() (*HealthStatus, error)
- func (sm *StoreManager) ImBotSettings() *ImBotSettingsStore
- func (sm *StoreManager) Model() *ModelStore
- func (sm *StoreManager) Provider() *ProviderStore
- func (sm *StoreManager) RemoteChats() *RemoteChatStore
- func (sm *StoreManager) RemoteSessions() *RemoteSessionStore
- func (sm *StoreManager) Stats() *StatsStore
- func (sm *StoreManager) Tasks() *TaskStore
- func (sm *StoreManager) ToolConfig() *ToolConfigStore
- func (sm *StoreManager) Usage() *UsageStore
- type StoreManagerConfig
- type TaskRecord
- type TaskStore
- func (s *TaskStore) Create(ctx context.Context, t *task.Task) error
- func (s *TaskStore) FindDueTasks(ctx context.Context, now time.Time, limit int) ([]task.Task, error)
- func (s *TaskStore) FindQueuedForKey(ctx context.Context, key string) (*task.Task, error)
- func (s *TaskStore) Get(ctx context.Context, taskID string) (*task.Task, error)
- func (s *TaskStore) List(ctx context.Context, filter task.ListFilter) ([]task.Task, error)
- func (s *TaskStore) MarkInterruptedOnStartup(ctx context.Context) error
- func (s *TaskStore) Update(ctx context.Context, t *task.Task) error
- func (s *TaskStore) UpdateStatus(ctx context.Context, taskID string, fields map[string]interface{}) error
- type TimeSeriesData
- type ToolConfigRecord
- type ToolConfigStore
- func (tcs *ToolConfigStore) Close() error
- func (tcs *ToolConfigStore) Delete(uuid string) error
- func (tcs *ToolConfigStore) DeleteByProvider(providerUUID string) error
- func (tcs *ToolConfigStore) GetByProvider(providerUUID string) ([]*ToolConfigRecord, error)
- func (tcs *ToolConfigStore) GetByProviderAndType(providerUUID string, toolType string) (*ToolConfigRecord, error)
- func (tcs *ToolConfigStore) GetDB() *gorm.DB
- func (tcs *ToolConfigStore) GetToolConfig(providerUUID, toolType string, target interface{}) (disabled, found bool, err error)
- func (tcs *ToolConfigStore) Save(config *ToolConfigRecord) error
- func (tcs *ToolConfigStore) SetToolConfig(providerUUID, toolType string, config interface{}, disabled bool) (string, error)
- type UsageDailyRecord
- type UsageMonthlyRecord
- type UsageRecord
- type UsageStatsQuery
- type UsageStore
- func (us *UsageStore) AggregateToDaily(date time.Time) (int64, error)
- func (us *UsageStore) DeleteOlderThan(cutoffDate time.Time) (int64, error)
- func (us *UsageStore) GetAggregatedStats(query UsageStatsQuery) ([]AggregatedStat, error)
- func (us *UsageStore) GetPerformanceSummary(startTime, endTime time.Time, filters map[string]string) (PerformanceSummary, error)
- func (us *UsageStore) GetRecords(startTime, endTime time.Time, filters map[string]string, limit, offset int) ([]UsageRecord, int64, error)
- func (us *UsageStore) GetRecordsAfterID(lastID uint, startTime time.Time, limit int) ([]UsageRecord, error)
- func (us *UsageStore) GetTimeSeries(interval string, startTime, endTime time.Time, filters map[string]string) ([]TimeSeriesData, error)
- func (us *UsageStore) RecordUsage(record *UsageRecord) error
- func (us *UsageStore) RenameRuleUUID(oldUUID, newUUID string) error
Constants ¶
const ( HealthStatusOK = "ok" HealthStatusError = "error" HealthStatusNotInit = "not_initialized" )
Health status constants
const ( // DefaultAdminUserID is the user ID for the default admin user // This is used for usage records created before multi-tenant support DefaultAdminUserID = "admin" )
const DefaultChatAgent = "tingly-box"
DefaultChatAgent is the agent a chat is driven by until something hands it off — Smart Guide is the entry point.
const (
ToolTypeMCPRuntime = "mcp_runtime" // MCP runtime tool sources
)
ToolType constants for different tool configuration types
Variables ¶
var ( ErrInvalidCapability = errors.New("invalid bot capability") ErrInvalidPermission = errors.New("invalid permission") ErrAccessTargetNotFound = errors.New("access target not found") ErrCrossBotTarget = errors.New("route target belongs to another bot") )
var ( // ErrChatIDRequired is returned when an operation needs a chat ID and got none. ErrChatIDRequired = errors.New("chat_id is required") // ErrStoreClosed is returned when the store has no usable DB handle. ErrStoreClosed = errors.New("chat store not initialized") )
Sentinels for the remote chat store.
Functions ¶
func TokensPerSecond ¶ added in v0.260806.1
TokensPerSecond derives per-request output TPS from persisted timing fields. The first token is accounted for by TTFT, leaving N-1 decode intervals from the first output token to the last.
Types ¶
type APITokenRecord ¶ added in v0.260418.2200
type APITokenRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;column:id"`
TokenID string `gorm:"uniqueIndex;column:token_id;not null;size:64"` // Token identifier (jti)
UserID string `gorm:"index:idx_api_token_user_id;not null;column:user_id;size:64"`
DisplayName string `gorm:"column:display_name;size:256"`
Enabled bool `gorm:"column:enabled;default:true"`
ExpiresAt *time.Time `gorm:"column:expires_at;index"`
LastUsedAt *time.Time `gorm:"column:last_used_at"`
CreatedAt time.Time `gorm:"column:created_at"`
CreatedBy string `gorm:"column:created_by;size:64"`
RevokedAt *time.Time `gorm:"column:revoked_at"`
RevokeReason string `gorm:"column:revoke_reason;size:512"`
}
APITokenRecord represents a user API token for multi-tenant authentication
func (APITokenRecord) TableName ¶ added in v0.260418.2200
func (APITokenRecord) TableName() string
TableName specifies the table name for GORM
type APITokenStore ¶ added in v0.260418.2200
type APITokenStore struct {
// contains filtered or unexported fields
}
APITokenStore manages API tokens for multi-tenant authentication
func NewAPITokenStore ¶ added in v0.260418.2200
func NewAPITokenStore(baseDir string) (*APITokenStore, error)
NewAPITokenStore creates or loads an API token store using SQLite database.
func (*APITokenStore) CleanupExpiredTokens ¶ added in v0.260418.2200
func (s *APITokenStore) CleanupExpiredTokens(olderThan time.Duration) (int64, error)
CleanupExpiredTokens removes expired tokens older than the specified duration
func (*APITokenStore) Close ¶ added in v0.260418.2200
func (s *APITokenStore) Close() error
Close closes the database connection
func (*APITokenStore) CreateTokenWithTokenID ¶ added in v0.260418.2200
func (s *APITokenStore) CreateTokenWithTokenID(userID, tokenID, displayName, createdBy string, expiresAt *time.Time) (*APITokenRecord, error)
CreateTokenWithTokenID creates a new API token record with a specific token ID
func (*APITokenStore) DeleteToken ¶ added in v0.260418.2200
func (s *APITokenStore) DeleteToken(tokenID string) error
DeleteToken permanently deletes a token record
func (*APITokenStore) GetDB ¶ added in v0.260418.2200
func (s *APITokenStore) GetDB() *gorm.DB
GetDB returns the underlying GORM DB instance (for testing)
func (*APITokenStore) GetToken ¶ added in v0.260418.2200
func (s *APITokenStore) GetToken(tokenID string) (*APITokenRecord, error)
GetToken retrieves a token by token ID
func (*APITokenStore) ListTokens ¶ added in v0.260418.2200
func (s *APITokenStore) ListTokens(userID string, enabled *bool, limit, offset int) ([]APITokenRecord, int64, error)
ListTokens returns tokens matching filters
func (*APITokenStore) RevokeToken ¶ added in v0.260418.2200
func (s *APITokenStore) RevokeToken(tokenID, reason string) error
RevokeToken revokes a token by setting enabled to false
func (*APITokenStore) SetTokenEnabled ¶ added in v0.260418.2200
func (s *APITokenStore) SetTokenEnabled(tokenID string, enabled bool) error
SetTokenEnabled enables or disables a token
func (*APITokenStore) UpdateLastUsed ¶ added in v0.260418.2200
func (s *APITokenStore) UpdateLastUsed(tokenID string) error
UpdateLastUsed updates the last_used_at timestamp for a token
func (*APITokenStore) UpdateTokenString ¶ added in v0.260418.2200
func (s *APITokenStore) UpdateTokenString(tokenID, newTokenString string) error
UpdateTokenString updates the token string for a token (for regeneration)
func (*APITokenStore) ValidateToken ¶ added in v0.260418.2200
func (s *APITokenStore) ValidateToken(tokenID string) (*APITokenRecord, error)
ValidateToken validates a token ID and returns the associated token record
type AggregatedStat ¶
type AggregatedStat struct {
Key string `json:"key"`
ProviderUUID string `json:"provider_uuid,omitempty"`
ProviderName string `json:"provider_name,omitempty"`
Model string `json:"model,omitempty"`
Scenario string `json:"scenario,omitempty"`
UserID string `json:"user_id,omitempty"`
RequestCount int64 `json:"request_count"`
TotalTokens int64 `json:"total_tokens"`
InputTokens int64 `json:"total_input_tokens"`
OutputTokens int64 `json:"total_output_tokens"`
CacheReadTokens int64 `json:"cache_read_tokens"`
CacheWriteTokens int64 `json:"cache_write_tokens"`
SystemTokens int64 `json:"system_tokens"`
AvgInputTokens float64 `json:"avg_input_tokens"`
AvgOutputTokens float64 `json:"avg_output_tokens"`
AvgLatencyMs float64 `json:"avg_latency_ms"`
ErrorCount int64 `json:"error_count"`
ErrorRate float64 `json:"error_rate"`
StreamedCount int64 `json:"streamed_count"`
StreamedRate float64 `json:"streamed_rate"`
}
AggregatedStat represents aggregated usage statistics
type BotAccessStore ¶ added in v0.260806.1
type BotAccessStore struct {
// contains filtered or unexported fields
}
BotAccessStore owns the final Bot Capability, DirectChat, Group, Actor, permission, and Route facts. All multi-row defaults are written in one transaction; reads never infer a missing policy.
func NewBotAccessStore ¶ added in v0.260806.1
func NewBotAccessStore(db *gorm.DB) *BotAccessStore
func (*BotAccessStore) AddGroupActor ¶ added in v0.260806.1
func (*BotAccessStore) AnyCapabilityEnabled ¶ added in v0.260806.1
func (*BotAccessStore) CreateRoute ¶ added in v0.260806.1
func (*BotAccessStore) DeleteDirectChat ¶ added in v0.260806.1
func (s *BotAccessStore) DeleteDirectChat(ctx context.Context, botUUID, id string) error
func (*BotAccessStore) DeleteGroup ¶ added in v0.260806.1
func (s *BotAccessStore) DeleteGroup(ctx context.Context, botUUID, id string) error
func (*BotAccessStore) DeleteRoute ¶ added in v0.260806.1
func (s *BotAccessStore) DeleteRoute(ctx context.Context, botUUID, id string) error
func (*BotAccessStore) DiscoverDirectChat ¶ added in v0.260806.1
func (s *BotAccessStore) DiscoverDirectChat(ctx context.Context, botUUID, platform, externalChatID string) (access.DirectChat, error)
func (*BotAccessStore) DiscoverGroup ¶ added in v0.260806.1
func (*BotAccessStore) GetCapability ¶ added in v0.260806.1
func (s *BotAccessStore) GetCapability(ctx context.Context, botUUID string, name access.CapabilityName) (access.BotCapability, bool, error)
func (*BotAccessStore) GetDirectChat ¶ added in v0.260806.1
func (s *BotAccessStore) GetDirectChat(ctx context.Context, botUUID, id string) (access.DirectChat, bool, error)
func (*BotAccessStore) ListCapabilities ¶ added in v0.260806.1
func (s *BotAccessStore) ListCapabilities(ctx context.Context, botUUID string) ([]access.BotCapability, error)
func (*BotAccessStore) ListDirectChatPermissions ¶ added in v0.260806.1
func (s *BotAccessStore) ListDirectChatPermissions(ctx context.Context, botUUID, id string) ([]access.Permission, error)
func (*BotAccessStore) ListDirectChats ¶ added in v0.260806.1
func (s *BotAccessStore) ListDirectChats(ctx context.Context, botUUID string) ([]access.DirectChat, error)
func (*BotAccessStore) ListGroupActors ¶ added in v0.260806.1
func (s *BotAccessStore) ListGroupActors(ctx context.Context, botUUID, groupID string) ([]access.GroupActor, error)
func (*BotAccessStore) ListGroupCapabilities ¶ added in v0.260806.1
func (s *BotAccessStore) ListGroupCapabilities(ctx context.Context, botUUID, id string) (map[access.CapabilityName]access.AccessEffect, error)
func (*BotAccessStore) ListGroups ¶ added in v0.260806.1
func (*BotAccessStore) ListRoutes ¶ added in v0.260806.1
func (*BotAccessStore) PairDirectChat ¶ added in v0.260806.1
func (s *BotAccessStore) PairDirectChat(ctx context.Context, chatID, externalActorID, displayName string) error
func (*BotAccessStore) PutCapability ¶ added in v0.260806.1
func (s *BotAccessStore) PutCapability(ctx context.Context, capability access.BotCapability) error
func (*BotAccessStore) RemoveGroupActor ¶ added in v0.260806.1
func (s *BotAccessStore) RemoveGroupActor(ctx context.Context, botUUID, groupID, actorID string) error
func (*BotAccessStore) ResolveRoute ¶ added in v0.260806.1
func (s *BotAccessStore) ResolveRoute(ctx context.Context, source, event string) (*access.ResolvedRoute, error)
func (*BotAccessStore) SetDirectChatBlocked ¶ added in v0.260806.1
func (*BotAccessStore) SetDirectChatPermission ¶ added in v0.260806.1
func (s *BotAccessStore) SetDirectChatPermission(ctx context.Context, botUUID, id string, capability access.CapabilityName, action access.ActionName, effect access.AccessEffect) error
func (*BotAccessStore) SetDirectChatPermissions ¶ added in v0.260806.1
func (s *BotAccessStore) SetDirectChatPermissions(ctx context.Context, botUUID, id string, perms []access.Permission) error
SetDirectChatPermissions writes a set of explicit permission rows for one Direct Chat in a single transaction. Presets use it so a partial network failure can never leave a half-applied permission state (e.g. start=allow with approve=deny).
func (*BotAccessStore) SetGroupActorPermission ¶ added in v0.260806.1
func (s *BotAccessStore) SetGroupActorPermission(ctx context.Context, botUUID, groupID, actorID string, capability access.CapabilityName, action access.ActionName, effect access.AccessEffect) error
func (*BotAccessStore) SetGroupBlocked ¶ added in v0.260806.1
func (*BotAccessStore) SetGroupCapability ¶ added in v0.260806.1
func (s *BotAccessStore) SetGroupCapability(ctx context.Context, botUUID, id string, capability access.CapabilityName, effect access.AccessEffect) error
func (*BotAccessStore) SetTransportFactsSource ¶ added in v0.260806.1
func (s *BotAccessStore) SetTransportFactsSource(source access.TransportFactsSource)
func (*BotAccessStore) Snapshot ¶ added in v0.260806.1
func (s *BotAccessStore) Snapshot(ctx context.Context, req access.AuthorizationRequest) (facts access.DecisionFacts, err error)
Snapshot implements access.FactSource. Missing rows stay zero-valued and therefore fail closed in access.Evaluate.
func (*BotAccessStore) UnpairDirectChat ¶ added in v0.260806.1
func (s *BotAccessStore) UnpairDirectChat(ctx context.Context, botUUID, id string) error
func (*BotAccessStore) UpdateRoute ¶ added in v0.260806.1
func (s *BotAccessStore) UpdateRoute(ctx context.Context, route access.Route, grantNotify bool) (access.Route, error)
UpdateRoute replaces the mutable route definition while preserving its stable identity and creation timestamp. Target validation and optional Notify grant happen in the same transaction so a cross-bot target can never be persisted, even briefly.
func (*BotAccessStore) UpsertActor ¶ added in v0.260806.1
type HealthStatus ¶
type HealthStatus struct {
Healthy bool `json:"healthy"`
TotalStores int `json:"total_stores"`
HealthyStores int `json:"healthy_stores"`
UnhealthyStores int `json:"unhealthy_stores"`
StoreStatus map[string]string `json:"store_status"`
}
HealthStatus represents the health of all stores.
type ImBotSettingsRecord ¶
type ImBotSettingsRecord struct {
BotUUID string `gorm:"primaryKey;column:bot_uuid"`
Name string `gorm:"column:name"`
Platform string `gorm:"column:platform;index:idx_platform"`
AuthType string `gorm:"column:auth_type"`
AuthConfig string `gorm:"column:auth_config;type:text"` // JSON string of auth map
ProxyURL string `gorm:"column:proxy_url"`
ChatIDLock string `gorm:"column:chat_id_lock"`
BashAllowlist string `gorm:"column:bash_allowlist;type:text"` // JSON array string
DefaultCwd string `gorm:"column:default_cwd"` // Default working directory
DefaultAgent string `gorm:"column:default_agent"` // Default Agent UUID
Enabled bool `gorm:"column:enabled;index:idx_enabled"`
// Output behavior settings
Debug bool `gorm:"column:debug;default:false"` // Show message IDs in output
Verbose *bool `gorm:"column:verbose;default:true"` // Send intermediate messages (nil = true)
// SmartGuide model configuration (required for @tb agent)
SmartGuideProvider string `gorm:"column:smartguide_provider"` // Provider UUID
SmartGuideModel string `gorm:"column:smartguide_model"` // Model identifier
// RequirePairing enforces TOFU pairing-code binding for direct messages.
// Nil for legacy rows is treated as false (opt-in migration); the bot
// create wizard sets this to true for newly created bots.
RequirePairing *bool `gorm:"column:require_pairing"`
// Scenarios is a JSON-encoded list of scenario bindings declaring
// which Claude Code hook scenarios this bot serves and the IM target.
// Schema: see internal/server/module/notify/binding.go ScenarioBinding.
Scenarios string `gorm:"column:scenarios;type:text"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
ImBotSettingsRecord is the GORM model for persisting ImBot credentials
func (*ImBotSettingsRecord) GetVerbose ¶
func (r *ImBotSettingsRecord) GetVerbose() bool
GetVerbose returns verbose setting with default true
func (ImBotSettingsRecord) TableName ¶
func (ImBotSettingsRecord) TableName() string
TableName specifies the table name for GORM
type ImBotSettingsStore ¶
type ImBotSettingsStore struct {
// contains filtered or unexported fields
}
ImBotSettingsStore persists ImBot settings in SQLite using GORM.
func NewImBotSettingsStore ¶
func NewImBotSettingsStore(baseDir string) (*ImBotSettingsStore, error)
NewImBotSettingsStore creates or loads an ImBot settings store using SQLite database.
func (*ImBotSettingsStore) CreateSettings ¶
func (s *ImBotSettingsStore) CreateSettings(settings Settings) (Settings, error)
CreateSettings creates a new ImBot configuration.
func (*ImBotSettingsStore) DeleteSettings ¶
func (s *ImBotSettingsStore) DeleteSettings(uuid string) error
DeleteSettings deletes an ImBot configuration.
func (*ImBotSettingsStore) GetSettingsByUUID ¶
func (s *ImBotSettingsStore) GetSettingsByUUID(uuid string) (Settings, error)
GetSettingsByUUID returns a single ImBot configuration by UUID.
func (*ImBotSettingsStore) ListEnabledSettings ¶
func (s *ImBotSettingsStore) ListEnabledSettings() ([]Settings, error)
ListEnabledSettings returns all enabled ImBot configurations.
func (*ImBotSettingsStore) ListSettings ¶
func (s *ImBotSettingsStore) ListSettings() ([]Settings, error)
ListSettings returns all ImBot configurations.
func (*ImBotSettingsStore) SetEnabled ¶ added in v0.260806.1
func (s *ImBotSettingsStore) SetEnabled(uuid string, enabled bool) error
SetEnabled writes the Bot's explicit lifecycle gate without touching any other settings. Capability lifecycle reconciliation uses this narrow method so it cannot accidentally clear partial-update fields such as scenarios.
func (*ImBotSettingsStore) ToggleSettings ¶
func (s *ImBotSettingsStore) ToggleSettings(uuid string) (bool, error)
ToggleSettings toggles the enabled status of an ImBot configuration.
func (*ImBotSettingsStore) UpdateSettings ¶
func (s *ImBotSettingsStore) UpdateSettings(uuid string, settings Settings) error
UpdateSettings updates an existing ImBot configuration. Only updates fields that are non-zero/empty in the settings struct.
type ModelSource ¶ added in v0.260604.1
type ModelSource string
ModelSource identifies how a cached model list was obtained.
const ( ModelSourceAPI ModelSource = "api" ModelSourceTemplate ModelSource = "template" )
type ModelStore ¶
type ModelStore struct {
// contains filtered or unexported fields
}
ModelStore persists provider model information in SQLite using GORM.
func NewModelStore ¶
func NewModelStore(baseDir string) (*ModelStore, error)
NewModelStore creates or loads a model store using SQLite database.
func (*ModelStore) Close ¶ added in v0.260716.1
func (s *ModelStore) Close() error
Close releases the store's database connection. Safe to call more than once. Short-lived embedders (tests, harness environments) must close, or each instance leaks a SQLite handle for the process lifetime.
func (*ModelStore) GetAllModelRecords ¶
func (ms *ModelStore) GetAllModelRecords() []ProviderModelRecord
GetAllModelRecords returns all provider records (with metadata)
func (*ModelStore) GetAllProviders ¶
func (ms *ModelStore) GetAllProviders() []string
GetAllProviders returns all provider UUIDs that have models
func (*ModelStore) GetModelCount ¶
func (ms *ModelStore) GetModelCount(providerUUID string) int
GetModelCount returns the number of models for a provider
func (*ModelStore) GetModels ¶
func (ms *ModelStore) GetModels(providerUUID string, ttl time.Duration) []string
GetModels returns models for a provider by UUID. All records use the same TTL (1 hour), regardless of source. If multiple records exist (api + template), the most recently updated is returned.
func (*ModelStore) GetModelsBySource ¶ added in v0.260604.1
func (ms *ModelStore) GetModelsBySource(providerUUID string, source ModelSource, ttl time.Duration) []string
GetModelsBySource returns models for a provider by UUID, filtered by source. Records are only returned if they match the source AND are within the TTL.
func (*ModelStore) GetProviderInfo ¶
func (ms *ModelStore) GetProviderInfo(providerUUID string) (apiBase string, lastUpdated string, exists bool)
GetProviderInfo returns basic info about a provider (apiBase, lastUpdated, exists)
func (*ModelStore) HasModels ¶
func (ms *ModelStore) HasModels(providerUUID string) bool
HasModels checks if a provider has models
func (*ModelStore) RemoveProvider ¶
func (ms *ModelStore) RemoveProvider(providerUUID string) error
RemoveProvider removes all models for a provider by UUID
func (*ModelStore) SaveModels ¶
func (ms *ModelStore) SaveModels(provider *typ.Provider, models []string, source ModelSource) error
SaveModels saves models for a provider by UUID
type PerformanceMetricSummary ¶ added in v0.260806.1
type PerformanceMetricSummary struct {
SampleCount int64
P10 float64
P50 float64
P90 float64
P95 float64
P99 float64
}
PerformanceMetricSummary describes the typical and tail values for one request-performance metric. P10 is primarily useful for TPS, where lower is worse; latency-style metrics use P50/P90/P99.
type PerformanceSummary ¶ added in v0.260806.1
type PerformanceSummary struct {
TTFT PerformanceMetricSummary
TPS PerformanceMetricSummary
Completion PerformanceMetricSummary
}
PerformanceSummary separates the three questions users ask about a streamed response: when it started, how quickly it generated, and when it completed.
type ProviderModelRecord ¶
type ProviderModelRecord struct {
ProviderUUID string `gorm:"primaryKey;column:provider_uuid"`
ProviderName string `gorm:"column:provider_name;index"`
APIBase string `gorm:"column:api_base"`
Models string `gorm:"column:models;type:text"`
Source ModelSource `gorm:"column:source"`
LastUpdated time.Time `gorm:"column:last_updated"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
ProviderModelRecord is the GORM model for persisting provider models
func (ProviderModelRecord) TableName ¶
func (ProviderModelRecord) TableName() string
TableName specifies the table name for GORM
type ProviderRecord ¶
type ProviderRecord struct {
UUID string `gorm:"primaryKey;column:uuid"`
Name string `gorm:"column:name;not null;index"`
APIBase string `gorm:"column:api_base;not null"`
APIStyle string `gorm:"column:api_style;not null"` // "openai" or "anthropic"
AuthType string `gorm:"column:auth_type;not null"` // "api_key", "oauth", or "vmodel"
Source string `gorm:"column:source;default:'user'"` // "user" (default) or "builtin"
// Configuration fields
NoKeyRequired bool `gorm:"column:no_key_required;default:false"`
Enabled bool `gorm:"column:enabled;default:true"`
ProxyURL string `gorm:"column:proxy_url"`
Timeout int64 `gorm:"column:timeout"`
Tags string `gorm:"column:tags;type:text"` // JSON array
LastUpdated string `gorm:"column:last_updated"`
// Dual-mode optional fields. Independent of APIBase/APIStyle.
APIBaseOpenAI string `gorm:"column:api_base_openai"`
APIBaseAnthropic string `gorm:"column:api_base_anthropic"`
// OpenAIEndpointMode declares which OpenAI endpoints this provider exposes
// ("", "chat", "responses", "both"). See ai.OpenAIEndpointMode.
OpenAIEndpointMode string `gorm:"column:openai_endpoint_mode"`
// Credential fields - stored with provider as a unit
// For api_key auth: stores the API key
// For oauth auth: stores OAuth access token
Token string `gorm:"column:token"` // API key or access token
OAuthProviderType string `gorm:"column:oauth_provider_type"` // For oauth: provider type
OAuthUserID string `gorm:"column:oauth_user_id"` // For oauth: user ID
OAuthRefreshToken string `gorm:"column:oauth_refresh_token"` // For oauth: refresh token
OAuthExpiresAt string `gorm:"column:oauth_expires_at"` // For oauth: token expiration (RFC3339)
OAuthExtraFields string `gorm:"column:oauth_extra_fields;type:text"` // For oauth: JSON
// VModel-specific fields (only populated when AuthType == "vmodel")
VModelDetail string `gorm:"column:vmodel_detail;type:text"` // JSON-encoded typ.VModelDetail
// Credential holds multi-field credentials for non-bearer auth types
// (aws_sigv4, azure_key, gcp_sa). JSON-encoded typ.CredentialBundle.
// Empty for api_key/oauth/vmodel. Added additively; AutoMigrate creates
// the column on existing databases with no backfill required.
Credential string `gorm:"column:credential;type:text"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
ProviderRecord is the GORM model for persisting a complete provider This includes both configuration and credentials as one logical entity
func (ProviderRecord) TableName ¶
func (ProviderRecord) TableName() string
TableName specifies the table name for GORM
type ProviderStore ¶
type ProviderStore struct {
// contains filtered or unexported fields
}
ProviderStore manages providers as complete units (configuration + credentials)
func NewProviderStore ¶
func NewProviderStore(baseDir string) (*ProviderStore, error)
NewProviderStore creates or loads a provider store using SQLite database.
func (*ProviderStore) Close ¶
func (ps *ProviderStore) Close() error
Close closes the database connection
func (*ProviderStore) Count ¶
func (ps *ProviderStore) Count() (int64, error)
Count returns the total number of providers
func (*ProviderStore) Delete ¶
func (ps *ProviderStore) Delete(uuid string) error
Delete removes a provider by UUID
func (*ProviderStore) Exists ¶
func (ps *ProviderStore) Exists(uuid string) bool
Exists checks if a provider exists by UUID
func (*ProviderStore) GetAccessToken ¶
func (ps *ProviderStore) GetAccessToken(uuid string) (string, error)
GetAccessToken returns the access token for a provider (convenience method)
func (*ProviderStore) GetByName ¶
func (ps *ProviderStore) GetByName(name string) (*typ.Provider, error)
GetByName returns a provider by name
func (*ProviderStore) GetByUUID ¶
func (ps *ProviderStore) GetByUUID(uuid string) (*typ.Provider, error)
GetByUUID returns a provider by UUID
func (*ProviderStore) GetDB ¶
func (ps *ProviderStore) GetDB() *gorm.DB
GetDB returns the underlying GORM DB instance (for testing/advanced usage)
func (*ProviderStore) IsOAuthExpired ¶
func (ps *ProviderStore) IsOAuthExpired(uuid string) (bool, error)
IsOAuthExpired checks if the OAuth token for a provider is expired
func (*ProviderStore) List ¶
func (ps *ProviderStore) List() ([]*typ.Provider, error)
List returns all providers
func (*ProviderStore) ListEnabled ¶
func (ps *ProviderStore) ListEnabled() ([]*typ.Provider, error)
ListEnabled returns all enabled providers
func (*ProviderStore) ListOAuth ¶
func (ps *ProviderStore) ListOAuth() ([]*typ.Provider, error)
ListOAuth returns all OAuth-enabled providers
func (*ProviderStore) Save ¶
func (ps *ProviderStore) Save(provider *typ.Provider) error
Save saves a provider (create or update)
func (*ProviderStore) UpdateCredential ¶
func (ps *ProviderStore) UpdateCredential(uuid string, token string, oauthDetail *typ.OAuthDetail) error
UpdateCredential updates only the credential fields of a provider
func (*ProviderStore) UpdateCredentialBundle ¶ added in v0.260531.1
func (ps *ProviderStore) UpdateCredentialBundle(uuid string, bundle *typ.CredentialBundle) error
UpdateCredentialBundle updates only the multi-field credential of a provider (auth types aws_sigv4, azure_key, gcp_sa). Added alongside UpdateCredential to avoid changing that method's signature and its existing callers.
func (*ProviderStore) UpdateOAuthAccessToken ¶
func (ps *ProviderStore) UpdateOAuthAccessToken(uuid, accessToken string) error
UpdateOAuthAccessToken updates only the OAuth access token for a provider
type RemoteChatRecord ¶ added in v0.260801.1
type RemoteChatRecord struct {
ChatID string `gorm:"primaryKey;column:chat_id"`
Platform string `gorm:"column:platform"`
ProjectPath string `gorm:"column:project_path"`
OwnerID string `gorm:"column:owner_id;index:idx_remote_chats_owner,priority:1"`
// ProjectHistory is the MRU path list, JSON-encoded.
ProjectHistory string `gorm:"column:project_history;type:text"`
IsPaired bool `gorm:"column:is_paired"`
PairedBotUUID string `gorm:"column:paired_bot_uuid;index:idx_remote_chats_paired_bot"`
PairedSenderID string `gorm:"column:paired_sender_id"`
PairedAt time.Time `gorm:"column:paired_at"`
IsWhitelisted bool `gorm:"column:is_whitelisted;index:idx_remote_chats_whitelisted"`
WhitelistedBy string `gorm:"column:whitelisted_by"`
BashCwd string `gorm:"column:bash_cwd"`
CurrentAgent string `gorm:"column:current_agent"`
Verbose *bool `gorm:"column:verbose"`
Disabled bool `gorm:"column:disabled;index:idx_remote_chats_disabled"`
DisabledAt time.Time `gorm:"column:disabled_at"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
RemoteChatRecord is the GORM model behind bot.Chat.
ProjectHistory stays a JSON column for now — splitting it into its own table is the next step (see .design/remote-storage.md P2); everything the product actually queries on (owner, whitelist, pairing) is a real column with an index.
func (RemoteChatRecord) TableName ¶ added in v0.260801.1
func (RemoteChatRecord) TableName() string
TableName specifies the table name for GORM.
type RemoteChatStore ¶ added in v0.260801.1
type RemoteChatStore struct {
// contains filtered or unexported fields
}
RemoteChatStore persists IM chat state in the shared SQLite database.
It replaces a JSON file that every bot loaded into its own memory and rewrote whole, which meant concurrent writers silently erased each other — in-process (fixed earlier by sharing one store) and across processes (only fixed by being here, on one WAL database with row-level updates).
func NewRemoteChatStore ¶ added in v0.260801.1
func NewRemoteChatStore(db *gorm.DB) *RemoteChatStore
NewRemoteChatStore builds a store over an existing DB handle. The handle is owned by the StoreManager; Close here does not close it.
func (*RemoteChatStore) AddToWhitelist ¶ added in v0.260801.1
func (s *RemoteChatStore) AddToWhitelist(chatID, platform, addedBy string) error
AddToWhitelist whitelists a chat, creating it if needed.
func (*RemoteChatStore) BindProject ¶ added in v0.260801.1
func (s *RemoteChatStore) BindProject(chatID, platform, projectPath, ownerID string) error
BindProject binds a project to a chat, creating the chat if needed, and pushes the path onto the chat's MRU history.
func (*RemoteChatStore) ClearPaired ¶ added in v0.260801.1
func (s *RemoteChatStore) ClearPaired(chatID string) error
ClearPaired removes any pairing recorded on the chat, preserving the rest of its state.
func (*RemoteChatStore) DeleteChat ¶ added in v0.260806.1
func (s *RemoteChatStore) DeleteChat(chatID string) error
DeleteChat hard-deletes the chat row. All chat state (pairing, whitelist, project binding) is gone; a new message from the same chat recreates it fresh via the normal auto-create path. Sessions are untouched. Deleting a missing chat is a no-op.
func (*RemoteChatStore) GetBashCwd ¶ added in v0.260801.1
func (s *RemoteChatStore) GetBashCwd(chatID string) (string, bool, error)
GetBashCwd retrieves the bash working directory for a chat.
func (*RemoteChatStore) GetChat ¶ added in v0.260801.1
func (s *RemoteChatStore) GetChat(chatID string) (*bot.Chat, error)
GetChat retrieves a chat by ID. A missing chat is (nil, nil).
func (*RemoteChatStore) GetCurrentAgent ¶ added in v0.260801.1
func (s *RemoteChatStore) GetCurrentAgent(chatID string) (string, error)
GetCurrentAgent retrieves the chat's current agent, defaulting to Smart Guide as the entry point.
func (*RemoteChatStore) GetOrCreateChat ¶ added in v0.260801.1
func (s *RemoteChatStore) GetOrCreateChat(chatID, platform string) (*bot.Chat, error)
GetOrCreateChat returns the chat, creating an empty one if it does not exist.
The table is keyed by chat_id alone (no platform dimension), so when an existing row's platform differs from the requested platform we refuse rather than silently returning (and later overwriting) another platform's chat. This is the guard against cross-platform chatID-string collisions leaking platform A's chat into platform B.
func (*RemoteChatStore) GetProjectPath ¶ added in v0.260801.1
func (s *RemoteChatStore) GetProjectPath(chatID string) (string, bool, error)
GetProjectPath retrieves the project path bound to a chat.
func (*RemoteChatStore) ImportChat ¶ added in v0.260801.1
func (s *RemoteChatStore) ImportChat(chat *bot.Chat) error
ImportChat stores a chat exactly as given, without restamping UpdatedAt.
Migration needs this for the same reason sessions do: UpdatedAt orders ListChats, so stamping it on import would make every migrated chat look equally and freshly active in the bot's chat list.
func (*RemoteChatStore) IsChatDisabled ¶ added in v0.260806.1
func (s *RemoteChatStore) IsChatDisabled(chatID string) bool
IsChatDisabled reports the blocklist flag. Missing chat → false.
func (*RemoteChatStore) IsChatPaired ¶ added in v0.260801.1
func (s *RemoteChatStore) IsChatPaired(chatID, botUUID string) bool
IsChatPaired reports whether the chat is paired with the given bot UUID.
func (*RemoteChatStore) IsWhitelisted ¶ added in v0.260801.1
func (s *RemoteChatStore) IsWhitelisted(chatID string) bool
IsWhitelisted reports whether a chat is whitelisted.
func (*RemoteChatStore) ListChatProjectPaths ¶ added in v0.260801.1
func (s *RemoteChatStore) ListChatProjectPaths(chatID string) ([]string, error)
ListChatProjectPaths returns the per-chat MRU list of project paths (newest first), falling back to [ProjectPath] for chats with no history yet.
func (*RemoteChatStore) ListChats ¶ added in v0.260801.1
ListChats returns the chat records this bot can reach on platform — those whose Platform field is set AND matches. Empty/mismatched-platform records are dropped at the source (see bot.ChatStoreInterface.ListChats for why). Ordered newest-first by updated_at, with chat_id as a stable tiebreaker, so the most recently active chats surface at the top.
func (*RemoteChatStore) ListChatsByOwner ¶ added in v0.260801.1
func (s *RemoteChatStore) ListChatsByOwner(ownerID, platform string) ([]*bot.Chat, error)
ListChatsByOwner lists a user's chats on a platform that have a project bound.
func (*RemoteChatStore) RemoveFromWhitelist ¶ added in v0.260801.1
func (s *RemoteChatStore) RemoveFromWhitelist(chatID string) error
RemoveFromWhitelist clears a chat's whitelist flag.
func (*RemoteChatStore) SetBashCwd ¶ added in v0.260801.1
func (s *RemoteChatStore) SetBashCwd(chatID, cwd string) error
SetBashCwd sets the bash working directory for a chat.
func (*RemoteChatStore) SetChatDisabled ¶ added in v0.260806.1
func (s *RemoteChatStore) SetChatDisabled(chatID string, disabled bool) error
SetChatDisabled toggles the inbound blocklist flag. A missing chat is a no-op (there is nothing to block; the flag would be erased by the next auto-create anyway).
func (*RemoteChatStore) SetCurrentAgent ¶ added in v0.260801.1
func (s *RemoteChatStore) SetCurrentAgent(chatID, platform, agentType string) error
SetCurrentAgent sets the chat's current agent, creating the chat row if it doesn't exist yet — without the auto-create, handoff state was silently dropped for any chat that hadn't been bound or paired first.
func (*RemoteChatStore) SetPaired ¶ added in v0.260801.1
func (s *RemoteChatStore) SetPaired(chatID, platform, botUUID, senderID string) error
SetPaired marks a chat as paired with the given bot and sender, creating the chat if needed.
func (*RemoteChatStore) UpdateChat ¶ added in v0.260801.1
func (s *RemoteChatStore) UpdateChat(chatID string, fn func(*bot.Chat)) error
UpdateChat applies fn to an existing chat inside a transaction, so a concurrent writer cannot interleave between the read and the write. A missing chat is a no-op, matching the store this replaces.
func (*RemoteChatStore) UpsertChat ¶ added in v0.260801.1
func (s *RemoteChatStore) UpsertChat(chat *bot.Chat) error
UpsertChat creates or replaces a chat row.
type RemoteSessionRecord ¶ added in v0.260801.1
type RemoteSessionRecord struct {
ID string `gorm:"primaryKey;column:id"`
ChatID string `gorm:"column:chat_id;index:idx_remote_sessions_bind,priority:1;index:idx_remote_sessions_chat"`
Agent string `gorm:"column:agent;index:idx_remote_sessions_bind,priority:2"`
Project string `gorm:"column:project;index:idx_remote_sessions_bind,priority:3"`
Status string `gorm:"column:status;index:idx_remote_sessions_status"`
Request string `gorm:"column:request;type:text"`
Response string `gorm:"column:response;type:text"`
Error string `gorm:"column:error;type:text"`
PermissionMode string `gorm:"column:permission_mode"`
CreatedAt time.Time `gorm:"column:created_at"`
LastActivity time.Time `gorm:"column:last_activity;index:idx_remote_sessions_bind,priority:4"`
ExpiresAt time.Time `gorm:"column:expires_at"`
}
RemoteSessionRecord is the GORM model for a remote-control execution session — one row per (chat, agent, project) conversation with an agent.
This is the session INDEX only — binding, status, timestamps. The message history lives beside it in an append-only transcript file per session (see session.Transcript): small bounded metadata belongs in a table where the composite index on (chat_id, agent, project, last_activity) turns FindByChatAgentProject into one lookup, while unbounded conversation text belongs in a file that appends in O(1) and never bloats the shared database. See .design/remote-storage.md.
func (RemoteSessionRecord) TableName ¶ added in v0.260801.1
func (RemoteSessionRecord) TableName() string
TableName specifies the table name for GORM.
type RemoteSessionStore ¶ added in v0.260801.1
type RemoteSessionStore struct {
// contains filtered or unexported fields
}
RemoteSessionStore persists remote-control sessions across two media, chosen per access pattern rather than by preference:
- the session INDEX (binding, status, timestamps) goes in the shared SQLite database. Not for lookup speed — the manager keeps live sessions in memory and scans that first — but because it is small mutable state that several processes write concurrently: a session's status turns over repeatedly, and the CLI and the server must not overwrite each other the way two holders of a JSON file did;
- the message TRANSCRIPT goes in an append-only file per session, because it is write-once, read whole, never queried by content, and unbounded. See session.Transcript for the full argument.
func NewRemoteSessionStore ¶ added in v0.260801.1
func NewRemoteSessionStore(db *gorm.DB, transcript *session.Transcript) *RemoteSessionStore
NewRemoteSessionStore builds a store over an existing DB handle plus a transcript directory. The handle is owned by the StoreManager; Close here does not close it. A nil transcript simply drops history.
func (*RemoteSessionStore) AppendMessage ¶ added in v0.260801.1
func (s *RemoteSessionStore) AppendMessage(sessionID string, msg session.Message) error
AppendMessage adds one message to a session's transcript file.
func (*RemoteSessionStore) Delete ¶ added in v0.260801.1
func (s *RemoteSessionStore) Delete(sessionID string) error
Delete removes a session's index record and its transcript.
The row goes first: an orphaned transcript file is inert (nothing can reach it without an index entry) whereas an index entry whose transcript is gone would surface in listings as a session whose history silently vanished.
func (*RemoteSessionStore) FindByChatAgentProject ¶ added in v0.260801.1
func (s *RemoteSessionStore) FindByChatAgentProject(chatID, agent, project string) (*session.Session, error)
FindByChatAgentProject returns the most recently active non-terminal session bound to the tuple. Manager.FindBy consults its in-memory map first, so this is the cold path: a session written by another process, or one the manager has not loaded since restart.
func (*RemoteSessionStore) Get ¶ added in v0.260801.1
func (s *RemoteSessionStore) Get(sessionID string) (*session.Session, error)
Get retrieves a session's index record by ID. Messages are not loaded — call Messages when the transcript is actually needed. A missing session is (nil, nil), matching the store it replaces.
func (*RemoteSessionStore) Import ¶ added in v0.260801.1
func (s *RemoteSessionStore) Import(sess *session.Session) error
Import stores a session exactly as given, without stamping LastActivity.
Migration needs this: LastActivity orders FindByChatAgentProject and drives retention, so touching it on import would make every migrated session look like it was just active and reorder conversations that had been dormant for weeks.
func (*RemoteSessionStore) List ¶ added in v0.260801.1
func (s *RemoteSessionStore) List() []*session.Session
List returns the session index records worth warming the manager's in-memory map with. Two bounds matter here, both because this runs synchronously at startup: it must not read transcripts (that would pull every conversation ever held into memory), and it skips terminal sessions, which accumulate forever — Manager.Close leaves closed rows behind on purpose.
Skipping them changes nothing observable: Manager.FindBy ignores closed and expired sessions anyway, and GetOrLoad still fetches any session by id.
func (*RemoteSessionStore) ListByChat ¶ added in v0.260801.1
func (s *RemoteSessionStore) ListByChat(chatID string) ([]*session.Session, error)
ListByChat returns all sessions for a chat, newest activity first.
func (*RemoteSessionStore) Messages ¶ added in v0.260801.1
func (s *RemoteSessionStore) Messages(sessionID string) ([]session.Message, error)
Messages reads a session's transcript on demand.
func (*RemoteSessionStore) Set ¶ added in v0.260801.1
func (s *RemoteSessionStore) Set(sessionID string, sess *session.Session) error
Set upserts a session's index record.
This writes one row. It used to also reconcile the message rows — counting what was stored, appending only the new tail, trimming a shortened history — machinery that existed purely because the transcript was a table. With messages in an append-only file, AppendMessage stands on its own and this stays a single upsert.
type ServiceStatsRecord ¶
type ServiceStatsRecord struct {
// Composite primary key: provider + model (stats are global, not per-rule)
Provider string `gorm:"primaryKey;column:provider"`
Model string `gorm:"primaryKey;column:model"`
ServiceID string `gorm:"column:service_id"`
RequestCount int64 `gorm:"column:request_count"`
LastUsed time.Time `gorm:"column:last_used"`
WindowStart time.Time `gorm:"column:window_start"`
WindowRequestCount int64 `gorm:"column:window_request_count"`
WindowTokensConsumed int64 `gorm:"column:window_tokens_consumed"`
WindowInputTokens int64 `gorm:"column:window_input_tokens"`
WindowOutputTokens int64 `gorm:"column:window_output_tokens"`
TimeWindow int `gorm:"column:time_window"`
}
ServiceStatsRecord is the GORM model for persisting service statistics
func (ServiceStatsRecord) TableName ¶
func (ServiceStatsRecord) TableName() string
TableName specifies the table name for GORM
type Settings ¶
type Settings struct {
UUID string `json:"uuid,omitempty"`
Name string `json:"name,omitempty"`
Token string `json:"token,omitempty"` // Legacy: for backward compatibility
Platform string `json:"platform"`
AuthType string `json:"auth_type"`
Auth map[string]string `json:"auth"`
ProxyURL string `json:"proxy_url,omitempty"`
ChatIDLock string `json:"chat_id_lock,omitempty"` // Deprecated: retained for storage compatibility; not an authorization gate.
BashAllowlist []string `json:"bash_allowlist,omitempty"`
DefaultCwd string `json:"default_cwd,omitempty"` // Default working directory
DefaultAgent string `json:"default_agent,omitempty"` // Default Agent UUID
Enabled bool `json:"enabled"`
// SmartGuide model configuration (required for @tb agent)
SmartGuideProvider string `json:"smartguide_provider,omitempty"` // Provider UUID
SmartGuideModel string `json:"smartguide_model,omitempty"` // Model identifier
// RequirePairing enforces TOFU pairing for DMs. Nil = legacy/opt-in.
RequirePairing *bool `json:"require_pairing,omitempty"`
// Scenarios is the raw JSON-encoded list of hook scenarios this bot
// serves. The notify module parses it into typed bindings; the
// settings store keeps it opaque to avoid a cross-package dependency.
Scenarios string `json:"scenarios,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
}
Settings represents ImBot configuration (exported for use by remote_coder module)
type StatsStore ¶
type StatsStore struct {
// contains filtered or unexported fields
}
StatsStore persists service usage statistics in SQLite using GORM.
func NewStatsStore ¶
func NewStatsStore(baseDir string) (*StatsStore, error)
NewStatsStore creates or loads a stats store using SQLite database.
func (*StatsStore) ClearAll ¶
func (ss *StatsStore) ClearAll() error
ClearAll removes all persisted stats.
func (*StatsStore) ClearService ¶ added in v0.260709.1
func (ss *StatsStore) ClearService(provider, model string) error
ClearService removes persisted stats for a single provider:model. No error if no rows matched (the service simply had no recorded stats).
func (*StatsStore) Get ¶
func (ss *StatsStore) Get(provider, model string) (loadbalance.ServiceStats, bool)
Get returns stats for a specific provider/model combination.
func (*StatsStore) HydrateRules ¶
func (ss *StatsStore) HydrateRules(rules []typ.Rule) error
HydrateRules injects stored stats into the provided rules and initializes missing entries.
func (*StatsStore) RecordUsage ¶
func (ss *StatsStore) RecordUsage(service *loadbalance.Service, inputTokens, outputTokens int) (loadbalance.ServiceStats, error)
RecordUsage records usage for a service and persists the updated stats.
func (*StatsStore) ServiceKey ¶
func (ss *StatsStore) ServiceKey(provider, model string) string
ServiceKey builds a unique key for a provider/model combination.
func (*StatsStore) Snapshot ¶
func (ss *StatsStore) Snapshot() map[string]loadbalance.ServiceStats
Snapshot returns a copy of all stats keyed by provider:model.
func (*StatsStore) UpdateFromService ¶
func (ss *StatsStore) UpdateFromService(service *loadbalance.Service) error
UpdateFromService stores the current stats from a service into the store.
type StoreManager ¶
type StoreManager struct {
// contains filtered or unexported fields
}
StoreManager manages all database stores with a shared GORM DB instance. It provides unified initialization, thread-safe access, and lifecycle management.
func NewStoreManager ¶
func NewStoreManager(baseDir string) (*StoreManager, error)
NewStoreManager creates a new StoreManager and initializes all stores. It opens a single SQLite database connection shared by all stores.
Parameters:
baseDir - Base directory for database storage
Returns:
*StoreManager - Initialized store manager error - Error if any store fails to initialize
func NewStoreManagerWithConfig ¶
func NewStoreManagerWithConfig(config StoreManagerConfig) (*StoreManager, error)
NewStoreManagerWithConfig creates a StoreManager with custom configuration.
func (*StoreManager) APIToken ¶ added in v0.260418.2200
func (sm *StoreManager) APIToken() *APITokenStore
APIToken returns the APITokenStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) BaseDir ¶
func (sm *StoreManager) BaseDir() string
BaseDir returns the base directory for this StoreManager.
func (*StoreManager) BotAccess ¶ added in v0.260806.1
func (sm *StoreManager) BotAccess() *BotAccessStore
BotAccess returns the final-state Bot Capability and access-policy store.
func (*StoreManager) Close ¶
func (sm *StoreManager) Close() error
Close closes all database connections and cleans up resources. After Close() is called, all accessor methods will return nil.
func (*StoreManager) HealthCheck ¶
func (sm *StoreManager) HealthCheck() (*HealthStatus, error)
HealthCheck checks the health of all stores. Returns a HealthStatus with the state of each store.
func (*StoreManager) ImBotSettings ¶
func (sm *StoreManager) ImBotSettings() *ImBotSettingsStore
ImBotSettings returns the ImBotSettingsStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) Model ¶
func (sm *StoreManager) Model() *ModelStore
Model returns the ModelStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) Provider ¶
func (sm *StoreManager) Provider() *ProviderStore
Provider returns the ProviderStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) RemoteChats ¶ added in v0.260801.1
func (sm *StoreManager) RemoteChats() *RemoteChatStore
RemoteChats returns the RemoteChatStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) RemoteSessions ¶ added in v0.260801.1
func (sm *StoreManager) RemoteSessions() *RemoteSessionStore
RemoteSessions returns the RemoteSessionStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) Stats ¶
func (sm *StoreManager) Stats() *StatsStore
Stats returns the StatsStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) Tasks ¶ added in v0.260507.1
func (sm *StoreManager) Tasks() *TaskStore
Tasks returns the TaskStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) ToolConfig ¶
func (sm *StoreManager) ToolConfig() *ToolConfigStore
ToolConfig returns the ToolConfigStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
func (*StoreManager) Usage ¶
func (sm *StoreManager) Usage() *UsageStore
Usage returns the UsageStore (thread-safe). Returns nil if the store is not initialized or after Close() has been called.
type StoreManagerConfig ¶
StoreManagerConfig holds configuration for StoreManager initialization.
type TaskRecord ¶ added in v0.260507.1
type TaskRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;column:id"`
TaskID string `gorm:"uniqueIndex;column:task_id;not null;size:64"`
Type string `gorm:"column:type;not null;size:128"`
Status string `gorm:"column:status;not null;size:32;index:idx_tasks_status_scheduled"`
OwnerType string `gorm:"column:owner_type;size:64;index:idx_tasks_owner"`
OwnerID string `gorm:"column:owner_id;size:64;index:idx_tasks_owner"`
Source string `gorm:"column:source;size:64"`
SerializationKey string `gorm:"column:serialization_key;size:256;index:idx_tasks_key_status"`
Payload string `gorm:"column:payload;type:text"`
Result string `gorm:"column:result;type:text"`
Progress string `gorm:"column:progress;size:512"`
Error string `gorm:"column:error;type:text"`
Attempt int `gorm:"column:attempt;default:0"`
MaxAttempts int `gorm:"column:max_attempts;default:1"`
ScheduledAt *time.Time `gorm:"column:scheduled_at;index:idx_tasks_status_scheduled"`
StartedAt *time.Time `gorm:"column:started_at"`
FinishedAt *time.Time `gorm:"column:finished_at"`
CancelledAt *time.Time `gorm:"column:cancelled_at"`
// Recurrence and ParentTaskID are reserved for Phase 4 (recurring tasks).
Recurrence string `gorm:"column:recurrence;type:text"`
ParentTaskID string `gorm:"column:parent_task_id;size:64"`
CreatedAt time.Time `gorm:"column:created_at;index:idx_tasks_owner;index:idx_tasks_key_status"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
TaskRecord is the GORM model for the tasks table.
func (TaskRecord) TableName ¶ added in v0.260507.1
func (TaskRecord) TableName() string
type TaskStore ¶ added in v0.260507.1
type TaskStore struct {
// contains filtered or unexported fields
}
TaskStore persists and retrieves tasks using a shared GORM DB.
func (*TaskStore) FindDueTasks ¶ added in v0.260507.1
func (*TaskStore) FindQueuedForKey ¶ added in v0.260507.1
func (*TaskStore) MarkInterruptedOnStartup ¶ added in v0.260507.1
type TimeSeriesData ¶
type TimeSeriesData struct {
Timestamp string `json:"timestamp"`
RequestCount int64 `json:"request_count"`
TotalTokens int64 `json:"total_tokens"`
InputTokens int64 `json:"input_tokens"`
OutputTokens int64 `json:"output_tokens"`
CacheReadTokens int64 `json:"cache_read_tokens"`
CacheWriteTokens int64 `json:"cache_write_tokens"`
SystemTokens int64 `json:"system_tokens"`
ErrorCount int64 `json:"error_count"`
AvgLatencyMs float64 `json:"avg_latency_ms"`
}
TimeSeriesData represents a single time bucket in time series data
type ToolConfigRecord ¶
type ToolConfigRecord struct {
UUID string `gorm:"primaryKey;column:uuid"`
ProviderUUID string `gorm:"column:provider_uuid;not null;index:idx_provider_uuid"`
ToolType string `gorm:"column:tool_type;not null;index:idx_tool_type"`
ConfigJSON string `gorm:"column:config_json;type:text"`
Disabled bool `gorm:"column:disabled;default:false"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
ToolConfigRecord is the GORM model for persisting provider-specific tool configurations
func (ToolConfigRecord) TableName ¶
func (ToolConfigRecord) TableName() string
TableName specifies the table name for GORM
type ToolConfigStore ¶
type ToolConfigStore struct {
// contains filtered or unexported fields
}
ToolConfigStore manages provider-specific tool configurations
func NewToolConfigStore ¶
func NewToolConfigStore(baseDir string) (*ToolConfigStore, error)
NewToolConfigStore creates or loads a tool config store using SQLite database. It uses the same database file as the provider store.
func (*ToolConfigStore) Close ¶
func (tcs *ToolConfigStore) Close() error
Close closes the database connection
func (*ToolConfigStore) Delete ¶
func (tcs *ToolConfigStore) Delete(uuid string) error
Delete removes a tool config by UUID
func (*ToolConfigStore) DeleteByProvider ¶
func (tcs *ToolConfigStore) DeleteByProvider(providerUUID string) error
DeleteByProvider removes all tool configs for a provider
func (*ToolConfigStore) GetByProvider ¶
func (tcs *ToolConfigStore) GetByProvider(providerUUID string) ([]*ToolConfigRecord, error)
GetByProvider returns all tool configs for a provider
func (*ToolConfigStore) GetByProviderAndType ¶
func (tcs *ToolConfigStore) GetByProviderAndType(providerUUID string, toolType string) (*ToolConfigRecord, error)
GetByProviderAndType returns a tool config by provider UUID and tool type
func (*ToolConfigStore) GetDB ¶
func (tcs *ToolConfigStore) GetDB() *gorm.DB
GetDB returns the underlying GORM DB instance (for testing/advanced usage)
func (*ToolConfigStore) GetToolConfig ¶
func (tcs *ToolConfigStore) GetToolConfig(providerUUID, toolType string, target interface{}) (disabled, found bool, err error)
GetToolConfig returns the config for a specific provider and tool type (generic) target is a pointer to the config struct to unmarshal into Returns (disabled, found, error) - disabled: true if the tool is explicitly disabled for this provider - found: true if a config record exists for this provider/tool type - error: any unmarshaling error
func (*ToolConfigStore) Save ¶
func (tcs *ToolConfigStore) Save(config *ToolConfigRecord) error
Save saves a tool config (create or update)
func (*ToolConfigStore) SetToolConfig ¶
func (tcs *ToolConfigStore) SetToolConfig(providerUUID, toolType string, config interface{}, disabled bool) (string, error)
SetToolConfig sets the config for a specific provider and tool type (generic) config is any struct that can be marshaled to JSON Returns the UUID of the created/updated record
type UsageDailyRecord ¶
type UsageDailyRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;column:id"`
Date string `gorm:"column:date;index:idx_date;uniqueIndex:uq_daily_dim,priority:1;not null"` // YYYY-MM-DD (UTC)
ProviderUUID string `gorm:"column:provider_uuid;uniqueIndex:uq_daily_dim,priority:2;not null"`
ProviderName string `gorm:"column:provider_name;not null"`
Model string `gorm:"column:model;uniqueIndex:uq_daily_dim,priority:3;not null"`
UserID string `gorm:"column:user_id;uniqueIndex:uq_daily_dim,priority:4;not null;default:''"`
RequestCount int64 `gorm:"column:request_count;not null"`
TotalTokens int64 `gorm:"column:total_tokens;not null"`
InputTokens int64 `gorm:"column:input_tokens;not null"`
OutputTokens int64 `gorm:"column:output_tokens;not null"`
// Cache tokens: reads, then writes (a subset of InputTokens)
CacheReadTokens int64 `gorm:"column:cache_input_tokens;default:0"`
CacheWriteTokens int64 `gorm:"column:cache_write_tokens;default:0"`
// System tokens
SystemTokens int64 `gorm:"column:system_tokens;default:0"`
ErrorCount int64 `gorm:"column:error_count;default:0"`
StreamedCount int64 `gorm:"column:streamed_count;default:0"`
// Sum of latency_ms across the day, so merged averages stay weighted
LatencySumMs int64 `gorm:"column:latency_sum_ms;default:0"`
}
UsageDailyRecord is the GORM model for daily aggregated usage statistics. One row per (UTC day, provider, model, user). Date uses the same day boundary as SQLite's date(timestamp) so daily rows can substitute raw usage_records scans for completed days.
func (UsageDailyRecord) TableName ¶
func (UsageDailyRecord) TableName() string
TableName specifies the table name for GORM
type UsageMonthlyRecord ¶
type UsageMonthlyRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;column:id"`
Year int `gorm:"column:year;not null"`
Month int `gorm:"column:month;not null"`
ProviderUUID string `gorm:"column:provider_uuid;not null"`
ProviderName string `gorm:"column:provider_name;not null"`
Model string `gorm:"column:model;not null"`
RequestCount int64 `gorm:"column:request_count;not null"`
TotalTokens int64 `gorm:"column:total_tokens;not null"`
InputTokens int64 `gorm:"column:input_tokens;not null"`
OutputTokens int64 `gorm:"column:output_tokens;not null"`
// Cache tokens: reads, then writes (a subset of InputTokens)
CacheReadTokens int64 `gorm:"column:cache_input_tokens;default:0"`
CacheWriteTokens int64 `gorm:"column:cache_write_tokens;default:0"`
// System tokens
SystemTokens int64 `gorm:"column:system_tokens;default:0"`
ErrorCount int64 `gorm:"column:error_count;default:0"`
}
UsageMonthlyRecord is the GORM model for monthly aggregated usage statistics
func (UsageMonthlyRecord) TableName ¶
func (UsageMonthlyRecord) TableName() string
TableName specifies the table name for GORM
type UsageRecord ¶
type UsageRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;column:id"`
ProviderUUID string `gorm:"column:provider_uuid;index:idx_provider_model;not null"`
ProviderName string `gorm:"column:provider_name;not null"`
Model string `gorm:"column:model;index:idx_provider_model;not null"`
Scenario string `gorm:"column:scenario;index:idx_scenario;not null"`
RuleUUID string `gorm:"column:rule_uuid;index:idx_rule"`
UserID string `gorm:"column:user_id;index:idx_user;not null;default:''"`
RequestModel string `gorm:"column:request_model"`
Timestamp time.Time `gorm:"column:timestamp;index:idx_timestamp;index:idx_timestamp_scenario;not null"`
InputTokens int `gorm:"column:input_tokens;not null"`
OutputTokens int `gorm:"column:output_tokens;not null"`
TotalTokens int `gorm:"column:total_tokens;index;not null"`
// CacheReadTokens counts cache-READ hits only. Cache writes are billed
// separately (Anthropic cache_creation, OpenAI cache_write_tokens since
// gpt-5.6) and are counted in CacheWriteTokens — which is a SUBSET of
// InputTokens, not an addition to it.
//
// The physical column is still cache_input_tokens: renaming it would mean
// an ALTER on three tables for no behavioral gain, so the legacy name is
// pinned in the tag and the mismatch stops at this line. Raw SQL selects
// alias it (`SUM(cache_input_tokens) as cache_read_tokens`) so Scan binds.
CacheReadTokens int `gorm:"column:cache_input_tokens;default:0"`
CacheWriteTokens int `gorm:"column:cache_write_tokens;default:0"`
// System tokens (framework overhead, templates, etc.)
SystemTokens int `gorm:"column:system_tokens;default:0"`
Status string `gorm:"column:status;index;not null"` // success, error, partial
ErrorCode string `gorm:"column:error_code"`
LatencyMs int `gorm:"column:latency_ms"`
TTFTMs int `gorm:"column:ttft_ms;default:0"`
Streamed bool `gorm:"column:streamed;type:integer"`
}
UsageRecord is the GORM model for persisting individual usage records
func (UsageRecord) TableName ¶
func (UsageRecord) TableName() string
TableName specifies the table name for GORM
type UsageStatsQuery ¶
type UsageStatsQuery struct {
GroupBy string // model, provider, scenario, rule, user, daily, hourly
StartTime time.Time
EndTime time.Time
Provider string
Model string
Scenario string
RuleUUID string
UserID string
Status string
Limit int
SortBy string // total_tokens, request_count, avg_latency
SortOrder string // asc, desc
}
GetAggregatedStats returns aggregated usage statistics based on query parameters
type UsageStore ¶
type UsageStore struct {
// contains filtered or unexported fields
}
UsageStore persists usage records in SQLite using GORM.
func NewUsageStore ¶
func NewUsageStore(baseDir string) (*UsageStore, error)
NewUsageStore creates or loads a usage store using SQLite database.
func (*UsageStore) AggregateToDaily ¶
func (us *UsageStore) AggregateToDaily(date time.Time) (int64, error)
AggregateToDaily (re)builds the usage_daily rows for the UTC day containing the given time. It returns the number of aggregate rows written.
func (*UsageStore) DeleteOlderThan ¶
func (us *UsageStore) DeleteOlderThan(cutoffDate time.Time) (int64, error)
DeleteOlderThan deletes records older than the specified date, together with the daily aggregates derived from them so both views stay consistent.
func (*UsageStore) GetAggregatedStats ¶
func (us *UsageStore) GetAggregatedStats(query UsageStatsQuery) ([]AggregatedStat, error)
GetAggregatedStats returns aggregated statistics. For queries spanning several completed days it combines the usage_daily pre-aggregation table with a raw scan of only the partial edge days (see usage_daily.go), so dashboard loads stay fast regardless of how many raw records accumulate.
func (*UsageStore) GetPerformanceSummary ¶ added in v0.260806.1
func (us *UsageStore) GetPerformanceSummary(startTime, endTime time.Time, filters map[string]string) (PerformanceSummary, error)
GetPerformanceSummary calculates percentiles across the complete filtered range. Only successful requests participate: failures and cancellations have different completion semantics and would distort the user-experience view.
func (*UsageStore) GetRecords ¶
func (us *UsageStore) GetRecords(startTime, endTime time.Time, filters map[string]string, limit, offset int) ([]UsageRecord, int64, error)
GetRecords returns individual usage records (for debugging/audit)
func (*UsageStore) GetRecordsAfterID ¶
func (us *UsageStore) GetRecordsAfterID(lastID uint, startTime time.Time, limit int) ([]UsageRecord, error)
GetRecordsAfterID returns usage records with id greater than lastID. On initial sync, startTime can be used to cap the historical backfill window.
func (*UsageStore) GetTimeSeries ¶
func (us *UsageStore) GetTimeSeries(interval string, startTime, endTime time.Time, filters map[string]string) ([]TimeSeriesData, error)
GetTimeSeries returns time-series data for usage. Day-interval queries spanning several completed days are served from usage_daily with raw scans only for the partial edge days (see usage_daily.go).
func (*UsageStore) RecordUsage ¶
func (us *UsageStore) RecordUsage(record *UsageRecord) error
RecordUsage records a single usage event
func (*UsageStore) RenameRuleUUID ¶ added in v0.260611.1
func (us *UsageStore) RenameRuleUUID(oldUUID, newUUID string) error
RenameRuleUUID re-attributes historical usage records from oldUUID to newUUID so per-rule usage stats survive a rule UUID normalization.