Documentation
¶
Overview ¶
Package connectors is the central registry for every connector definition wick will expose via MCP. Downstream apps append to it via app.RegisterConnector; the MCP and admin-UI layers walk All() at boot to validate definitions and seed default instances.
Shape of a connector module (see internal/planning/archive/connectors-design.md for the full design):
- Package under internal/connectors/<name>/ exposing a Meta builder, a typed Creds struct (`wick:"..."` tags), a typed Input struct, and an `Execute(c *connector.Ctx) (any, error)` function.
- Register here inside RegisterBuiltins() (default-on for every wick app — github, httprest) or RegisterLabSamples() (cmd/lab only — crudcrud), or in the downstream project's main.go via app.RegisterConnector.
Connector definitions live in code; per-instance rows (credentials, labels, tags) live in the connector_instances table — populated by the admin UI in a later phase.
Index ¶
- Constants
- Variables
- func AccountDisabledOps(acc *entity.ConnectorAccount) map[string]bool
- func All() []connector.Module
- func OnRegister(fn func(connector.Module))
- func Register(m connector.Module)
- func RegisterBuiltins()
- func RegisterLabSamples()
- func RegisterProfile(profile string)
- type AuditFilter
- type ExecuteParams
- type ExecuteResult
- type HealthCheckResult
- type OpState
- type Repo
- func (r *Repo) ClearSystemDisabled(ctx context.Context, connectorID, opKey string) error
- func (r *Repo) CountByKey(ctx context.Context, key string) (int64, error)
- func (r *Repo) CountRunsAudit(ctx context.Context, f AuditFilter) (int64, error)
- func (r *Repo) CountRunsFiltered(ctx context.Context, connectorID string, f RunFilter) (int64, error)
- func (r *Repo) Create(ctx context.Context, c *entity.Connector) error
- func (r *Repo) CreateRun(ctx context.Context, run *entity.ConnectorRun) error
- func (r *Repo) Delete(ctx context.Context, id string) error
- func (r *Repo) DeleteAccount(ctx context.Context, accountID string) error
- func (r *Repo) FinishRun(ctx context.Context, runID string, status entity.ConnectorRunStatus, ...) error
- func (r *Repo) Get(ctx context.Context, id string) (*entity.Connector, error)
- func (r *Repo) GetAccountByID(ctx context.Context, accountID string) (*entity.ConnectorAccount, error)
- func (r *Repo) GetRun(ctx context.Context, runID string) (*entity.ConnectorRun, error)
- func (r *Repo) IsAccessibleForManager(ctx context.Context, connectorID string, userTagIDs []string) (bool, error)
- func (r *Repo) IsAccessibleTo(ctx context.Context, connectorID string, userTagIDs []string) (bool, error)
- func (r *Repo) IsOperationAdminOnly(ctx context.Context, connectorID, opKey string) (bool, error)
- func (r *Repo) List(ctx context.Context) ([]entity.Connector, error)
- func (r *Repo) ListAccessibleForManager(ctx context.Context, userTagIDs []string) ([]entity.Connector, error)
- func (r *Repo) ListAccessibleTo(ctx context.Context, userTagIDs []string) ([]entity.Connector, error)
- func (r *Repo) ListAccounts(ctx context.Context, connectorID string) ([]entity.ConnectorAccount, error)
- func (r *Repo) ListByKey(ctx context.Context, key string) ([]entity.Connector, error)
- func (r *Repo) ListOperations(ctx context.Context, connectorID string) ([]entity.ConnectorOperation, error)
- func (r *Repo) ListRunsAudit(ctx context.Context, f AuditFilter, limit, offset int) ([]entity.ConnectorRun, error)
- func (r *Repo) ListRunsByConnector(ctx context.Context, connectorID string, limit int) ([]entity.ConnectorRun, error)
- func (r *Repo) ListRunsFiltered(ctx context.Context, connectorID string, f RunFilter, limit, offset int) ([]entity.ConnectorRun, error)
- func (r *Repo) PurgeRunsOlderThan(ctx context.Context, cutoff time.Time) (int64, error)
- func (r *Repo) SetAccessPolicy(ctx context.Context, id string, ...) error
- func (r *Repo) SetAccountDisabledOps(ctx context.Context, accountID, disabledOpsJSON string) error
- func (r *Repo) SetDisabled(ctx context.Context, id string, disabled bool) error
- func (r *Repo) SetOperation(ctx context.Context, connectorID, opKey string, enabled bool) error
- func (r *Repo) SetOperationAdminOnly(ctx context.Context, connectorID, opKey string, adminOnly bool) error
- func (r *Repo) SetRateLimit(ctx context.Context, id string, rpm int) error
- func (r *Repo) SetSessionConfigAllowed(ctx context.Context, id string, allowed bool) error
- func (r *Repo) SetSystemDisabled(ctx context.Context, connectorID, opKey, reason string) error
- func (r *Repo) SummariseRuns(ctx context.Context, f AuditFilter) (RunSummary, error)
- func (r *Repo) Update(ctx context.Context, c *entity.Connector) error
- func (r *Repo) UpsertAccount(ctx context.Context, acc *entity.ConnectorAccount, multiAccount bool) error
- type RunFilter
- type RunSummary
- type Service
- func (s *Service) Bootstrap(ctx context.Context, mods []connector.Module) error
- func (s *Service) CatalogRefresh(ctx context.Context, key, instanceID string)
- func (s *Service) ClearSystemDisabled(ctx context.Context, connectorID, opKey string) error
- func (s *Service) CountRunsAudit(ctx context.Context, f AuditFilter) (int64, error)
- func (s *Service) CountRunsFiltered(ctx context.Context, connectorID string, f RunFilter) (int64, error)
- func (s *Service) Create(ctx context.Context, key, label string, configs map[string]string, ...) (*entity.Connector, error)
- func (s *Service) Delete(ctx context.Context, id string) error
- func (s *Service) DeleteAccount(ctx context.Context, accountID string) error
- func (s *Service) Duplicate(ctx context.Context, sourceID, createdBy string) (*entity.Connector, error)
- func (s *Service) Enc() *enc.Service
- func (s *Service) Execute(ctx context.Context, p ExecuteParams) (*ExecuteResult, error)
- func (s *Service) FilterBotSlot(rows []entity.Connector) []entity.Connector
- func (s *Service) Get(ctx context.Context, id string) (*entity.Connector, error)
- func (s *Service) GetAccount(ctx context.Context, accountID string) (*entity.ConnectorAccount, error)
- func (s *Service) GetRun(ctx context.Context, runID string) (*entity.ConnectorRun, error)
- func (s *Service) HealthCheckSessionInstance(ctx context.Context, baseKey, instanceID string, config map[string]string) ([]connector.OpHealth, error)
- func (s *Service) IsManageableBy(ctx context.Context, connectorID string, userTagIDs []string, isAdmin bool) (bool, error)
- func (s *Service) IsVisibleTo(ctx context.Context, connectorID string, userTagIDs []string, isAdmin bool) (bool, error)
- func (s *Service) List(ctx context.Context) ([]entity.Connector, error)
- func (s *Service) ListAccounts(ctx context.Context, connectorID string) ([]entity.ConnectorAccount, error)
- func (s *Service) ListByKey(ctx context.Context, key string) ([]entity.Connector, error)
- func (s *Service) ListForManager(ctx context.Context, userTagIDs []string, isAdmin bool) ([]entity.Connector, error)
- func (s *Service) ListRuns(ctx context.Context, connectorID string, limit int) ([]entity.ConnectorRun, error)
- func (s *Service) ListRunsAudit(ctx context.Context, f AuditFilter, limit, offset int) ([]entity.ConnectorRun, error)
- func (s *Service) ListRunsFiltered(ctx context.Context, connectorID string, f RunFilter, limit, offset int) ([]entity.ConnectorRun, error)
- func (s *Service) ListVisibleTo(ctx context.Context, userTagIDs []string, isAdmin bool) ([]entity.Connector, error)
- func (s *Service) LoadConfigs(c entity.Connector) map[string]string
- func (s *Service) Module(key string) (connector.Module, bool)
- func (s *Service) Modules() []connector.Module
- func (s *Service) OperationStates(ctx context.Context, connectorID, key string) (map[string]bool, error)
- func (s *Service) OperationStatesFull(ctx context.Context, connectorID, key string) (map[string]OpState, error)
- func (s *Service) PurgeOldRuns(ctx context.Context, retentionDays int) (int64, error)
- func (s *Service) RemoveModule(key string)
- func (s *Service) Retry(ctx context.Context, originalRunID, userID, ipAddr, userAgent string) (*ExecuteResult, error)
- func (s *Service) RowConfigs(c entity.Connector) []entity.Config
- func (s *Service) RunHealthCheck(ctx context.Context, connectorID string) (*HealthCheckResult, error)
- func (s *Service) SaveAccount(ctx context.Context, ...) error
- func (s *Service) SessionConfigCapable(key string) bool
- func (s *Service) SetAccessPolicy(ctx context.Context, id string, ...) error
- func (s *Service) SetAccountDisabledOps(ctx context.Context, accountID string, opKeys []string) error
- func (s *Service) SetCatalogRefresh(h func(ctx context.Context, key, instanceID string))
- func (s *Service) SetConfigs(c *configs.Service)
- func (s *Service) SetDisabled(ctx context.Context, id string, disabled bool) error
- func (s *Service) SetEnc(e *enc.Service)
- func (s *Service) SetMetrics(rec metrics.Recorder)
- func (s *Service) SetOperationAdminOnly(ctx context.Context, connectorID, opKey string, adminOnly bool) error
- func (s *Service) SetOperationEnabled(ctx context.Context, connectorID, opKey string, enabled bool) error
- func (s *Service) SetRateLimit(ctx context.Context, id string, rpm int) error
- func (s *Service) SetSessionConfigAllowed(ctx context.Context, id string, allowed bool) error
- func (s *Service) SetTags(t tagSeeder)
- func (s *Service) Status(c entity.Connector) string
- func (s *Service) SummariseRuns(ctx context.Context, f AuditFilter) (RunSummary, error)
- func (s *Service) Update(ctx context.Context, id, label string, configs map[string]string, ...) error
- func (s *Service) UpsertModule(ctx context.Context, m connector.Module) error
- type SessionInstanceTarget
Constants ¶
const ( ProfileFull = "full" ProfileAgent = "agent" ProfileLite = "lite" )
Build profiles select which builtin connectors a binary registers. The active profile is read at boot from the configs DB row (configs.KeyProfile) via configsSvc.Profile(). "full" (default and any unknown value) preserves the historical all-connectors behaviour.
Variables ¶
var ErrFixedInstanceViolation = errors.New("connector is fixed: only one instance allowed")
ErrFixedInstanceViolation is returned by Service.Create / Duplicate when trying to add a second instance for a connector whose Meta.Fixed is true. Wick auto-seeds exactly one row for a Fixed connector at Bootstrap; admins cannot add or duplicate beyond that.
var ErrNoHealthCheck = errors.New("connector does not implement HealthCheck")
ErrNoHealthCheck is returned by RunHealthCheck when the target connector's module did not register a HealthCheck hook. The manager handler treats this as a 404-ish — admins should not see the button on that connector at all.
Functions ¶
func AccountDisabledOps ¶ added in v0.16.0
func AccountDisabledOps(acc *entity.ConnectorAccount) map[string]bool
AccountDisabledOps parses the DisabledOps JSON and returns the set of disabled op keys for fast lookup.
func OnRegister ¶ added in v0.15.0
OnRegister installs a listener that fires for every connector module in the registry — once per module already present at the time of the call (catch-up), then once per future Register call (catch future). The catch-up loop matters: workflow setup runs after some builtins have already been registered, and a future-only subscription would silently drop them.
Listeners are not removable. The registry lives for the lifetime of the process; subscriptions are intended for setup-time wiring, not dynamic plug-in/plug-out.
func Register ¶
Register appends a fully-resolved Module record to the registry. Called from app.RegisterConnector; do not call directly from app code.
Idempotent on Meta.Key: re-registering the same key REPLACES the existing entry. This keeps server stop→start safe — wickmanager is registered mid-boot with runtime Deps (configsSvc, jobsSvc, ...) that are rebuilt on each boot. A plain append would trip Bootstrap's duplicate-key check; a skip would leave handlers wired to stale services from the previous boot.
After the (append|replace), every listener registered via OnRegister is notified with the resolved module. Listeners run synchronously on the calling goroutine — keep them cheap. Registrations all happen on the main boot goroutine today; revisit if that ever changes.
func RegisterBuiltins ¶
func RegisterBuiltins()
RegisterBuiltins seeds in-house connectors every downstream wick app gets by default. Idempotent on Meta.Key via registerOnce.
func RegisterLabSamples ¶ added in v0.9.0
func RegisterLabSamples()
RegisterLabSamples seeds the demo-only connectors shipped with the cmd/lab binary — currently the crudcrud sample. Downstream wick apps do not call this; they register their own connectors via main.go.
func RegisterProfile ¶ added in v0.22.0
func RegisterProfile(profile string)
RegisterProfile seeds the builtin connectors permitted by the named profile. Idempotent on Meta.Key via registerOnce.
Types ¶
type AuditFilter ¶ added in v0.9.0
type AuditFilter struct {
ConnectorID string
OperationKey string
Source string
Status string
UserID string
From *time.Time // inclusive lower bound on StartedAt
To *time.Time // inclusive upper bound on StartedAt
}
AuditFilter narrows cross-connector audit queries. All fields are optional — omit to get all runs across every connector instance.
type ExecuteParams ¶
type ExecuteParams struct {
ConnectorID string
OperationKey string
Input map[string]string
// RawInput is the caller's arguments with original JSON types preserved
// (bool, number, string, …), keyed identically to Input. Optional — only
// the MCP tools/call path sets it. It is forwarded to the connector via
// Ctx.SetRawInput so MCP-proxy connectors can relay a scalar in its
// original type instead of the stringified Input form. nil elsewhere.
RawInput map[string]any
Source entity.ConnectorRunSource
UserID string
IPAddress string
UserAgent string
// IsAdmin indicates whether the caller holds admin role. When false,
// operations marked AdminOnly in the connector_operations table are
// blocked before execution starts.
IsAdmin bool
// ParentRunID is set when this call replays an earlier run.
// Intended for use with Source == ConnectorRunSourceRetry.
ParentRunID *string
// Progress, when non-nil, receives incremental progress events the
// connector emits via Ctx.ReportProgress. The MCP SSE handler wires
// a reporter that frames each event as a notifications/progress
// JSON-RPC message; the JSON transport leaves this nil so events
// are dropped harmlessly.
Progress connector.ProgressReporter
// AccountID, when non-empty, selects a specific ConnectorAccount
// whose access token overrides the row's user_token config. Used by
// the test panel when multiple accounts are connected to one instance.
AccountID string
// SessionInstance, when non-nil, runs against a session-workspace
// instance instead of a DB connector row: there is no row to load,
// so the base module is cloned and the instance's own Config map is
// used verbatim. ConnectorID is the synthetic "sw_<uuid>" id (used
// for run logging + rate limiting only). Per-row checks (op enable/
// disable rows, admin-only flags, OAuth accounts) are skipped — a
// session instance has none of that backing state.
SessionInstance *SessionInstanceTarget
}
ExecuteParams bundles the ambient context for one execution. Keeping it as a struct keeps the call site readable when more fields are added (e.g. retry parent, MCP session id).
type ExecuteResult ¶
type ExecuteResult struct {
RunID string
Status entity.ConnectorRunStatus
ResponseJSON string
ErrorMessage string
LatencyMs int
}
ExecuteResult carries the outcome of one Execute call. Returned alongside an error so the caller (panel-test or MCP) can render the run details even when the operation itself failed.
type HealthCheckResult ¶ added in v0.10.0
type HealthCheckResult struct {
Ops []connector.OpHealth
NewlyLocked []string // ops that became system-disabled this run
NewlyCleared []string // ops whose system-disabled flag was cleared this run
}
HealthCheckResult bundles the outcome of a health-check run for one connector row. Per-op transitions describe what changed in the DB so the UI can surface a useful summary toast ("3 ops disabled, 1 cleared").
type OpState ¶ added in v0.10.0
OpState bundles the effective state of one operation on one connector row: the admin-controlled Enabled flag, the health-check-controlled SystemDisabled flag, and the reason surfaced alongside the lock when SystemDisabled is true. Effective availability is `Enabled AND NOT SystemDisabled`. AdminOnly restricts the operation to admin MCP callers and is toggled separately by admins.
type Repo ¶
type Repo struct {
// contains filtered or unexported fields
}
Repo wraps the gorm handle and exposes the connector-specific CRUD surface used by the admin UI, the MCP dispatch layer, and the run-history retention job.
All queries scope on context, so cancellation from the HTTP handler (or the cron worker) propagates cleanly into the DB driver.
func (*Repo) ClearSystemDisabled ¶ added in v0.10.0
ClearSystemDisabled removes the health-check lock from an operation (e.g. after a successful re-check). Leaves Enabled untouched, so an op that was manually disabled stays disabled; one the system locked will become available for manual toggling again.
func (*Repo) CountByKey ¶
CountByKey returns how many Connector rows exist for a code key. Used by Bootstrap to decide whether to auto-create the initial row.
func (*Repo) CountRunsAudit ¶ added in v0.9.0
CountRunsAudit returns the total matching the same filter as ListRunsAudit. Used to drive pagination.
func (*Repo) CountRunsFiltered ¶
func (r *Repo) CountRunsFiltered(ctx context.Context, connectorID string, f RunFilter) (int64, error)
CountRunsFiltered returns the total row count matching the same filter as ListRunsFiltered. Used to drive pagination controls.
func (*Repo) Create ¶
Create inserts a new Connector row. The BeforeCreate hook on the entity stamps an ID if the caller left it empty.
func (*Repo) CreateRun ¶
CreateRun inserts a row at the start of an execution. Status should be ConnectorRunStatusRunning; FinishRun finalizes it.
func (*Repo) Delete ¶
Delete hard-deletes a connector row plus its operation toggles and connected accounts. Run history is intentionally preserved.
func (*Repo) DeleteAccount ¶ added in v0.16.0
DeleteAccount removes one connected account by ID.
func (*Repo) FinishRun ¶
func (r *Repo) FinishRun(ctx context.Context, runID string, status entity.ConnectorRunStatus, response, errMsg string, latencyMs, httpStatus int) error
FinishRun stamps terminal status, the response body, error message, and the timing/HTTP-status metrics. EndedAt is set to now.
func (*Repo) GetAccountByID ¶ added in v0.16.0
func (r *Repo) GetAccountByID(ctx context.Context, accountID string) (*entity.ConnectorAccount, error)
GetAccountByID returns one ConnectorAccount or gorm.ErrRecordNotFound.
func (*Repo) GetRun ¶
GetRun loads a single run, used by the retry handler to replay the stored RequestJSON against the current Connector.Configs.
func (*Repo) IsAccessibleForManager ¶
func (r *Repo) IsAccessibleForManager(ctx context.Context, connectorID string, userTagIDs []string) (bool, error)
IsAccessibleForManager mirrors IsAccessibleTo but ignores the disabled flag. Used by manager handlers so admins who disabled a row can still open its detail page to re-enable.
func (*Repo) IsAccessibleTo ¶
func (r *Repo) IsAccessibleTo(ctx context.Context, connectorID string, userTagIDs []string) (bool, error)
IsAccessibleTo reports whether a single connector row is visible to the caller using the same rule as ListAccessibleTo. Used by tools/call to re-check authorization before dispatch (the tools/list snapshot the client cached may be stale).
func (*Repo) IsOperationAdminOnly ¶ added in v0.9.0
IsOperationAdminOnly returns true when the stored row has AdminOnly=true. Returns false (not restricted) when no row exists yet.
func (*Repo) ListAccessibleForManager ¶
func (r *Repo) ListAccessibleForManager(ctx context.Context, userTagIDs []string) ([]entity.Connector, error)
ListAccessibleForManager mirrors ListAccessibleTo but does NOT strip disabled rows. The admin manager surface must be able to enumerate disabled rows so they can be re-enabled. Tag-filter logic is unchanged.
func (*Repo) ListAccessibleTo ¶
func (r *Repo) ListAccessibleTo(ctx context.Context, userTagIDs []string) ([]entity.Connector, error)
ListAccessibleTo returns the not-disabled Connector rows the caller is allowed to see, mirroring the Tools tag-filter rule:
- row with no filter-type tags → visible to everyone
- row with ≥1 filter-type tag → visible only when userTagIDs intersects the row's filter-tags
Tag association reuses the `tool_tags` table with `tool_path = '/connectors/{id}'` (see entity.Connector godoc).
Pass an empty userTagIDs for users that carry no filter tags — they still see fully untagged rows. Admin callers should bypass this and use List instead.
func (*Repo) ListAccounts ¶ added in v0.16.0
func (r *Repo) ListAccounts(ctx context.Context, connectorID string) ([]entity.ConnectorAccount, error)
ListAccounts returns all connected accounts for a connector instance.
func (*Repo) ListByKey ¶
ListByKey returns every Connector that instantiates the given code definition (e.g. all "loki" rows).
func (*Repo) ListOperations ¶
func (r *Repo) ListOperations(ctx context.Context, connectorID string) ([]entity.ConnectorOperation, error)
ListOperations returns the toggle rows for a connector. Missing rows mean "use the per-op default" (Destructive=false → on, Destructive=true → off); callers fold the defaults in themselves.
func (*Repo) ListRunsAudit ¶ added in v0.9.0
func (r *Repo) ListRunsAudit(ctx context.Context, f AuditFilter, limit, offset int) ([]entity.ConnectorRun, error)
ListRunsAudit returns connector runs across all (or a filtered subset of) connector instances, newest first. Designed for the cross-connector audit log page and the /api/runs JSON endpoint. Admin-only.
func (*Repo) ListRunsByConnector ¶
func (r *Repo) ListRunsByConnector(ctx context.Context, connectorID string, limit int) ([]entity.ConnectorRun, error)
ListRunsByConnector returns the most recent runs for one connector, newest first. Backed by composite index (connector_id, started_at).
func (*Repo) ListRunsFiltered ¶
func (r *Repo) ListRunsFiltered(ctx context.Context, connectorID string, f RunFilter, limit, offset int) ([]entity.ConnectorRun, error)
ListRunsFiltered returns runs for one connector filtered by op/source/ status/user. The history page uses this to power its filter bar. Supports limit+offset for page-based paging.
func (*Repo) PurgeRunsOlderThan ¶
PurgeRunsOlderThan deletes ConnectorRun rows whose StartedAt is before the cutoff. Returns how many rows were removed so the retention job can log progress.
Backed by the standalone started_at index — a single range delete, no composite index needed.
func (*Repo) SetAccessPolicy ¶ added in v0.16.0
func (r *Repo) SetAccessPolicy(ctx context.Context, id string, allowConfigure, allowSSO, enableSSO, multiAccount bool) error
SetAccessPolicy updates the access policy fields for a connector instance.
func (*Repo) SetAccountDisabledOps ¶ added in v0.16.0
SetAccountDisabledOps persists the JSON-encoded disabled ops list for an account.
func (*Repo) SetDisabled ¶
SetDisabled flips the Disabled flag without touching anything else. Used by the admin manager toggle.
func (*Repo) SetOperation ¶
SetOperation upserts the toggle for a single (connector, op) pair. Insert when no row exists, update when it does. Uses an explicit OnConflict upsert on the composite PK with a map payload so the boolean Enabled column is always written verbatim: a plain Save() resolves to an UPDATE when the PK is populated (silent no-op on a missing row), and a struct insert drops Enabled=false because the column carries a `default:true` tag — false is indistinguishable from unset. A map value bypasses that zero-value detection.
func (*Repo) SetOperationAdminOnly ¶ added in v0.9.0
func (r *Repo) SetOperationAdminOnly(ctx context.Context, connectorID, opKey string, adminOnly bool) error
SetOperationAdminOnly upserts the admin_only flag for a (connector, op) pair without touching the Enabled state. Inserts a new row with Enabled=true (safe default) when no row exists yet.
func (*Repo) SetRateLimit ¶ added in v0.9.0
SetRateLimit updates the per-minute call cap for a connector instance. Pass 0 to remove the limit.
func (*Repo) SetSessionConfigAllowed ¶ added in v0.17.0
SetSessionConfigAllowed flips the per-instance opt-in for per-session config overrides. Separate from SetAccessPolicy so the toggle has its own POST and doesn't round-trip the SSO fields.
func (*Repo) SetSystemDisabled ¶ added in v0.10.0
SetSystemDisabled marks an operation as disabled by the health-check system with a human-readable reason. The manual Enabled flag is left untouched — effective availability becomes `Enabled AND NOT SystemDisabled`. Upserts a new row when none exists yet.
func (*Repo) SummariseRuns ¶ added in v0.9.0
func (r *Repo) SummariseRuns(ctx context.Context, f AuditFilter) (RunSummary, error)
SummariseRuns returns aggregate stats for the given audit filter window.
func (*Repo) Update ¶
Update writes label / disabled changes to an existing row. Per- field config values live in the configs table now and are written by Service.Update via configs.Service.SetOwned, not here. Identity fields (ID, Key, CreatedBy, CreatedAt) are untouched.
func (*Repo) UpsertAccount ¶ added in v0.16.0
func (r *Repo) UpsertAccount(ctx context.Context, acc *entity.ConnectorAccount, multiAccount bool) error
UpsertAccount saves a connected account.
- MultiAccount=false: replace any existing account for this connector (1 slot).
- MultiAccount=true: update existing account if same wick_user_id exists, otherwise insert new (prevents duplicate rows for the same user).
type RunSummary ¶ added in v0.9.0
type RunSummary struct {
Total int64 `json:"total"`
Succeeded int64 `json:"succeeded"`
Errored int64 `json:"errored"`
AvgLatencyMs float64 `json:"avg_latency_ms"`
}
RunSummary holds aggregated stats for a connector run query window.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the runtime façade between code-side connector definitions (kept in-memory by the registry) and DB-side connector rows. The admin UI, the panel-test handler, and the future MCP dispatcher all go through it.
Unlike the jobs Service, Bootstrap does NOT seed DB rows from code: connector instances are admin-created on demand. Bootstrap only wires the dispatch table so Execute can find the right ExecuteFunc when a row references its definition by Key.
func NewService ¶
NewService wires a Service around an existing Repo and the default HTTP client. The HTTP client is the one Ctx.HTTP exposes to every ExecuteFunc — replace with a custom client at construction time when tests need a transport hook.
func NewServiceFromDB ¶
NewServiceFromDB is a convenience constructor for the web server and worker — both already hold a *gorm.DB.
func (*Service) Bootstrap ¶
Bootstrap registers code-side connector definitions for dispatch and ensures every registered Key has at least one row in the database. Call once at startup with the All() slice from the registry.
For each module: if zero rows currently exist for the Key, an empty row is auto-created with Label = Meta.Name and Configs = "{}". This makes a fresh deploy ready to use — the admin opens the UI and only has to fill in the credentials. Existing rows (and their cred edits) are NEVER touched, so an admin who has already filled cred won't see the row reset on restart.
Duplicate Keys are an error — one Key may not back two definitions. DB rows whose Key has no registered module are tolerated: they show up as "deactivated" in the admin UI, and Execute on them returns an error.
func (*Service) CatalogRefresh ¶ added in v0.17.0
CatalogRefresh runs the lazy catalog re-sync hook, when installed. instanceID is the row whose account should authenticate the probe (oauth scheme) — servers may expose different tools per account.
func (*Service) ClearSystemDisabled ¶ added in v0.16.0
ClearSystemDisabled removes the health-check lock from one operation, allowing admin to override a stale or incorrect health-check result.
func (*Service) CountRunsAudit ¶ added in v0.9.0
CountRunsAudit returns total runs for the audit filter — pagination companion.
func (*Service) CountRunsFiltered ¶
func (s *Service) CountRunsFiltered(ctx context.Context, connectorID string, f RunFilter) (int64, error)
CountRunsFiltered returns total runs matching the filter — companion of ListRunsFiltered for paging.
func (*Service) Create ¶
func (s *Service) Create(ctx context.Context, key, label string, configs map[string]string, createdBy string) (*entity.Connector, error)
Create inserts a new Connector row for the given code-defined Key and seeds its per-field config rows in the configs table (owner = "connector:{id}"). configs is the credential map keyed by the Creds-struct field names; values are written one row per field.
Returns the freshly stored row (with ID stamped).
func (*Service) Delete ¶
Delete hard-deletes the connector row plus its operation toggles and its per-field config rows. Run history is intentionally preserved for audit.
func (*Service) DeleteAccount ¶ added in v0.16.0
DeleteAccount removes one connected account by ID.
func (*Service) Duplicate ¶
func (s *Service) Duplicate(ctx context.Context, sourceID, createdBy string) (*entity.Connector, error)
Duplicate copies an existing connector row with credentials reset. The new row carries the same Key (so it dispatches to the same code definition) and a "(copy)"-suffixed Label; Configs is "{}" so the admin must re-fill secrets. Tag inheritance is intentionally NOT performed — the caller is responsible for assigning the creator's own tags via the existing ToolTag system.
func (*Service) Enc ¶ added in v0.17.0
Enc exposes the encrypted-fields cipher for callers that must tokenize values outside an Execute round-trip (wick_session_workspace encrypts user-typed secrets before persisting instance config). May be nil — callers must treat that as "encryption unavailable".
func (*Service) Execute ¶
func (s *Service) Execute(ctx context.Context, p ExecuteParams) (*ExecuteResult, error)
Execute runs one operation against one connector row, logging a ConnectorRun with the request, response, latency, and IP/UA.
The same code path serves panel-test, MCP tools/call, and retry — the caller distinguishes via params.Source so the run row is tagged correctly. On success the returned ResponseJSON is the marshaled ExecuteFunc return value; on error ErrorMessage carries the message (the run row also stores it).
Validation order:
- connector row exists and is not Disabled
- connector's Key has a registered module (post-Bootstrap)
- requested OperationKey exists on the module
- operation is currently Enabled (per OperationStates)
func (*Service) FilterBotSlot ¶ added in v0.16.0
FilterBotSlot removes non-SSO instance rows from a row set when at least one SSO-enabled row (EnableSSO=true) exists for the same connector key in the visible set.
Connectors without OAuthMeta are left untouched — they have no SSO concept. Call this after ListVisibleTo before surfacing rows to the LLM via wick_list.
func (*Service) GetAccount ¶ added in v0.16.0
func (s *Service) GetAccount(ctx context.Context, accountID string) (*entity.ConnectorAccount, error)
GetAccount returns one ConnectorAccount by ID.
func (*Service) GetRun ¶
GetRun loads a single ConnectorRun by ID. Backs the test page's prefill flow when a Retry link is followed from the history view.
func (*Service) HealthCheckSessionInstance ¶ added in v0.17.0
func (s *Service) HealthCheckSessionInstance(ctx context.Context, baseKey, instanceID string, config map[string]string) ([]connector.OpHealth, error)
HealthCheckSessionInstance runs a base module's HealthCheck hook against a session-workspace instance's own config — the "test setup" button for an ephemeral instance. Returns ErrNoHealthCheck when the base module registers no hook, so the caller can fall back to running a real operation as the probe.
func (*Service) IsManageableBy ¶
func (s *Service) IsManageableBy(ctx context.Context, connectorID string, userTagIDs []string, isAdmin bool) (bool, error)
IsManageableBy reports whether the caller may operate on a row from the manager UI. Disabled rows are still manageable — the caller may be re-enabling them.
func (*Service) IsVisibleTo ¶
func (s *Service) IsVisibleTo(ctx context.Context, connectorID string, userTagIDs []string, isAdmin bool) (bool, error)
IsVisibleTo reports whether a single connector row is accessible to the caller. Used by tools/call to re-check authorization at dispatch time so a stale tools/list snapshot can't be replayed for access.
func (*Service) ListAccounts ¶ added in v0.16.0
func (s *Service) ListAccounts(ctx context.Context, connectorID string) ([]entity.ConnectorAccount, error)
ListAccounts returns all connected OAuth accounts for a connector instance.
func (*Service) ListByKey ¶ added in v0.10.0
List returns every connector row newest first, regardless of tag filter or visibility. Used by the admin manager and the retention dashboard. UI-layer code is responsible for tag-filtering for non-admin views.
func (*Service) ListForManager ¶
func (s *Service) ListForManager(ctx context.Context, userTagIDs []string, isAdmin bool) ([]entity.Connector, error)
ListForManager returns rows the caller can see in the admin manager. Unlike ListVisibleTo, disabled rows are included so users can re- enable or delete them. Admins see every row.
func (*Service) ListRuns ¶
func (s *Service) ListRuns(ctx context.Context, connectorID string, limit int) ([]entity.ConnectorRun, error)
ListRuns returns the most recent ConnectorRun rows for a connector, newest first. Used by the admin detail page to render history under the test panel.
func (*Service) ListRunsAudit ¶ added in v0.9.0
func (s *Service) ListRunsAudit(ctx context.Context, f AuditFilter, limit, offset int) ([]entity.ConnectorRun, error)
ListRunsAudit returns connector runs across all instances with optional filters. Intended for the cross-connector admin audit log.
func (*Service) ListRunsFiltered ¶
func (s *Service) ListRunsFiltered(ctx context.Context, connectorID string, f RunFilter, limit, offset int) ([]entity.ConnectorRun, error)
ListRunsFiltered returns runs filtered by op / source / status / user. Backs the history page; pass zero-value filter for "no filter".
func (*Service) ListVisibleTo ¶
func (s *Service) ListVisibleTo(ctx context.Context, userTagIDs []string, isAdmin bool) ([]entity.Connector, error)
ListVisibleTo returns the not-disabled connector rows the caller can access, applying the same tag-filter rule as Tools (see Repo.ListAccessibleTo). Pass isAdmin=true to bypass tag filtering — admins see every row whether or not they carry the row's tags.
Use this from MCP tools/list and any user-facing surface that enumerates connectors; only the admin manager should call List.
func (*Service) LoadConfigs ¶ added in v0.6.1
LoadConfigs returns the credential map for a connector row, keyed by the Creds-struct field names. Values are pulled from the configs table (owner = "connector:{id}").
func (*Service) Module ¶
Module looks up a definition by Key. The second return is false when no module is registered for the key (typical when a DB row outlives its code definition after a deploy that drops the connector).
func (*Service) Modules ¶
Modules returns the registered definitions, useful for the "+ New instance" picker in the admin UI.
func (*Service) OperationStates ¶
func (s *Service) OperationStates(ctx context.Context, connectorID, key string) (map[string]bool, error)
OperationStates returns the resolved enable state for every op the connector's definition declares: stored toggle when the row exists, otherwise the per-op default (off for Destructive, on for the rest).
Map key is OperationKey. Returned map is empty when the connector's Key has no registered module.
func (*Service) OperationStatesFull ¶ added in v0.10.0
func (s *Service) OperationStatesFull(ctx context.Context, connectorID, key string) (map[string]OpState, error)
OperationStatesFull returns the full per-operation state map for a connector row, folding stored rows + system-disabled flag + the Destructive-default rule. Missing rows mean "use the default" — on for non-destructive, off for destructive.
func (*Service) PurgeOldRuns ¶
PurgeOldRuns deletes ConnectorRun rows older than retentionDays. Returns the number of rows removed. Called by the cleanup job on a daily cadence (set up in a later phase).
func (*Service) RemoveModule ¶ added in v0.26.0
RemoveModule drops a module definition at runtime (the reverse of UpsertModule), used by the plugin hot-reloader when a plugin is uninstalled. The connector vanishes from the LLM surface immediately; any DB instance rows persist and become inert (Module() returns false) until a module with the same key is registered again.
func (*Service) Retry ¶
func (s *Service) Retry(ctx context.Context, originalRunID, userID, ipAddr, userAgent string) (*ExecuteResult, error)
Retry replays an earlier run against the current Connector.Configs. The new run's ParentRunID points to the original; cred edits made since the original are honored.
func (*Service) RowConfigs ¶ added in v0.6.1
RowConfigs returns the connector module's declared config schema overlaid with the row's stored values. Used by the admin UI so the form always reflects the latest declaration even when EnsureOwned has not yet seeded a brand-new field. Returns nil when the row's Key has no registered module (e.g. after a deploy that dropped the connector — admins should delete the orphan row).
func (*Service) RunHealthCheck ¶ added in v0.10.0
func (s *Service) RunHealthCheck(ctx context.Context, connectorID string) (*HealthCheckResult, error)
RunHealthCheck invokes the module's HealthCheck hook and reconciles the per-operation system_disabled flags against the report. Ops the hook reports OK have their lock cleared (if previously set); ops it reports failing get system-disabled with the reported reason. Returns ErrNoHealthCheck when the module did not register a hook.
The hook itself runs against a Ctx populated from the row's stored configs — encrypted credentials are decrypted on read, identical to Execute. The caller's permission to act on this row is the manager handler's job; this method is unauthenticated by design (it is a background-style operation, not user input).
func (*Service) SaveAccount ¶ added in v0.16.0
func (s *Service) SaveAccount(ctx context.Context, connectorID, wickUserID, externalUserID, displayName, accessToken string) error
SaveAccount persists a connected OAuth account. Respects MultiAccount from the connector row: false = replace existing, true = add new. wickUserID is the wick platform user who initiated the OAuth flow. externalUserID is the provider-side user ID from GetUserIdentity.
func (*Service) SessionConfigCapable ¶ added in v0.17.0
SessionConfigCapable reports whether a connector's MODULE opted into per-session config (the capability). The per-instance toggle is only shown / honored for capable connectors.
func (*Service) SetAccessPolicy ¶ added in v0.16.0
func (s *Service) SetAccessPolicy(ctx context.Context, id string, allowConfigure, allowSSO, enableSSO, multiAccount bool) error
SetAccessPolicy updates the access policy for a connector instance:
- allowConfigure: non-admin users with tag access may edit credentials
- allowSSO: non-admin users may connect their OAuth account
- enableSSO: OAuth flow is active on this instance
- multiAccount: each OAuth connect creates a new row (true) or replaces token (false)
func (*Service) SetAccountDisabledOps ¶ added in v0.16.0
func (s *Service) SetAccountDisabledOps(ctx context.Context, accountID string, opKeys []string) error
SetAccountDisabledOps updates which operations are disabled for an account. opKeys is the list of op keys to disable — empty slice clears all.
func (*Service) SetCatalogRefresh ¶ added in v0.17.0
SetCatalogRefresh installs the hook wick_get fires before reading a module's operations — custom MCP connectors lazily re-sync their live tool catalog there. Nil (the default) is a no-op; set once at boot before serving.
func (*Service) SetConfigs ¶ added in v0.6.1
SetConfigs wires the central configs.Service used to store per- instance config rows under owner = "connector:{id}". When nil, reads fall back to the legacy JSON blob on entity.Connector. Call at boot before Bootstrap so seeded rows get their config rows reconciled into the configs table.
func (*Service) SetDisabled ¶
SetDisabled toggles the row-level off-switch.
func (*Service) SetEnc ¶ added in v0.6.0
SetEnc wires the encrypted-fields cipher in after construction. Call once at boot from server.go, before Execute is reachable. Passing nil is allowed — Execute then runs without any masking.
func (*Service) SetMetrics ¶ added in v0.9.0
SetMetrics wires a telemetry recorder into the service. Call once at boot before the server starts accepting requests. Passing nil is safe — the Noop recorder is used instead.
func (*Service) SetOperationAdminOnly ¶ added in v0.9.0
func (s *Service) SetOperationAdminOnly(ctx context.Context, connectorID, opKey string, adminOnly bool) error
SetOperationAdminOnly sets the admin_only restriction for a (connector, op) pair. When true, only admin users may call the operation via MCP.
func (*Service) SetOperationEnabled ¶
func (s *Service) SetOperationEnabled(ctx context.Context, connectorID, opKey string, enabled bool) error
SetOperationEnabled flips the per-(connector, op) toggle.
func (*Service) SetRateLimit ¶ added in v0.9.0
SetRateLimit updates the calls-per-minute cap for a connector instance. Pass 0 to remove the limit.
func (*Service) SetSessionConfigAllowed ¶ added in v0.17.0
SetSessionConfigAllowed flips the per-instance opt-in for per-session cloning (Config tab + wick_session_workspace). Only meaningful when the module declares AllowSessionConfig.
func (*Service) SetTags ¶ added in v0.10.0
func (s *Service) SetTags(t tagSeeder)
SetTags wires the tags service used to attach Meta.DefaultTags onto every connector row at boot. Call before Bootstrap. nil disables tag seeding.
func (*Service) Status ¶ added in v0.6.1
Status returns "ready" when every Required field on the connector has a non-empty value, "needs_setup" otherwise. Reads from the configs.Service cache (RWMutex, no DB hit per call).
func (*Service) SummariseRuns ¶ added in v0.9.0
func (s *Service) SummariseRuns(ctx context.Context, f AuditFilter) (RunSummary, error)
SummariseRuns returns aggregate stats (total, success, error, avg latency) for the given audit filter window.
func (*Service) Update ¶
func (s *Service) Update(ctx context.Context, id, label string, configs map[string]string, disabled bool) error
Update writes label / configs / disabled changes. Identity fields (Key, CreatedBy, CreatedAt) are immutable and untouched.
Per-field config values land in the configs table (owner = "connector:{id}"); only declared keys are written, unknown keys are silently dropped to keep stale form fields from polluting storage.
func (*Service) UpsertModule ¶ added in v0.17.0
UpsertModule installs or replaces one module in the dispatch map at runtime and runs the same row seeding / config reconciliation as Bootstrap. This is the post-boot registration path for DB-defined custom connectors (save + reload) — built-in modules never change after boot. The map swap is atomic under the service mutex: in- flight Execute calls keep the module they already resolved, new calls see the replacement.
type SessionInstanceTarget ¶ added in v0.17.0
SessionInstanceTarget describes an ephemeral session-workspace connector for Execute. BaseKey is the module it clones; Config is its full config map (secret values stored as wick_cenc_ master tokens, decrypted by the shared master-token pass in Execute).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package crudcrud is a sample connector that wraps the crudcrud.com REST sandbox — a free, throwaway JSON store useful for demos and integration smoke tests.
|
Package crudcrud is a sample connector that wraps the crudcrud.com REST sandbox — a free, throwaway JSON store useful for demos and integration smoke tests. |
|
Package custom is the generic executor behind admin-built custom connectors.
|
Package custom is the generic executor behind admin-built custom connectors. |
|
Package customconnector is the management connector for custom connector definitions: the same lifecycle the admin UI offers (create / inspect / update / re-sync / disable / delete definitions, plus instance rows), exposed as LLM-callable operations so an agent can build a connector without anyone opening the dashboard.
|
Package customconnector is the management connector for custom connector definitions: the same lifecycle the admin UI offers (create / inspect / update / re-sync / disable / delete definitions, plus instance rows), exposed as LLM-callable operations so an agent can build a connector without anyone opening the dashboard. |
|
Package github wraps the GitHub REST API v3 as a wick connector.
|
Package github wraps the GitHub REST API v3 as a wick connector. |
|
Package googleworkspace wraps Google Drive, Sheets, Docs, Slides, Gmail, Calendar, and Meet REST APIs for LLM consumption.
|
Package googleworkspace wraps Google Drive, Sheets, Docs, Slides, Gmail, Calendar, and Meet REST APIs for LLM consumption. |
|
Package httprest is a generic HTTP/REST connector that lets an LLM call any JSON API without writing a custom connector.
|
Package httprest is a generic HTTP/REST connector that lets an LLM call any JSON API without writing a custom connector. |
|
Package notifications exposes Wick's in-process notification service as a fixed connector.
|
Package notifications exposes Wick's in-process notification service as a fixed connector. |
|
Package phoenix wraps the Arize Phoenix observability API as a wick connector for debugging LLM behaviour.
|
Package phoenix wraps the Arize Phoenix observability API as a wick connector for debugging LLM behaviour. |
|
Package plugin is the host side of the connector plugin platform: it spawns connector subprocesses on demand, hands out live gRPC clients, and reaps idle ones.
|
Package plugin is the host side of the connector plugin platform: it spawns connector subprocesses on demand, hands out live gRPC clients, and reaps idle ones. |
|
Package slack wraps Slack's Web API as a wick connector.
|
Package slack wraps Slack's Web API as a wick connector. |
|
Package wickmanager exposes wick's own management plane (apps, jobs, tools, connectors, lifecycle server/worker) as a fixed single- instance connector.
|
Package wickmanager exposes wick's own management plane (apps, jobs, tools, connectors, lifecycle server/worker) as a fixed single- instance connector. |
|
Package workflow exposes the workflow engine as a fixed single-instance MCP connector.
|
Package workflow exposes the workflow engine as a fixed single-instance MCP connector. |