Documentation
¶
Overview ¶
Package controlplane owns Stella's deployment control-plane resources: LLM providers, deployment settings (embedding, CLI-tool registry, OAuth provider config), plugins (registered + manifest), and channels.
These resources are administered, not user-owned. Authorization is a single admin gate at Begin (see access.go): an Access is minted only for an admin authority, so a non-admin actor is denied before any durable read or external action — identical to the legacy requireAdmin gate this service replaces. There is no per-user ownership and no per-method authorization.
The service also owns the persistence and live-reload orchestration each control-plane mutation performs (store writes plus pool/plugin-host hot reloads), so the HTTP transport keeps only request decoding and response shaping. It never reads request-supplied identity: the caller passes a trusted authz.Authority derived from verified session claims.
Index ¶
- Constants
- Variables
- func SettingsDefaultModelDispatch(ctx context.Context, h SettingsDefaultModelHandler, action string, ...) (any, error)
- func SettingsDefaultModelToolNames() []string
- func SettingsEmbeddingSettingDispatch(ctx context.Context, h SettingsEmbeddingSettingHandler, action string, ...) (any, error)
- func SettingsEmbeddingSettingToolNames() []string
- func SettingsPluginDispatch(ctx context.Context, h SettingsPluginHandler, action string, ...) (any, error)
- func SettingsPluginToolNames() []string
- func SettingsProviderDispatch(ctx context.Context, h SettingsProviderHandler, action string, ...) (any, error)
- func SettingsProviderToolNames() []string
- type Access
- func (a *Access) CliToolLatest(ctx context.Context, tool string) (string, error)
- func (a *Access) CreateProvider(ctx context.Context, p config.Provider) error
- func (a *Access) DeleteChannel(ctx context.Context, id string) error
- func (a *Access) DeleteManifestPlugin(ctx context.Context, id string) error
- func (a *Access) DeleteOAuthProviderConfig(ctx context.Context, id string) error
- func (a *Access) DeleteProvider(ctx context.Context, id string) error
- func (a *Access) DeleteProviderIfVersion(ctx context.Context, id, version string) error
- func (a *Access) FetchProviderModels(ctx context.Context, id, apiKey, baseURL string) ([]ProviderModelItem, error)
- func (a *Access) GetChannel(ctx context.Context, id string) (config.Channel, error)
- func (a *Access) GetDefaultModels(ctx context.Context) (config.DefaultModels, error)
- func (a *Access) GetEmbeddingSettings(ctx context.Context) (EmbeddingState, error)
- func (a *Access) GetOAuthProviderConfig(ctx context.Context, id string) (connections.OAuthProviderConfig, error)
- func (a *Access) GetPluginConfig(ctx context.Context, kind, name string) (map[string]any, error)
- func (a *Access) GetPluginConfigSchema(ctx context.Context, kind, name string) (map[string]any, error)
- func (a *Access) GetPluginStatus(ctx context.Context, kind, name string) (any, error)
- func (a *Access) GetProvider(ctx context.Context, id string) (config.Provider, error)
- func (a *Access) GetProviderSnapshot(ctx context.Context, id string) (config.ProviderSnapshot, error)
- func (a *Access) ListChannels(ctx context.Context) ([]config.Channel, error)
- func (a *Access) ListManifestPlugins(ctx context.Context) (*manifest.Manifest, error)
- func (a *Access) ListModelCatalogModels(ctx context.Context) ([]modelcatalog.Model, error)
- func (a *Access) ListModelCatalogProviders(ctx context.Context, includeUnsupported bool) ([]modelcatalog.Provider, error)
- func (a *Access) ListPlugins(ctx context.Context) ([]pkgplugins.RegisteredPlugin, error)
- func (a *Access) ListProviderModelCounts(ctx context.Context, providers []config.Provider) (map[string][2]int, error)
- func (a *Access) ListProviderModels(ctx context.Context, id string) ([]ProviderModelItem, error)
- func (a *Access) ListProviderSnapshots(ctx context.Context) ([]config.ProviderSnapshot, error)
- func (a *Access) ListProviderTypes() ([]host.ProviderType, error)
- func (a *Access) ListProviders(ctx context.Context) ([]config.Provider, error)
- func (a *Access) LookupAgent(ctx context.Context, id string) (config.Agent, error)
- func (a *Access) ManageChannel(id string) (*ChannelManagement, error)
- func (a *Access) ModelCatalogStatus(ctx context.Context) (*modelcatalog.Catalog, modelcatalog.SnapshotRecord, string, error)
- func (a *Access) NormalizeProvider(ctx context.Context, p config.Provider) (config.Provider, error)
- func (a *Access) ProbeProvider(ctx context.Context, apiType, apiKey, baseURL string) ([]ProviderModelItem, error)
- func (a *Access) ProviderModelsSyncedAt(ctx context.Context, id string) (*time.Time, error)
- func (a *Access) ResetManifestPlugin(ctx context.Context, id, field string) (*manifest.Manifest, error)
- func (a *Access) ResolveProviderModel(ctx context.Context, id, modelID string) (modelcatalog.Result, error)
- func (a *Access) SaveChannel(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
- func (a *Access) SaveManifestPluginDefinition(ctx context.Context, plugin manifest.ManifestPlugin, fields []string) (*manifest.Manifest, error)
- func (a *Access) SearchCliToolRegistry(ctx context.Context, query string, limit int) ([]manifest.RegistryTool, error)
- func (a *Access) SetDefaultModels(ctx context.Context, d config.DefaultModels) (config.DefaultModels, error)
- func (a *Access) SetDefaultModelsIfVersion(ctx context.Context, d config.DefaultModels, expectedVersion string) (config.DefaultModels, error)
- func (a *Access) SetEmbeddingSettings(ctx context.Context, upd EmbeddingUpdate) (EmbeddingState, error)
- func (a *Access) SetEmbeddingSettingsIfVersion(ctx context.Context, upd EmbeddingUpdate, expectedVersion string) (EmbeddingState, error)
- func (a *Access) SetManifestPluginEnabled(ctx context.Context, id string, enabled bool) (*manifest.Manifest, error)
- func (a *Access) SetOAuthProviderConfig(ctx context.Context, cfg connections.OAuthProviderConfig) (connections.OAuthProviderConfig, error)
- func (a *Access) SyncManifestPlugins(ctx context.Context) (manifest.ReconcileResult, error)
- func (a *Access) SyncModelCatalog(ctx context.Context) (modelcatalog.SyncResult, error)
- func (a *Access) TogglePlugin(ctx context.Context, kind, name string, enabled bool) (config.Plugin, error)
- func (a *Access) UpdatePluginConfig(ctx context.Context, kind, name string, cfg map[string]any) (config.Plugin, error)
- func (a *Access) UpdateProvider(ctx context.Context, id string, p config.Provider) (config.Provider, error)
- func (a *Access) UpdateProviderIfVersion(ctx context.Context, p config.Provider, version string) (config.Provider, error)
- type AgentChannels
- func (a *AgentChannels) DeleteChannel(ctx context.Context, id string) error
- func (a *AgentChannels) GetChannel(ctx context.Context, id string) (config.Channel, error)
- func (a *AgentChannels) ListChannels(ctx context.Context) ([]config.Channel, error)
- func (a *AgentChannels) SaveChannel(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
- type ChannelAccess
- type ChannelBinding
- type ChannelManagement
- func (m *ChannelManagement) Channel(ctx context.Context, id string) (config.Channel, error)
- func (m *ChannelManagement) Save(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
- func (m *ChannelManagement) ValidateBinding(ctx context.Context, ch config.Channel) error
- type ConflictError
- type EmbeddingState
- type EmbeddingUpdate
- type ForbiddenError
- type ManagementTool
- func NewDefaultModelManagementTool(spec SettingsDefaultModelActionTool, service func() *Service) *ManagementTool
- func NewEmbeddingSettingManagementTool(spec SettingsEmbeddingSettingActionTool, service func() *Service) *ManagementTool
- func NewPluginManagementTool(spec SettingsPluginActionTool, service func() *Service) *ManagementTool
- func NewProviderManagementTool(spec SettingsProviderActionTool, service func() *Service) *ManagementTool
- type NotFoundError
- type ProviderModelItem
- type PublicChannel
- type Service
- func (s *Service) Begin(_ context.Context, authority authz.Authority) (*Access, error)
- func (s *Service) BeginAgentChannels(_ context.Context, authority authz.Authority, managedAgentIDs []string) (*AgentChannels, error)
- func (s *Service) BeginChannelBinding(ctx context.Context, authority authz.Authority, channelID string) (*ChannelBinding, error)
- func (s *Service) DisabledChannelTypes(ctx context.Context, authority authz.Authority) (map[string]bool, error)
- func (s *Service) ListEnabledModels(ctx context.Context, authority authz.Authority) ([]config.CachedModel, error)
- func (s *Service) PublicChannels(ctx context.Context, authority authz.Authority) ([]PublicChannel, error)
- func (s *Service) SetModelCatalog(catalog *modelcatalog.Catalog)
- type SettingsDefaultModelActionTool
- type SettingsDefaultModelGetInput
- type SettingsDefaultModelHandler
- type SettingsDefaultModelUpdateInput
- type SettingsEmbeddingSettingActionTool
- type SettingsEmbeddingSettingGetInput
- type SettingsEmbeddingSettingHandler
- type SettingsEmbeddingSettingUpdateInput
- type SettingsPluginActionTool
- type SettingsPluginDisableInput
- type SettingsPluginEnableInput
- type SettingsPluginHandler
- type SettingsPluginListInput
- type SettingsProviderActionTool
- type SettingsProviderCreateInput
- type SettingsProviderDeleteInput
- type SettingsProviderGetInput
- type SettingsProviderHandler
- type SettingsProviderListInput
- type SettingsProviderUpdateInput
- type UpstreamError
- type ValidationError
Constants ¶
const ChannelPluginConfigError = "channel instance config lives on /channels, not plugin config"
ChannelPluginConfigError is the client message returned when an admin tries to read or write a channel plugin's config through the plugin API; channel instance config lives on the /channels surface instead.
const SettingsDefaultModelToolPrefix = "settings_default_model"
SettingsDefaultModelToolPrefix is the family every generated settings_default_model tool name starts with.
const SettingsEmbeddingSettingToolPrefix = "settings_embedding_setting"
SettingsEmbeddingSettingToolPrefix is the family every generated settings_embedding_setting tool name starts with.
const SettingsPluginToolPrefix = "settings_plugin"
SettingsPluginToolPrefix is the family every generated settings_plugin tool name starts with.
const SettingsProviderToolPrefix = "settings_provider"
SettingsProviderToolPrefix is the family every generated settings_provider tool name starts with.
Variables ¶
ErrUnavailable is returned when the service itself is not configured (a nil receiver); the transport maps it to a fail-closed 503.
Functions ¶
func SettingsDefaultModelDispatch ¶ added in v0.66.0
func SettingsDefaultModelToolNames ¶ added in v0.66.0
func SettingsDefaultModelToolNames() []string
SettingsDefaultModelToolNames lists every generated tool name, for callers that gate on names.
func SettingsEmbeddingSettingDispatch ¶ added in v0.66.0
func SettingsEmbeddingSettingToolNames ¶ added in v0.66.0
func SettingsEmbeddingSettingToolNames() []string
SettingsEmbeddingSettingToolNames lists every generated tool name, for callers that gate on names.
func SettingsPluginDispatch ¶ added in v0.66.0
func SettingsPluginToolNames ¶ added in v0.66.0
func SettingsPluginToolNames() []string
SettingsPluginToolNames lists every generated tool name, for callers that gate on names.
func SettingsProviderDispatch ¶ added in v0.66.0
func SettingsProviderToolNames ¶ added in v0.66.0
func SettingsProviderToolNames() []string
SettingsProviderToolNames lists every generated tool name, for callers that gate on names.
Types ¶
type Access ¶
type Access struct {
// contains filtered or unexported fields
}
Access is one authorized control-plane use case. Every control-plane resource (providers, settings, plugins, channels) is admin-only, so authorization is a single gate at Begin: an Access exists only for an admin authority. Each method then performs the durable write and hot-reload the legacy handler did, with no further per-method authorization.
func (*Access) CliToolLatest ¶
CliToolLatest resolves the latest installable version for a mise tool key.
func (*Access) CreateProvider ¶
CreateProvider validates catalog and adapter references, applies stable defaults, then persists the provider and hot-reloads the pool.
func (*Access) DeleteChannel ¶
DeleteChannel stops a channel's runtime and removes it.
func (*Access) DeleteManifestPlugin ¶ added in v0.63.2
DeleteManifestPlugin removes an admin-added plugin: its override row is the whole definition, so dropping it drops the plugin. A builtin ships with the server and is refused — disabling it is the reversible equivalent, and letting a delete "remove" one would only resurrect it on the next resolve. Installed binaries stay in the mise cache, exactly as they do when a plugin is disabled.
func (*Access) DeleteOAuthProviderConfig ¶
DeleteOAuthProviderConfig removes an OAuth provider client configuration.
func (*Access) DeleteProvider ¶
DeleteProvider removes a provider and hot-reloads the pool.
func (*Access) DeleteProviderIfVersion ¶ added in v0.66.0
func (*Access) FetchProviderModels ¶
func (*Access) GetChannel ¶
GetChannel returns one channel by id (opaque 404 when missing).
func (*Access) GetDefaultModels ¶ added in v0.66.0
GetDefaultModels returns the deployment-wide default model configuration.
func (*Access) GetEmbeddingSettings ¶
func (a *Access) GetEmbeddingSettings(ctx context.Context) (EmbeddingState, error)
GetEmbeddingSettings returns the deployment-wide embedding configuration.
func (*Access) GetOAuthProviderConfig ¶
func (a *Access) GetOAuthProviderConfig(ctx context.Context, id string) (connections.OAuthProviderConfig, error)
GetOAuthProviderConfig returns the stored OAuth provider client configuration.
func (*Access) GetPluginConfig ¶
GetPluginConfig returns a plugin's stored config. Channel plugins are rejected: their instance config lives on /channels.
func (*Access) GetPluginConfigSchema ¶
func (a *Access) GetPluginConfigSchema(ctx context.Context, kind, name string) (map[string]any, error)
GetPluginConfigSchema returns a plugin's admin config schema.
func (*Access) GetPluginStatus ¶
GetPluginStatus returns a plugin's admin status payload.
func (*Access) GetProvider ¶
GetProvider returns one provider by id (opaque 404 when missing).
func (*Access) GetProviderSnapshot ¶ added in v0.66.0
func (a *Access) GetProviderSnapshot(ctx context.Context, id string) (config.ProviderSnapshot, error)
GetProviderSnapshot returns settings-safe fields and the CAS version from one durable read. Keeping them together prevents a stale projection from inheriting a newer version and overwriting an intervening admin change.
func (*Access) ListChannels ¶
func (*Access) ListManifestPlugins ¶
ListManifestPlugins returns the builtin manifest overlaid with DB overrides.
func (*Access) ListModelCatalogModels ¶ added in v0.66.0
func (*Access) ListModelCatalogProviders ¶ added in v0.66.0
func (a *Access) ListModelCatalogProviders(ctx context.Context, includeUnsupported bool) ([]modelcatalog.Provider, error)
ResolveProviderModel exposes the same effective merge used by the model list and runtime snapshot, preventing evidence and billing from drifting apart.
func (*Access) ListPlugins ¶
func (a *Access) ListPlugins(ctx context.Context) ([]pkgplugins.RegisteredPlugin, error)
ListPlugins returns the admin-visible registered plugins. The transport shapes each into its admin view.
func (*Access) ListProviderModelCounts ¶ added in v0.66.0
func (a *Access) ListProviderModelCounts(ctx context.Context, providers []config.Provider) (map[string][2]int, error)
ListProviderModelCounts computes projections from one provider, cache, and catalog read. It deliberately does not call mergedProviderModels per row.
func (*Access) ListProviderModels ¶
ListProviderModels returns the merged custom+fetched model list for a provider.
func (*Access) ListProviderSnapshots ¶ added in v0.66.0
func (*Access) ListProviderTypes ¶
func (a *Access) ListProviderTypes() ([]host.ProviderType, error)
ListProviderTypes returns the provider plugin types the deployment can add.
func (*Access) ListProviders ¶
ListProviders returns every configured LLM provider.
func (*Access) LookupAgent ¶
LookupAgent reads an agent for a channel-binding precondition: a registration flow binds a channel to an agent that must exist and be enabled. It is an admin-gated read (the Access already passed Begin), so a non-admin never reaches it; the caller inspects the returned agent's Enabled flag.
func (*Access) ManageChannel ¶
func (a *Access) ManageChannel(id string) (*ChannelManagement, error)
ManageChannel opens a channel-management operation. The admin gate already ran at Begin, so this only hands back the operation handle; id is retained for call-site symmetry (registration flows keep this handle across their platform handshake, then call Save after credentials arrive).
func (*Access) ModelCatalogStatus ¶ added in v0.66.0
func (a *Access) ModelCatalogStatus(ctx context.Context) (*modelcatalog.Catalog, modelcatalog.SnapshotRecord, string, error)
func (*Access) NormalizeProvider ¶ added in v0.66.0
NormalizeProvider resolves catalog-backed defaults without guessing a catalog vendor from a generic adapter type. Explicit operator values always win.
func (*Access) ProbeProvider ¶ added in v0.66.0
func (a *Access) ProbeProvider(ctx context.Context, apiType, apiKey, baseURL string) ([]ProviderModelItem, error)
ProbeProvider lists models without creating a provider row or touching the fetched cache. It is the atomic pre-create validation boundary for the UI.
func (*Access) ProviderModelsSyncedAt ¶ added in v0.66.0
FetchProviderModels lists the provider's models from its live API, refreshes the cached set, and returns the merged list. Credentials fall back to the stored provider when the caller omits them. It preserves the legacy status split: a missing provider during the credential fallback is a 400 "api_key is required", while the authoritative load is a 404.
func (*Access) ResetManifestPlugin ¶ added in v0.63.2
func (a *Access) ResetManifestPlugin(ctx context.Context, id, field string) (*manifest.Manifest, error)
ResetManifestPlugin hands a builtin's definition back to the server, either one field of it or all of it. The enable switch is a separate decision and survives either way: "stop customizing this" is not "turn it on".
Releasing one field from a row written before overrides went sparse converts it first. That conversion is lossless — such a row owns every field, including the ones its JSON omits and therefore owns as empty — so the other fields stay pinned exactly where they were, and only the named one starts following the server again.
An admin-added plugin has no definition to fall back to, so resetting one is refused — deleting it is the operation that means anything there.
func (*Access) ResolveProviderModel ¶ added in v0.66.0
func (*Access) SaveChannel ¶
func (a *Access) SaveChannel(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
SaveChannel validates and persists a channel, ensures its plugin is enabled, and applies its runtime. create=true rejects an id that already exists (the create-only POST contract). It returns the reloaded channel.
func (*Access) SaveManifestPluginDefinition ¶ added in v0.63.2
func (a *Access) SaveManifestPluginDefinition(ctx context.Context, plugin manifest.ManifestPlugin, fields []string) (*manifest.Manifest, error)
SaveManifestPluginDefinition records the fields this request takes ownership of and leaves every other field of the row alone.
fields is the contract: a builtin's row grows exactly those keys, at the submitted values, on top of whatever it already owned. Deriving them here by diffing against the shipped definition is what this replaces — that quietly released a pinned field whenever a release happened to ship the same value.
An admin-added plugin has no definition underneath it, so its row is the whole plugin and fields does not apply; its enable state travels with it, because there is no shipped default to fall back to.
func (*Access) SearchCliToolRegistry ¶
func (a *Access) SearchCliToolRegistry(ctx context.Context, query string, limit int) ([]manifest.RegistryTool, error)
SearchCliToolRegistry searches the mise tool registry so the UI can add a CLI tool by name instead of a hand-written backend key.
func (*Access) SetDefaultModels ¶ added in v0.66.0
func (a *Access) SetDefaultModels(ctx context.Context, d config.DefaultModels) (config.DefaultModels, error)
SetDefaultModels persists the deployment-wide default models and rebuilds the runner factories so newly admitted runners see them. An empty field clears that role; a non-empty one must carry its provider prefix, since unlike an agent tier there is no agent context to infer a provider from and a bare model name would resolve differently per agent.
Only shape is validated, not provider existence: a provider row can be deleted after a default references it, so "this provider is configured" is not an invariant a write-time check can hold, and a fresh deployment legitimately names its models before the provider rows exist.
func (*Access) SetDefaultModelsIfVersion ¶ added in v0.66.0
func (a *Access) SetDefaultModelsIfVersion(ctx context.Context, d config.DefaultModels, expectedVersion string) (config.DefaultModels, error)
SetDefaultModelsIfVersion is the atomic Settings-tool write path. The raw app_setting value is compared in SQL, so a concurrent UI write cannot be overwritten after the tool's read.
func (*Access) SetEmbeddingSettings ¶
func (a *Access) SetEmbeddingSettings(ctx context.Context, upd EmbeddingUpdate) (EmbeddingState, error)
SetEmbeddingSettings persists the embedding lane's knobs.
Enabling the lane before its model resolves is allowed on purpose. The model lives in DefaultModels, so the two are separate writes, and rejecting here would make the admin's success depend on which one they saved first — with a half-applied deployment whenever the second call failed. config.ResolveEmbedding treats an unresolvable reference as disabled instead, so the stored flag is an intent that turns itself on the moment the model behind it resolves.
func (*Access) SetEmbeddingSettingsIfVersion ¶ added in v0.66.0
func (a *Access) SetEmbeddingSettingsIfVersion(ctx context.Context, upd EmbeddingUpdate, expectedVersion string) (EmbeddingState, error)
SetEmbeddingSettingsIfVersion closes the read/write race for a Settings tool while leaving the existing HTTP write contract untouched.
func (*Access) SetManifestPluginEnabled ¶ added in v0.63.2
func (a *Access) SetManifestPluginEnabled(ctx context.Context, id string, enabled bool) (*manifest.Manifest, error)
SetManifestPluginEnabled turns one plugin on or off. The enable switch is its own column, so this never touches the definition override: "turn this off" and "stop customizing this" stay independent decisions.
func (*Access) SetOAuthProviderConfig ¶
func (a *Access) SetOAuthProviderConfig(ctx context.Context, cfg connections.OAuthProviderConfig) (connections.OAuthProviderConfig, error)
SetOAuthProviderConfig persists an OAuth provider client configuration and returns the refreshed stored value.
func (*Access) SyncManifestPlugins ¶
SyncManifestPlugins reconciles the merged manifest against the filesystem (installs binaries/skills) and returns the reconcile result.
func (*Access) SyncModelCatalog ¶ added in v0.66.0
func (a *Access) SyncModelCatalog(ctx context.Context) (modelcatalog.SyncResult, error)
func (*Access) TogglePlugin ¶
func (a *Access) TogglePlugin(ctx context.Context, kind, name string, enabled bool) (config.Plugin, error)
TogglePlugin enables/disables a plugin and hot-reloads its runtime.
func (*Access) UpdatePluginConfig ¶
func (a *Access) UpdatePluginConfig(ctx context.Context, kind, name string, cfg map[string]any) (config.Plugin, error)
UpdatePluginConfig validates and persists a plugin's config, then hot-reloads its runtime. Channel plugins are rejected (config lives on /channels).
func (*Access) UpdateProvider ¶
func (a *Access) UpdateProvider(ctx context.Context, id string, p config.Provider) (config.Provider, error)
UpdateProvider merges the request over the stored provider (preserving Type and defaulting Name), persists it, and hot-reloads the pool. It returns the merged provider so the transport can echo it.
func (*Access) UpdateProviderIfVersion ¶ added in v0.66.0
func (a *Access) UpdateProviderIfVersion(ctx context.Context, p config.Provider, version string) (config.Provider, error)
UpdateProviderIfVersion writes only when the database row still has the version the Settings tool read. This protects a hidden key from being copied over a concurrent credential change.
type AgentChannels ¶ added in v0.63.2
type AgentChannels struct {
// contains filtered or unexported fields
}
AgentChannels is channel management confined to one caller's agents.
A channel is an agent's phone number, so the person who owns the agent owns its channels: they hold the bot token, they answer for what it says. The deployment-wide control plane stays admin-only — this reaches exactly the channels bound to agents the caller may manage, and a channel outside that set is as opaque as a missing one.
func (*AgentChannels) DeleteChannel ¶ added in v0.63.2
func (a *AgentChannels) DeleteChannel(ctx context.Context, id string) error
DeleteChannel removes one of the caller's channels.
func (*AgentChannels) GetChannel ¶ added in v0.63.2
GetChannel returns one of the caller's channels; anything else is a 404.
func (*AgentChannels) ListChannels ¶ added in v0.63.2
ListChannels returns the channels bound to the caller's agents.
func (*AgentChannels) SaveChannel ¶ added in v0.63.2
func (a *AgentChannels) SaveChannel(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
SaveChannel persists a channel that stays bound to one of the caller's agents. Both ends are checked: an update must target a channel they already own, and the saved row must still name an agent they manage — so a channel can neither be taken from another owner nor handed to an agent the caller cannot manage.
type ChannelAccess ¶ added in v0.63.2
type ChannelAccess interface {
ListChannels(ctx context.Context) ([]config.Channel, error)
GetChannel(ctx context.Context, id string) (config.Channel, error)
SaveChannel(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
DeleteChannel(ctx context.Context, id string) error
}
ChannelAccess is the channel-management surface the transport talks to. Two authorized implementations satisfy it: the admin Access, which reaches every channel in the deployment, and AgentChannels, which reaches only the channels of the agents its caller manages. The handlers are identical either way — the scope decision is made once, when the access is opened.
type ChannelBinding ¶ added in v0.62.0
type ChannelBinding struct {
// contains filtered or unexported fields
}
ChannelBinding is one authorized channel→agent binding operation.
Channel administration — credentials, naming, enablement, deletion — stays admin-only behind Begin. Choosing which agent answers on a channel is a per-user action instead, so it gets its own narrow gate here rather than widening the admin Access or letting the transport write the row directly. The operation only ever moves AgentID: the stored config (channel credentials) is carried through untouched, and it reuses the same persist + plugin-apply path as an admin save, including the (agent, platform) binding invariant.
func (*ChannelBinding) Bind ¶ added in v0.62.0
func (b *ChannelBinding) Bind(ctx context.Context, agentID string) (PublicChannel, error)
Bind points the channel at agentID, or unbinds it when agentID is empty, and returns the secret-free projection of the saved row. A bound agent must exist and be enabled; the caller's authority over that agent was already decided.
func (*ChannelBinding) CurrentAgentID ¶ added in v0.62.0
func (b *ChannelBinding) CurrentAgentID() string
CurrentAgentID is the agent this channel is bound to right now, empty when it is unbound. The caller needs it to authorize taking the channel away from its current owner.
type ChannelManagement ¶
type ChannelManagement struct {
// contains filtered or unexported fields
}
ChannelManagement is one channel-management operation. Its Save method owns the channel row plus the required channel plugin enable/apply as a single unit, so callers never need a second plugin call.
func (*ChannelManagement) Channel ¶
Channel reads the current row for this operation's channel so a caller can merge a partial update onto it. It is an admin-gated read (Begin already ran); a missing channel returns an error the caller treats as "start from a fresh row" rather than a hard failure.
func (*ChannelManagement) Save ¶
func (m *ChannelManagement) Save(ctx context.Context, ch config.Channel, cfgMap map[string]any, create bool) (config.Channel, error)
Save persists the already-authorized channel and applies its plugin as one control-plane operation. It intentionally makes no further authorization call.
func (*ChannelManagement) ValidateBinding ¶
ListChannels returns every configured channel. ValidateBinding checks the durable channel-binding invariant before an enrollment flow performs an external handshake. Save repeats the check and the database unique index closes the concurrent-write race.
type ConflictError ¶
type ConflictError struct{ Msg string }
ConflictError reports a create that collides with an existing resource, mapped to 409 by the transport. It is returned only after authorization succeeds.
func (*ConflictError) Error ¶
func (e *ConflictError) Error() string
type EmbeddingState ¶ added in v0.66.0
type EmbeddingState struct {
Settings config.EmbeddingSettings
Active bool
}
EmbeddingState is the lane as an admin needs to see it: what is stored, plus whether it is actually running. The two differ whenever the embedding model does not resolve to a provider with a key, and only the server can tell — which is why Active travels with the settings instead of being re-derived in the browser from a partial view of the catalog.
type EmbeddingUpdate ¶
EmbeddingUpdate carries a validated embedding-settings write. It covers only the lane's own knobs: the embedding model and its credentials are named in DefaultModels alongside every other model role.
type ForbiddenError ¶
type ForbiddenError struct{ Msg string }
ForbiddenError reports a control-plane precondition that forbids an operation for a reason other than the admin gate (e.g. a resource locked by an environment override). It maps to 403 with Msg, distinct from the opaque authz.ErrForbidden denial, and is only ever returned after authorization succeeds so it never leaks to an unauthorized caller.
func (*ForbiddenError) Error ¶
func (e *ForbiddenError) Error() string
type ManagementTool ¶ added in v0.66.0
type ManagementTool struct {
// contains filtered or unexported fields
}
ManagementTool is one Stella-only deployment action. It obtains both direct human authority and the control-plane admin capability at execution time so a cached catalog cannot turn a role change into a write capability.
func NewDefaultModelManagementTool ¶ added in v0.66.0
func NewDefaultModelManagementTool(spec SettingsDefaultModelActionTool, service func() *Service) *ManagementTool
func NewEmbeddingSettingManagementTool ¶ added in v0.66.0
func NewEmbeddingSettingManagementTool(spec SettingsEmbeddingSettingActionTool, service func() *Service) *ManagementTool
func NewPluginManagementTool ¶ added in v0.66.0
func NewPluginManagementTool(spec SettingsPluginActionTool, service func() *Service) *ManagementTool
func NewProviderManagementTool ¶ added in v0.66.0
func NewProviderManagementTool(spec SettingsProviderActionTool, service func() *Service) *ManagementTool
func (*ManagementTool) Definition ¶ added in v0.66.0
func (t *ManagementTool) Definition() tools.Definition
type NotFoundError ¶
type NotFoundError struct{ Msg string }
NotFoundError reports a control-plane resource that does not exist. Msg carries the historical per-resource client message so the transport preserves the 404 body byte-for-byte.
func (*NotFoundError) Error ¶
func (e *NotFoundError) Error() string
type ProviderModelItem ¶
type ProviderModelItem struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Source string `json:"source"`
Enabled bool `json:"enabled"`
Config config.ProviderModel `json:"config,omitzero"`
Override *config.ProviderModelOverride `json:"override,omitempty"`
Catalog *modelcatalog.Model `json:"catalog,omitempty"`
}
ProviderModelItem is one merged model entry for a provider: custom (config-declared) models plus fetched (cached) models, unioned. Kept here with the persistence it derives from; the transport writes it directly.
type PublicChannel ¶
type PublicChannel struct {
ID string
Type string // effective type: the configured type, or the id when unset
AgentID string
Enabled bool
}
PublicChannel is the config-secret-free projection of a channel for the user-facing channel list. It deliberately omits the raw Config JSON that config.Channel carries (channel credentials), exposing only the fields the public list renders.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service owns the control-plane resources: the persistence and runtime handles a control-plane mutation needs to apply and hot-reload changes. Authorization is the admin gate in Begin (see access.go); a nil receiver fails closed.
func NewService ¶
func NewService(store config.Store, plugins *pluginhost.Host, pools *agent.PoolManager, conns *connections.Service, log *slog.Logger) *Service
NewService builds the control-plane service from its fully-wired dependencies. The composition root constructs it once and shares the same instance behind the HTTP endpoints. log defaults to slog.Default() when nil.
func (*Service) Begin ¶
Begin authorizes one control-plane use case. The control plane is administered, not user-owned: it validates the Authority and requires IsAdmin exactly once, so a non-admin or invalid authority fails closed here, before any durable read or external action — identical to the legacy requireAdmin gate this replaces. The handler never inspects identity beyond passing the trusted Authority.
func (*Service) BeginAgentChannels ¶ added in v0.63.2
func (s *Service) BeginAgentChannels(_ context.Context, authority authz.Authority, managedAgentIDs []string) (*AgentChannels, error)
BeginAgentChannels opens agent-scoped channel management for the agents the caller was already found to manage.
The Agent decision is deliberately not made here: the caller must clear the Agent PEP for every id it passes, so the "which agents may this user manage" rule stays in the one domain that owns it — the same split BeginChannelBinding uses. An empty set is forbidden rather than an empty listing, so a user with no agents of their own cannot probe channel ids at all.
func (*Service) BeginChannelBinding ¶ added in v0.62.0
func (s *Service) BeginChannelBinding(ctx context.Context, authority authz.Authority, channelID string) (*ChannelBinding, error)
BeginChannelBinding authorizes rebinding one channel's agent for a signed-in caller and loads the target row. Any valid user principal may bind, but a non-admin may only touch an enabled channel; a disabled channel is as opaque to them as a missing one, so both fail as 404.
The Agent decisions are deliberately not made here: the caller must clear the Agent PEP for CurrentAgentID (when set) and for the agent it binds, so the "which agents may this user use" rule stays in the one domain that owns it.
func (*Service) DisabledChannelTypes ¶ added in v0.63.2
func (s *Service) DisabledChannelTypes(ctx context.Context, authority authz.Authority) (map[string]bool, error)
DisabledChannelTypes returns the set of channel-plugin names an admin has explicitly switched off, used by the transport to hide their channels.
A platform is usable unless an admin explicitly switched it off, so this reads the stored override rows rather than the merged plugin list: the builtin default for a channel plugin is "disabled" (a platform with no channel has nothing to run), and treating that default as a veto would hide every channel whose plugin row nobody flipped on. The runtime applies the same rule to instances (RuntimeHost.channelPlatformDisabled), so creating a channel needs no plugin row at all.
func (*Service) ListEnabledModels ¶
func (s *Service) ListEnabledModels(ctx context.Context, authority authz.Authority) ([]config.CachedModel, error)
ListEnabledModels returns the models available for selection: enabled models from enabled providers, plus fetched-cache models whose provider is enabled, deduplicated by provider/model and sorted. It performs no provider API calls.
func (*Service) PublicChannels ¶
func (s *Service) PublicChannels(ctx context.Context, authority authz.Authority) ([]PublicChannel, error)
PublicChannels returns the secret-free projection of every configured channel for the user-facing channel list. The transport filters visibility by the caller's agent access and the enabled plugin types; this only supplies the projected rows.
func (*Service) SetModelCatalog ¶ added in v0.66.0
func (s *Service) SetModelCatalog(catalog *modelcatalog.Catalog)
SetModelCatalog installs the process-wide catalog snapshot after startup or synchronization. Callers may replace it atomically between requests.
type SettingsDefaultModelActionTool ¶ added in v0.66.0
type SettingsDefaultModelActionTool = toolmeta.ActionTool
SettingsDefaultModelActionTool describes one generated tool: an exact schema bound to one action.
func SettingsDefaultModelActionTools ¶ added in v0.66.0
func SettingsDefaultModelActionTools() []SettingsDefaultModelActionTool
SettingsDefaultModelActionTools lists every generated tool in a stable order.
type SettingsDefaultModelGetInput ¶ added in v0.66.0
type SettingsDefaultModelGetInput struct {
}
type SettingsDefaultModelHandler ¶ added in v0.66.0
type SettingsDefaultModelHandler interface {
Get(context.Context, SettingsDefaultModelGetInput) (any, error)
Update(context.Context, SettingsDefaultModelUpdateInput) (any, error)
}
type SettingsDefaultModelUpdateInput ¶ added in v0.66.0
type SettingsDefaultModelUpdateInput struct {
ExpectedVersion string `json:"expected_version,omitempty"`
Model string `json:"model,omitempty"`
ModelEmbedding string `json:"model_embedding,omitempty"`
ModelFast string `json:"model_fast,omitempty"`
ModelFastThinking string `json:"model_fast_thinking,omitempty"`
ModelStrong string `json:"model_strong,omitempty"`
ModelStrongThinking string `json:"model_strong_thinking,omitempty"`
ModelThinking string `json:"model_thinking,omitempty"`
ModelVision string `json:"model_vision,omitempty"`
}
type SettingsEmbeddingSettingActionTool ¶ added in v0.66.0
type SettingsEmbeddingSettingActionTool = toolmeta.ActionTool
SettingsEmbeddingSettingActionTool describes one generated tool: an exact schema bound to one action.
func SettingsEmbeddingSettingActionTools ¶ added in v0.66.0
func SettingsEmbeddingSettingActionTools() []SettingsEmbeddingSettingActionTool
SettingsEmbeddingSettingActionTools lists every generated tool in a stable order.
type SettingsEmbeddingSettingGetInput ¶ added in v0.66.0
type SettingsEmbeddingSettingGetInput struct {
}
type SettingsEmbeddingSettingHandler ¶ added in v0.66.0
type SettingsEmbeddingSettingHandler interface {
Get(context.Context, SettingsEmbeddingSettingGetInput) (any, error)
Update(context.Context, SettingsEmbeddingSettingUpdateInput) (any, error)
}
type SettingsEmbeddingSettingUpdateInput ¶ added in v0.66.0
type SettingsPluginActionTool ¶ added in v0.66.0
type SettingsPluginActionTool = toolmeta.ActionTool
SettingsPluginActionTool describes one generated tool: an exact schema bound to one action.
func SettingsPluginActionTools ¶ added in v0.66.0
func SettingsPluginActionTools() []SettingsPluginActionTool
SettingsPluginActionTools lists every generated tool in a stable order.
type SettingsPluginDisableInput ¶ added in v0.66.0
type SettingsPluginEnableInput ¶ added in v0.66.0
type SettingsPluginHandler ¶ added in v0.66.0
type SettingsPluginHandler interface {
Disable(context.Context, SettingsPluginDisableInput) (any, error)
Enable(context.Context, SettingsPluginEnableInput) (any, error)
List(context.Context, SettingsPluginListInput) (any, error)
}
type SettingsPluginListInput ¶ added in v0.66.0
type SettingsPluginListInput struct {
}
type SettingsProviderActionTool ¶ added in v0.66.0
type SettingsProviderActionTool = toolmeta.ActionTool
SettingsProviderActionTool describes one generated tool: an exact schema bound to one action.
func SettingsProviderActionTools ¶ added in v0.66.0
func SettingsProviderActionTools() []SettingsProviderActionTool
SettingsProviderActionTools lists every generated tool in a stable order.
type SettingsProviderCreateInput ¶ added in v0.66.0
type SettingsProviderCreateInput struct {
BaseUrl string `json:"base_url,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Id string `json:"id,omitempty"`
Models map[string]struct {
CatalogModel string `json:"catalogModel,omitempty"`
ContextWindow int `json:"contextWindow,omitempty"`
Cost struct {
CacheRead float64 `json:"cacheRead,omitempty"`
CacheWrite float64 `json:"cacheWrite,omitempty"`
Input float64 `json:"input,omitempty"`
InputAudio float64 `json:"inputAudio,omitempty"`
Output float64 `json:"output,omitempty"`
OutputAudio float64 `json:"outputAudio,omitempty"`
Reasoning float64 `json:"reasoning,omitempty"`
Tiers []struct {
CacheRead float64 `json:"cacheRead,omitempty"`
CacheWrite float64 `json:"cacheWrite,omitempty"`
Input float64 `json:"input,omitempty"`
InputAudio float64 `json:"inputAudio,omitempty"`
MinContext int `json:"minContext,omitempty"`
Output float64 `json:"output,omitempty"`
OutputAudio float64 `json:"outputAudio,omitempty"`
Reasoning float64 `json:"reasoning,omitempty"`
} `json:"tiers,omitempty"`
} `json:"cost,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Id string `json:"id,omitempty"`
Input []string `json:"input,omitempty"`
MaxTokens int `json:"maxTokens,omitempty"`
Name string `json:"name,omitempty"`
Output []string `json:"output,omitempty"`
Reasoning *bool `json:"reasoning,omitempty"`
} `json:"models,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
}
type SettingsProviderDeleteInput ¶ added in v0.66.0
type SettingsProviderGetInput ¶ added in v0.66.0
type SettingsProviderGetInput struct {
Id string `json:"id,omitempty"`
}
type SettingsProviderHandler ¶ added in v0.66.0
type SettingsProviderHandler interface {
Create(context.Context, SettingsProviderCreateInput) (any, error)
Delete(context.Context, SettingsProviderDeleteInput) (any, error)
Get(context.Context, SettingsProviderGetInput) (any, error)
List(context.Context, SettingsProviderListInput) (any, error)
Update(context.Context, SettingsProviderUpdateInput) (any, error)
}
type SettingsProviderListInput ¶ added in v0.66.0
type SettingsProviderListInput struct {
}
type SettingsProviderUpdateInput ¶ added in v0.66.0
type SettingsProviderUpdateInput struct {
BaseUrl string `json:"base_url,omitempty"`
Enabled bool `json:"enabled,omitempty"`
ExpectedVersion string `json:"expected_version,omitempty"`
Id string `json:"id,omitempty"`
Models map[string]struct {
CatalogModel string `json:"catalogModel,omitempty"`
ContextWindow int `json:"contextWindow,omitempty"`
Cost struct {
CacheRead float64 `json:"cacheRead,omitempty"`
CacheWrite float64 `json:"cacheWrite,omitempty"`
Input float64 `json:"input,omitempty"`
InputAudio float64 `json:"inputAudio,omitempty"`
Output float64 `json:"output,omitempty"`
OutputAudio float64 `json:"outputAudio,omitempty"`
Reasoning float64 `json:"reasoning,omitempty"`
Tiers []struct {
CacheRead float64 `json:"cacheRead,omitempty"`
CacheWrite float64 `json:"cacheWrite,omitempty"`
Input float64 `json:"input,omitempty"`
InputAudio float64 `json:"inputAudio,omitempty"`
MinContext int `json:"minContext,omitempty"`
Output float64 `json:"output,omitempty"`
OutputAudio float64 `json:"outputAudio,omitempty"`
Reasoning float64 `json:"reasoning,omitempty"`
} `json:"tiers,omitempty"`
} `json:"cost,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Id string `json:"id,omitempty"`
Input []string `json:"input,omitempty"`
MaxTokens int `json:"maxTokens,omitempty"`
Name string `json:"name,omitempty"`
Output []string `json:"output,omitempty"`
Reasoning *bool `json:"reasoning,omitempty"`
} `json:"models,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
}
type UpstreamError ¶
type UpstreamError struct{ Err error }
UpstreamError reports a failed call to an external control-plane dependency (e.g. a provider's model-listing endpoint), mapped to 502 by the transport.
func (*UpstreamError) Error ¶
func (e *UpstreamError) Error() string
func (*UpstreamError) Unwrap ¶
func (e *UpstreamError) Unwrap() error
type ValidationError ¶
type ValidationError struct{ Msg string }
ValidationError reports a rejected control-plane input (the legacy 400 path). Msg carries the exact historical client message.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string