models

package
v2.2.1 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: AGPL-3.0 Imports: 32 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AttestationAppliesToDatasource = "datasource"
	AttestationAppliesToTool       = "tool"
	AttestationAppliesToAll        = "all"
)
View Source
const (
	DefaultPrimaryColor         = "#23E2C2"
	DefaultSecondaryColor       = "#343452"
	DefaultBackgroundColor      = "#FFFFFF"
	DefaultAppTitle             = "Tyk AI Portal"
	DefaultLogoPath             = ""
	DefaultFaviconPath          = ""
	DefaultCustomCSS            = ""
	BrandingSettingsSingletonID = 1
)

Default branding values (current Tyk branding)

View Source
const (
	EdgeStatusRegistered   = "registered"
	EdgeStatusConnected    = "connected"
	EdgeStatusDisconnected = "disconnected"
	EdgeStatusUnhealthy    = "unhealthy"
)

Edge instance status constants

View Source
const (
	EdgeSyncStatusInSync  = "in_sync"
	EdgeSyncStatusPending = "pending"
	EdgeSyncStatusUnknown = "unknown"
	EdgeSyncStatusStale   = "stale"
)

Edge sync status constants

View Source
const (
	PushOperationInProgress       = "in_progress"
	PushOperationSucceeded        = "succeeded"
	PushOperationSucceededWarning = "succeeded_with_warnings"
	PushOperationPartiallyFailed  = "partially_failed"
	PushOperationFailed           = "failed"
	PushOperationExpired          = "expired"
)

Push operation statuses. in_progress until every command is terminal.

View Source
const (
	PushCommandPending          = "pending"
	PushCommandClaimed          = "claimed"
	PushCommandSent             = "sent"
	PushCommandSucceeded        = "succeeded"
	PushCommandSucceededWarning = "succeeded_with_warning"
	PushCommandFailed           = "failed"
	PushCommandExpired          = "expired"
)

Push command statuses. pending → claimed → sent → one terminal status; claimed and sent go back to pending when a transport failure allows another attempt.

View Source
const (
	EndpointTypeDatasource     = "datasource"
	EndpointTypeTool           = "tool"
	EndpointTypeModelRouter    = "model_router"
	EndpointTypeSemanticRouter = "semantic_router"
	EndpointTypePlugin         = "plugin" // a custom_endpoint plugin's /plugins/{slug}/ routes
)

Kinds of gateway endpoint that carry an auth plugin list. LLMs are not here: their plugins (of every hook type, auth among them) live in llm_plugins.

View Source
const (
	FilterKindScript    = "script"
	FilterKindGuardrail = "guardrail"
)

Filter kinds. A script filter runs a Tengo script; a guardrail filter runs a typed provider (the built-in pattern library or an external classifier) described by Config. Both kinds share every attachment point and execution scope.

View Source
const (
	GovernedObjectTypeLLM        = "llm"
	GovernedObjectTypeTool       = "tool"
	GovernedObjectTypeDatasource = "datasource"
	GovernedObjectTypeMCPServer  = "mcp_server"

	// GovernedObjectTypeAll is the wildcard for MetadataSchema.AppliesTo.
	GovernedObjectTypeAll = "*"

	// GovernedObjectTypePluginResourcePrefix prefixes object types derived from
	// plugin resource types: plugin_resource:<plugin_id>:<slug>.
	GovernedObjectTypePluginResourcePrefix = "plugin_resource:"
)

Built-in governed-metadata object types.

View Source
const (
	MetadataEnforcementAdvisory = "advisory" // validation issues are reported, never block
	MetadataEnforcementEnforce  = "enforce"  // hard errors block admin create/update of the object
)

Schema enforcement levels.

View Source
const (
	MetadataSeverityError   = "error"
	MetadataSeverityWarning = "warning"
)

Field issue severities.

View Source
const (
	MetadataFieldTypeString          = "string"
	MetadataFieldTypeText            = "text"
	MetadataFieldTypeNumber          = "number"
	MetadataFieldTypeBoolean         = "boolean"
	MetadataFieldTypeDate            = "date"
	MetadataFieldTypeEmail           = "email"
	MetadataFieldTypeURL             = "url"
	MetadataFieldTypeUser            = "user"
	MetadataFieldTypeVocabulary      = "vocabulary"
	MetadataFieldTypeMultiVocabulary = "multi_vocabulary"
	MetadataFieldTypeStringList      = "string_list"
)

Field types supported by governed metadata schemas.

View Source
const (
	MetadataStatusValid       = "valid"
	MetadataStatusWarnings    = "warnings"
	MetadataStatusInvalid     = "invalid"
	MetadataStatusUnvalidated = "unvalidated"
)

Validation statuses stored on ObjectMetadata.

View Source
const (
	MetadataSourceAdmin  = "admin"
	MetadataSourceSystem = "system"
)

Sources of schemas, vocabularies and metadata writes.

View Source
const (
	DefaultGroupID   uint   = 1 // Deprecated: Use name-based lookup instead
	DefaultGroupName string = "Default"
)
View Source
const (
	MCPGrantKindKey      = "key"      // a Tyk key Studio mints (broker)
	MCPGrantKindOAuth    = "oauth"    // the proxy advertises OAuth; the client obtains its own token
	MCPGrantKindKeyless  = "keyless"  // no credential needed
	MCPGrantKindExternal = "external" // mTLS, HMAC, JWT or custom: provisioned outside Studio
)

Grant kinds: how the App reaches the MCP server.

View Source
const (
	MCPCredentialMinting     = "minting"
	MCPCredentialActive      = "active"
	MCPCredentialSuspended   = "suspended"
	MCPCredentialRotatingOut = "rotating_out"
	MCPCredentialRevoked     = "revoked"
	MCPCredentialFailed      = "failed"
)

Credential status. minting/active/suspended/rotating_out are "live" (they occupy the one-per-App-per-connection slot); revoked and failed are terminal.

View Source
const (
	MCPDriftNone         = "none"
	MCPDriftPendingWiden = "pending_widen"
	MCPDriftApplying     = "applying"
	MCPDriftError        = "error"
)

Drift between the policies the key should carry and those it does.

View Source
const (
	MCPRevokeModeDeleted      = "deleted"
	MCPRevokeModeInactiveOnly = "inactive_only"
)

How a revocation reached the Dashboard.

View Source
const (
	MCPCredentialPurposeApp  = "app"
	MCPCredentialPurposeChat = "chat"
)

Credential purposes. "app" is the key handed to the App owner; "chat" is reserved for a Studio-held key (later milestone).

View Source
const (
	MCPServerKindRemote    = "remote"      // upstream.url is a remote MCP endpoint
	MCPServerKindRestToMCP = "rest_to_mcp" // upstream.url is tyk://<api-id>/mcp
)

MCP server kinds: what the Tyk proxy fronts.

View Source
const (
	MCPDashboardActive          = "active"
	MCPDashboardInactive        = "inactive"
	MCPDashboardMissing         = "missing"          // no longer returned by the Dashboard
	MCPDashboardPendingPlatform = "pending_platform" // handoff: waiting for the platform team to create the proxy
)

Dashboard-side state of an MCP server as seen by the last sync.

View Source
const (
	MCPOriginDashboard  = "dashboard"
	MCPOriginStudio     = "studio"
	MCPOriginSubmission = "submission"
)

Where an MCP server record came from.

View Source
const (
	MCPAuthKeyless       = "keyless"
	MCPAuthToken         = "auth_token"
	MCPAuthBasic         = "basic"
	MCPAuthJWT           = "jwt"
	MCPAuthOAuthTyk      = "oauth_tyk"
	MCPAuthOAuthExternal = "oauth_external"
	MCPAuthOAuth21       = "oauth21"
	MCPAuthMTLS          = "mtls"
	MCPAuthHMAC          = "hmac"
	MCPAuthCustom        = "custom"
	MCPAuthMixed         = "mixed"
)

Consumer authentication modes derived from the proxy definition.

View Source
const (
	MCPSyncRunning = "running"
	MCPSyncOK      = "ok"
	MCPSyncPartial = "partial"
	MCPSyncFailed  = "failed"
)

Sync run outcomes.

View Source
const (
	// Gateway plugin hook types
	HookTypePreAuth        = "pre_auth"
	HookTypeAuth           = "auth"
	HookTypePostAuth       = "post_auth"
	HookTypeOnResponse     = "on_response"
	HookTypeDataCollection = "data_collection"

	// AI Studio plugin hook types
	HookTypeStudioUI         = "studio_ui"         // AI Studio UI extension plugins
	HookTypePortalUI         = "portal_ui"         // AI Portal UI extension plugins (end-user facing)
	HookTypeAgent            = "agent"             // AI Studio agent plugins
	HookTypeObjectHooks      = "object_hooks"      // AI Studio object interaction hooks (CRUD operations)
	HookTypeCustomEndpoint   = "custom_endpoint"   // Custom HTTP endpoints served by plugin
	HookTypeResourceProvider = "resource_provider" // Plugin provides custom resource types for Apps
)

Plugin hook type constants

View Source
const (
	// Plugin management scopes
	ServiceScopePluginsRead   = "plugins.read"
	ServiceScopePluginsWrite  = "plugins.write"
	ServiceScopePluginsConfig = "plugins.config"

	// LLM management scopes
	ServiceScopeLLMsRead   = "llms.read"
	ServiceScopeLLMsWrite  = "llms.write"
	ServiceScopeLLMsConfig = "llms.config"
	ServiceScopeLLMsProxy  = "llms.proxy" // Proxy LLM requests (for agent plugins)

	// Analytics scopes
	ServiceScopeAnalyticsRead = "analytics.read"

	// App management scopes
	ServiceScopeAppsRead  = "apps.read"
	ServiceScopeAppsWrite = "apps.write"

	// Tool management scopes
	ServiceScopeToolsRead       = "tools.read"
	ServiceScopeToolsWrite      = "tools.write"
	ServiceScopeToolsOperations = "tools.operations" // Call tool operations
	ServiceScopeToolsCall       = "tools.call"       // Execute tool operations

	// Datasource management scopes
	ServiceScopeDatasourcesRead       = "datasources.read"
	ServiceScopeDatasourcesWrite      = "datasources.write"
	ServiceScopeDatasourcesEmbeddings = "datasources.embeddings"
	ServiceScopeDatasourcesQuery      = "datasources.query" // Query datasources (for agent plugins)

	// Data catalogue management scopes
	ServiceScopeDataCataloguesRead  = "data-catalogues.read"
	ServiceScopeDataCataloguesWrite = "data-catalogues.write"

	// Tags management scopes
	ServiceScopeTagsRead  = "tags.read"
	ServiceScopeTagsWrite = "tags.write"

	// Filter management scopes
	ServiceScopeFiltersRead  = "filters.read"
	ServiceScopeFiltersWrite = "filters.write"

	// Model pricing scopes
	ServiceScopePricingRead  = "pricing.read"
	ServiceScopePricingWrite = "pricing.write"

	// Vendor information scopes
	ServiceScopeVendorsRead = "vendors.read"

	// Governed metadata scopes (Enterprise)
	ServiceScopeMetadataRead  = "metadata.read"
	ServiceScopeMetadataWrite = "metadata.write"

	// Advanced analytics scopes
	ServiceScopeAnalyticsDetailed = "analytics.detailed"
	ServiceScopeAnalyticsReports  = "analytics.reports"

	// System scopes
	ServiceScopeSystemRead = "system.read"

	// Key-Value storage scopes
	ServiceScopeKVReadWrite = "kv.readwrite" // Plugin key-value storage access

	// Scheduler management scopes
	ServiceScopeSchedulerManage = "scheduler.manage" // Manage plugin schedules

	// Notification scopes
	ServiceScopeNotificationsWrite = "notifications.write" // Raise in-app notifications for admins/users

	// Resource type management scopes (ResourceProvider plugins)
	ServiceScopeResourceTypesManage = "resource-types.manage" // Register/deactivate the plugin's own resource types at runtime

	// RBAC scopes
	ServiceScopeRBACRegister = "rbac.register" // Register the plugin's own permission resources at runtime

	// Plugin resource access scopes (ResourceProvider plugins)
	ServiceScopeResourceAccessManage = "resource-access.manage" // Read and set team grants on the plugin's own resource instances

	// Read-only scopes for governance plugins
	ServiceScopeAuditRead      = "audit.read"       // Read the platform audit trail for one resource (no request/response bodies)
	ServiceScopeMCPServersRead = "mcp-servers.read" // View MCP servers (never upstream URLs, auth details or definitions)
	ServiceScopeRoutersRead    = "routers.read"     // View model and semantic routers and the LLMs they route to

	// App governance scope: suspend/reactivate Apps and flag them, never edit them
	ServiceScopeAppsLifecycle = "apps.lifecycle"
)

Service scope constants for AI Studio plugins

View Source
const (
	PluginPermissionSourceManifest = "manifest"
	PluginPermissionSourceRuntime  = "runtime"
)
View Source
const (
	// DefaultAccessAuto grants every active instance to the Default team, so
	// every user sees it. The default, and the only mode in Community
	// Edition, where team segmentation is not available.
	DefaultAccessAuto = "auto"
	// DefaultAccessExplicit never grants automatically: instances reach the
	// teams an administrator (or the plugin, through its grant calls) grants
	// them to. Honoured only in Enterprise builds.
	DefaultAccessExplicit = "explicit"
)

Default-team access modes for plugin resource types.

View Source
const (
	SystemRoleOwner         = "owner"
	SystemRoleAdministrator = "administrator"
	SystemRoleEditor        = "editor"
	SystemRoleViewer        = "viewer"
	SystemRoleAuditor       = "auditor"
)

System role slugs seeded by the Enterprise RBAC service. System roles are immutable; administrators clone them to customise.

View Source
const (
	RoleBindingSubjectUser  = "user"
	RoleBindingSubjectGroup = "group"
)

Role binding subject types.

View Source
const (
	// 2: cluster_nodes.label and leader_eligible (nullable, additive).
	// 3: tyk_connections.host_key and its unique index (nullable, additive).
	// 4: endpoint_auth_plugins (new table, additive).
	// 5: proxy_logs and llm_chat_records on_behalf_of, acting_agent (nullable, additive).
	// 6: plugin_resource_types.default_access (nullable, additive).
	SchemaVersion          = 6
	MinReaderSchemaVersion = 1
)

The schema version lets an instance that does not migrate (a headless control plane sharing a full Studio's database) check that the schema is one it understands.

Rules for a change to the models:

  • Every change to the schema (the goldens in testdata/schema) bumps SchemaVersion; TestSchemaVersionMatchesGoldens and make schema-golden fail until it is bumped.
  • MinReaderSchemaVersion is raised, to the new SchemaVersion, only when the change breaks code built for an older schema: a dropped or renamed column or table, a changed column type, or a new NOT NULL column without a default. Added tables, nullable or defaulted columns and indexes leave it alone, so older readers keep working.
View Source
const (
	SecretRefObjectLLM        = "llm"
	SecretRefObjectTool       = "tool"
	SecretRefObjectDatasource = "datasource"
	SecretRefObjectEmbedder   = "embedder"
)

Object types recorded in SecretReference.ObjectType.

View Source
const (
	SemanticTargetRoute      = "route"
	SemanticTargetClassifier = "classifier"
)

Roles of a SemanticRouterTarget.

View Source
const (
	SubmissionStatusDraft            = "draft"
	SubmissionStatusSubmitted        = "submitted"
	SubmissionStatusInReview         = "in_review"
	SubmissionStatusApproved         = "approved"
	SubmissionStatusRejected         = "rejected"
	SubmissionStatusChangesRequested = "changes_requested"

	SubmissionResourceTypeDatasource = "datasource"
	SubmissionResourceTypeTool       = "tool"
	SubmissionResourceTypePlugin     = "plugin"
	SubmissionResourceTypeMCPServer  = "mcp_server" // Tyk-managed MCP proxy (Enterprise)
)
View Source
const (
	ActivityTypeSubmitted        = "submitted"
	ActivityTypeReviewStarted    = "review_started"
	ActivityTypeApproved         = "approved"
	ActivityTypeRejected         = "rejected"
	ActivityTypeChangesRequested = "changes_requested"
	ActivityTypeResubmitted      = "resubmitted"
	ActivityTypeRolledBack       = "rolled_back"
)
View Source
const (
	SyncEventConfigChanged    = "config_changed"
	SyncEventEdgeAck          = "edge_ack"
	SyncEventEdgeOutOfSync    = "edge_out_of_sync"
	SyncEventEdgeConnected    = "edge_connected"
	SyncEventEdgeDisconnected = "edge_disconnected"
	SyncEventEdgeStale        = "edge_stale"
)

Sync audit event types

View Source
const (
	TeamBudgetAlertOnly = "alert_only"
	TeamBudgetHardBlock = "hard_block"
)

Team budget enforcement modes. A team in alert-only mode is notified when its spend crosses a threshold; a hard-blocking team also has every one of its Apps refused once the ceiling is reached.

View Source
const (
	ToolTypeREST = "REST"
	// ToolTypeClient is a human-in-the-loop tool: the model calls it like any
	// function, but it is executed by the person in the chat UI (a form or an
	// approval) rather than by the server. Its definition lives in OASSpec as
	// a ClientToolDefinition JSON document.
	ToolTypeClient = "CLIENT"
)
View Source
const (
	DefaultToolRESTAccessEnabled = false
	DefaultToolMCPAccessEnabled  = false
)

Defaults for the access methods of a newly created tool. Tools that existed before the switches stay enabled (see Tool.RESTAccessDisabled); a new tool is chat only until an admin turns a method on.

View Source
const (
	// ClientToolKindApproval shows Approve / Reject buttons.
	ClientToolKindApproval = "approval"
	// ClientToolKindForm shows a JSON-Schema form (ResponseSchema).
	ClientToolKindForm = "form"
	// ClientToolKindPresent is generative UI: the model composes cards,
	// facts, tables, charts and forms from the built-in component
	// vocabulary (see PresentToolSchema) and the chat draws them. The
	// call resolves in the browser without user input.
	ClientToolKindPresent = "present"
)
View Source
const (
	TykConnectionModeCatalogue = "catalogue" // list/import proxies and policies only
	TykConnectionModeBroker    = "broker"    // + mint/update/revoke keys against pinned policies
	TykConnectionModeFull      = "full"      // + create/update proxies and policies
)

Tyk connection trust modes. Studio runs at the lower of the declared mode and what the capability probe can verify against the Dashboard user's permissions.

View Source
const (
	TykConnectionPending  = "pending"
	TykConnectionActive   = "active"
	TykConnectionDisabled = "disabled"
)

Tyk connection lifecycle.

View Source
const (
	TykCapabilityOK         = "ok"
	TykCapabilityDenied     = "denied"
	TykCapabilityUnverified = "unverified"
	TykCapabilityNo         = "no"
)

Capability states recorded by the probe.

View Source
const (
	TykCapMCPRead         = "mcp_read"
	TykCapPoliciesRead    = "policies_read"
	TykCapAPIsRead        = "apis_read"
	TykCapMCPSupported    = "mcp_supported"
	TykCapRestToMCP       = "rest_to_mcp_supported"
	TykCapKeysWrite       = "keys_write"
	TykCapKeysReadByHash  = "keys_read_by_hash"
	TykCapMCPWrite        = "mcp_write"
	TykCapPoliciesWrite   = "policies_write"
	TykCapKeyDeleteByHash = "key_delete_by_hash"
	TykCapMDCBRead        = "mdcb_read"
	// TykCapTemplateRead records whether the connection's API template
	// asset can be fetched (GET /api/assets/{id}).
	TykCapTemplateRead = "template_read"
	// TykCapMCPDryRun records whether POST /api/mcps?dryRun=true really
	// validates without persisting. Dashboard 5.14 ignores the flag and
	// creates the proxy; Studio detects that, deletes it, and validates
	// locally from then on.
	TykCapMCPDryRun        = "mcp_dry_run"
	TykCapDashboardVersion = "dashboard_version"
)

Capability names.

View Source
const (
	TykPolicyPresent = "present"
	TykPolicyMissing = "missing"
)

Policy cache state.

View Source
const (
	MCPPinRoleAccess      = "access"
	MCPPinRoleConsumption = "consumption"
)

Bundle pin roles: one access policy (ACL) and any number of consumption policies (rate limit / quota partitions), the Developer Portal shape.

View Source
const (
	SuperAdminID   uint = 1
	RoleSuperAdmin      = "Super Admin"
	RoleAdmin           = "Admin"
	RoleDeveloper       = "Developer"
	RoleChatUser        = "Chat user"
)
View Source
const (
	AuthSourceLocal = "local" // self-registration
	AuthSourceAdmin = "admin" // created by an administrator through the console or API
	AuthSourceSSO   = "sso"   // provisioned on first login through an identity provider
	AuthSourceHost  = "host"  // provisioned on first request from a host application Studio is embedded in
)

AuthSource records how a user account came to exist. It is set once, at creation, and never changes on later logins: a self-registered user who now signs in through the identity provider is still "local" in origin.

View Source
const (
	LoginMethodPassword = "password"
	LoginMethodSSO      = "sso"
	LoginMethodHost     = "host"
)

LoginMethod values recorded in LastLoginMethod.

View Source
const (
	AuthMethodContextKey = "auth_method"
	AuthMethodSession    = "session" // browser session cookie
	AuthMethodAPIKey     = "api_key" // user API key (header or ?token=)
	AuthMethodHost       = "host"    // identity supplied by the host application
)

AuthMethodContextKey is the gin context key under which the auth middleware records how a request was authenticated, so consumers that cannot import the auth package (the audit trail) can still read it.

View Source
const (
	WebhookTargetPending  = "pending"
	WebhookTargetApproved = "approved"
	WebhookTargetRejected = "rejected"
	WebhookTargetRevoked  = "revoked"
)

Webhook target lifecycle. A target is created pending and never receives a delivery until an administrator approves its URL. Changing the URL or the custom headers of an approved target sends it back to pending.

View Source
const (
	WebhookDeliveryQueued       = "queued"
	WebhookDeliveryInFlight     = "in_flight"
	WebhookDeliverySucceeded    = "succeeded"
	WebhookDeliveryRetrying     = "retrying"
	WebhookDeliveryDeadLettered = "dead_lettered"
	WebhookDeliveryCancelled    = "cancelled"
)

Delivery states. queued/retrying are claimable; in_flight is leased by a worker; the remaining three are terminal (dead_lettered can be replayed).

View Source
const (
	WebhookDeliveryKindEvent  = "event"
	WebhookDeliveryKindTest   = "test"
	WebhookDeliveryKindReplay = "replay"
)

Delivery kinds. Only event deliveries are deduplicated on (event, target); tests and replays always create a new row.

View Source
const (
	WebhookAttemptSuccess      = "success"
	WebhookAttemptRetry        = "retry"
	WebhookAttemptDeadLetter   = "dead_letter"
	WebhookAttemptCancelled    = "cancelled"
	WebhookAttemptLeaseExpired = "lease_expired"
	WebhookAttemptRenderError  = "render_error"
)

Attempt outcomes recorded per HTTP attempt (or per non-HTTP terminal step).

View Source
const (
	WebhookTemplateStandard = "standard"
	WebhookTemplateSlack    = "slack"
	WebhookTemplateMinimal  = "minimal"
	WebhookTemplateCustom   = "custom"
)

Payload template presets. "custom" uses TemplateBody.

View Source
const DefaultCatalogueName = "Default"
View Source
const DefaultDataCatalogueName = "Default"
View Source
const DefaultMigrationLockWait = 15 * time.Minute

DefaultMigrationLockWait bounds the wait for the migration lock when ctx has no deadline of its own.

View Source
const DefaultNamespace = "default"

DefaultNamespace is the canonical key of the global/default namespace in sync bookkeeping (namespace_sync_status rows, edge rows). Object tables keep "" for global objects; see CanonicalNamespace.

View Source
const DefaultPresentToolName = "Generative UI"

DefaultPresentToolName is the display name of the built-in tool.

View Source
const DefaultToolCatalogueName = "Default"
View Source
const GovernedObjectTypeSelfPrefix = GovernedObjectTypePluginResourcePrefix + "self:"

GovernedObjectTypeSelfPrefix lets a plugin refer to its own resource types without knowing its numeric plugin ID: "plugin_resource:self:<slug>". It is accepted in manifest schemas (applies_to) and in management API calls, and rewritten to the concrete object type for the calling plugin.

View Source
const (
	InstallSourceMarketplace = "marketplace"
)

Install sources recorded on InstalledPluginVersion.

View Source
const MaxFailoverTargets = 10

MaxFailoverTargets bounds the waterfall so a misconfiguration cannot turn one request into an unbounded chain of upstream calls.

View Source
const MaxPlausiblePerTokenPrice = 0.01

MaxPlausiblePerTokenPrice is the ceiling above which a submitted price is almost certainly a unit error rather than a real figure.

The most expensive models on the market are around $100 per million output tokens, i.e. 1e-4 per token. A value above 0.01 per token would be $10,000 per million -- two orders of magnitude beyond anything real, and exactly what you get by posting a per-million figure into a per-token field.

View Source
const ModelRouterPrivacySQL = "(SELECT MIN(rl.privacy_score) FROM pool_vendors rpv " +
	"JOIN model_pools rmp ON rmp.id = rpv.pool_id AND rmp.deleted_at IS NULL " +
	"JOIN llms rl ON rl.id = rpv.llm_id AND rl.active = TRUE AND rl.deleted_at IS NULL " +
	"WHERE rmp.router_id = model_routers.id AND rpv.active = TRUE AND rpv.deleted_at IS NULL)"

ModelRouterPrivacySQL is a router's privacy score in SQL, as a correlated subquery on model_routers.id: the lowest score among the active LLMs behind its active vendors. A router is only as private as the least private LLM it may send a request to.

View Source
const NotifyAdmins uint = 1 << 31 // Using the highest bit: 0x80000000

NotifyAdmins is a flag used to indicate that a notification should be sent to all admin users

View Source
const PluginPermissionPrefix = "plugin:"

PluginPermissionPrefix starts the permission resource key of every plugin; it mirrors authz.PluginResourcePrefix without importing the package.

View Source
const PortalSlotChatToolRenderer = "chat.tool_renderer"

PortalSlotChatToolRenderer is the portal slot whose "component" items render tool calls in the chat UI: each item names the tool operation it draws (Tool) and the web component to mount for it.

View Source
const PresentToolOperation = "present"

PresentToolOperation is the function name the model calls for generative UI. Ships as a built-in client tool (see GetOrCreateDefaultClientTools).

View Source
const RedactedLegacyKey = "[REDACTED]"

RedactedLegacyKey replaces the embedder key in redacted JSON.

View Source
const RoleBindingSourceHost = "host"

RoleBindingSourceHost marks a binding the application embedding Studio assigns (services.HostIdentity.Roles): the host keeps it in step, and Studio's administration cannot remove it. An empty source is a binding an administrator (or Studio itself) made.

View Source
const SecretRefPrefix = "$SECRET/"

SecretRefPrefix marks a credential field that reads a stored secret by name instead of carrying the value inline: "$SECRET/OPENAI_KEY".

View Source
const SemanticRouterPrivacySQL = "(SELECT MIN(rs.score) FROM (" +
	"SELECT sl.privacy_score AS score FROM llms sl " +
	"WHERE sl.active = TRUE AND sl.deleted_at IS NULL AND sl.id IN (" +
	"SELECT st.llm_id FROM semantic_router_targets st WHERE st.router_id = semantic_routers.id AND st.llm_id IS NOT NULL " +
	"UNION SELECT spv.llm_id FROM semantic_router_targets st2 " +
	"JOIN model_pools smp ON smp.router_id = st2.model_router_id AND smp.deleted_at IS NULL " +
	"JOIN pool_vendors spv ON spv.pool_id = smp.id AND spv.deleted_at IS NULL AND spv.active = TRUE " +
	"WHERE st2.router_id = semantic_routers.id) " +
	"UNION ALL SELECT se.privacy_score AS score FROM embedders se " +
	"WHERE se.id = semantic_routers.embedder_id AND se.llm_id IS NULL AND se.deleted_at IS NULL" +
	") rs)"

SemanticRouterPrivacySQL is a router's privacy score in SQL, as a correlated subquery on semantic_routers.id: the lowest score among the active LLMs the router may send a request's text to (its LLM targets, the active vendors of the Model Routers it hands off to, and its embedding and judge LLMs). A Model Router target counts with all of its vendors, which is never less strict than the pool a given alias reaches.

A standalone embedder sees the text too, with its own privacy score, so it counts as well (a linked one is already among the LLM targets).

View Source
const TykHostConnectionKey = "host"

TykHostConnectionKey is the HostKey of the host-managed connection.

Variables

View Source
var (
	// ErrEmbedderLLMMissing is returned when a linked embedder's LLM is gone.
	ErrEmbedderLLMMissing = errors.New("embedder's linked LLM no longer exists")
	// ErrEmbedderInvalid wraps structural validation failures.
	ErrEmbedderInvalid = errors.New("invalid embedder")
)
View Source
var (
	// ErrSchemaMissing: no schema version is recorded. No Studio has
	// migrated the database, or the one that did predates schema versions.
	ErrSchemaMissing = errors.New("no Studio schema version is recorded in the database")
	// ErrSchemaTooOld: the database was migrated by an older Studio than
	// this build needs.
	ErrSchemaTooOld = errors.New("the database schema is older than this build needs")
	// ErrSchemaTooNew: a newer Studio migrated the database in a way this
	// build cannot read.
	ErrSchemaTooNew = errors.New("the database schema is newer than this build can read")
)
View Source
var DefaultBootstrapModels = map[Vendor]string{
	OPENAI:    "gpt-5",
	ANTHROPIC: "claude-sonnet-4-5-20250929",
}

DefaultBootstrapModels names the model each seeded provider points at on a brand-new instance.

These live beside DefaultLLMSettings deliberately. They used to be written inline in GetOrCreateDefaultLLMs, drifted onto end-of-life models (gpt-4o and claude-sonnet-4-20250514, both since marked Legacy in the catalogue below), and nothing caught it -- so a new user who filled in their API key still hit model-not-found on their very first call. Keeping them next to the catalogue means there is one place to update when models turn over, and TestDefaultBootstrapModelsAreInCatalogue fails if a default is ever pointed at a model this build does not know about.

View Source
var DefaultFailoverStatusCodes = []int{408, 429, 500, 502, 503, 504}

Failover trigger defaults. A fallback is attempted when the primary's upstream answers with one of these statuses, times out, or cannot be reached at all. 4xx codes other than 408/429 are caller or configuration problems that every target would repeat, so they are never failover triggers; the validator rejects them.

EndpointTypes lists the endpoint kinds, in display order.

View Source
var ErrEmbedderNamespace = errors.New("embedder is not available in this namespace")

ErrEmbedderNamespace is returned when a linked embedder's LLM is scoped to a namespace other than its consumer's.

View Source
var ErrRouteSlugTaken = errors.New("route name is already used by another LLM or router")

ErrRouteSlugTaken is returned when a name or slug would clash with another route on the gateway.

View Source
var ErrSecretsKeyRequired = errors.New("TYK_AI_SECRET_KEY must be configured before storing Tyk Dashboard credentials")

ErrSecretsKeyRequired is returned by the model hooks when a secret-bearing column would be written without the encryption key configured. The integration never stores a Dashboard credential in plaintext.

View Source
var ErrUnsafeLogoURL = errors.New("logo_url must be an http(s) URL or a same-origin path")

ErrUnsafeLogoURL is returned for a logo URL a browser could be tricked by (javascript:, data:, protocol-relative and the like).

View Source
var HashPassword func(password string) (string, error) = hashPassword
View Source
var IsPasswordValid func(password, original string) bool = isPasswordValid

MCPCredentialLiveStatuses are the statuses that hold the per-App slot.

View Source
var PushCommandInFlight = []string{PushCommandClaimed, PushCommandSent}

PushCommandInFlight lists the statuses of a command delivered, or being delivered, on a stream.

PushCommandTerminal lists the statuses a command never leaves.

TykConnectionModes is every mode in ascending order of trust.

Functions

func AccessibleDatasourceQuery

func AccessibleDatasourceQuery(db *gorm.DB, userID uint) *gorm.DB

func AccessibleLLMQuery

func AccessibleLLMQuery(db *gorm.DB, userID uint) *gorm.DB

func AccessibleMCPServerQuery

func AccessibleMCPServerQuery(db *gorm.DB, userID uint) *gorm.DB

AccessibleMCPServerQuery is the portal visibility rule for Tyk-managed MCP servers: the user's teams -> the tool catalogues granted to them -> published servers in those catalogues that are active on their Dashboard. MCP servers have no catalogue family of their own; they share the tool catalogues.

func AccessibleModelRouterQuery

func AccessibleModelRouterQuery(db *gorm.DB, userID uint) *gorm.DB

AccessibleModelRouterQuery is the portal visibility rule for Model Routers: the user's teams -> the LLM catalogues granted to them -> active routers in those catalogues. Routers have no catalogue family of their own; they share the LLM catalogues with the LLMs they route to.

func AccessibleSemanticRouterQuery

func AccessibleSemanticRouterQuery(db *gorm.DB, userID uint) *gorm.DB

AccessibleSemanticRouterQuery is the portal visibility rule for Semantic Routers: the user's teams -> their LLM catalogues -> active routers in them.

func AccessibleToolQuery

func AccessibleToolQuery(db *gorm.DB, userID uint) *gorm.DB

AccessibleToolQuery filters on tools.active, which the per-catalogue portal page also applies (GetAccessibleTools itself does not).

It is the portal catalogue's view of tools, so it lists only tools an App can reach (see AppGrantableToolScope). A chat-only tool is offered in the chat tool picker, which reads GetAccessibleTools, and nowhere in the portal.

func AcquireMigrationLock

func AcquireMigrationLock(ctx context.Context, db *gorm.DB) (release func(), err error)

AcquireMigrationLock serialises schema migration and seeding between Studio instances that share a Postgres database, such as the replicas of a host that embeds Studio: AutoMigrate and the get-or-create seeds are not safe to run concurrently against one schema, and replicas booting together would race.

It takes a transaction-level advisory lock in a transaction of its own, on a connection of its own, and returns the function that ends the transaction and so releases the lock; the migrations themselves run on the pool's other connections. A transaction-level lock is released by the server whatever happens to the connection, and it works behind PgBouncer in transaction mode, which keeps a transaction on one server connection (a session-level lock taken through it stayed behind on a pooled server connection and blocked every later start).

It waits until the lock is free, logging while it waits, and gives up when ctx ends or, if ctx has no deadline, after DefaultMigrationLockWait. On SQLite, and on a pool limited to one connection (which the lock would starve), it does nothing.

func AnalyticsModels

func AnalyticsModels() []interface{}

AnalyticsModels are the tables analytics.Migrate creates: the records the analytics recorder writes, including those from edge analytics pulses, so a control plane that does not migrate writes them too. They are listed here so the schema goldens (and so SchemaVersion) cover them.

func AppGrantableToolScope

func AppGrantableToolScope(db *gorm.DB) *gorm.DB

AppGrantableToolScope is Tool.AppGrantable in SQL: a gateway-served tool with REST or MCP access switched on. Keep the two in step.

The tool type is compared without wrapping the column in a function, so the predicate stays usable by an index; a row with no type is a REST tool.

func BackfillAuthSource

func BackfillAuthSource(db *gorm.DB) error

BackfillAuthSource classifies rows created before AuthSource existed. Only rows with an empty (or NULL, on Postgres) auth_source are touched, so it is idempotent and safe to run on every start. The order matters: SSO-provisioned users are the only ones with no password hash; admin- created users have a password but were never issued a key; everyone else registered. An admin-created user whose key was later rolled, or an SSO user who set a password through the reset flow, is misread as "local"; administrators can correct auth_source through the API.

func BackfillSecretReferences

func BackfillSecretReferences(db *gorm.DB) error

BackfillSecretReferences rebuilds secret_references from the object tables. It runs once at startup: the first boot after this table was introduced populates it, and every later boot repairs drift from writes that bypassed the model hooks. Only rows whose credential columns can hold a reference are loaded (prefix match on the plain columns, a contains match on the JSON metadata), so the scan stays proportional to secret-backed objects.

func BackfillTeamAttribution

func BackfillTeamAttribution(db *gorm.DB) error

BackfillTeamAttribution stamps Apps and spend recorded before team attribution existed. It runs once: the settings row remembers it ran. Existing Apps keep their budgets and their (empty) budget source, so no traffic changes; only reporting gains the team.

func BuiltinObjectID

func BuiltinObjectID(id uint) string

BuiltinObjectID renders a built-in object's numeric ID as a governed-metadata object ID.

func CachePricesFor

func CachePricesFor(vendor string, cpit, cacheWritePT, cacheReadPT float64) (write, read float64)

CachePricesFor returns the per-token prices to bill a vendor's cache write and cache read tokens at.

OpenAI's prompt_tokens and Google's promptTokenCount already include the cache tokens, so the gateway carves them out of the prompt count and bills them separately. Before that split (OpenAI until 2.2.1) they were billed as ordinary input tokens. Cache prices default to 0, and most price rows never set them, so for these vendors a cache price of 0 means "not set" and the tokens fall back to the input price: an unset cache price must never make cached tokens free. Other vendors report cache tokens apart from the prompt count, so their cache prices are used as set.

func CanonicalNamespace

func CanonicalNamespace(ns string) string

CanonicalNamespace maps every spelling of the global/default namespace to DefaultNamespace: "" (object tables, the microgateway's EDGE_NAMESPACE default), "global" (the admin API) and "default" (edge registration, both editions). Any other namespace is returned trimmed. Every reader and writer of NamespaceSyncStatus goes through this so there is exactly one row per logical namespace.

func CheckLLMRouteSlug

func CheckLLMRouteSlug(db *gorm.DB, name string) error

CheckLLMRouteSlug refuses an LLM name whose route a router already uses.

func CheckLogoURL

func CheckLogoURL(u string) error

CheckLogoURL refuses a non-empty logo URL SafeLogoURL would drop.

func CheckRouterRouteSlug

func CheckRouterRouteSlug(db *gorm.DB, routerSlug string) error

CheckRouterRouteSlug refuses a Model Router slug an LLM already answers to or a Semantic Router already uses.

func CheckSemanticRouterRouteSlug

func CheckSemanticRouterRouteSlug(db *gorm.DB, routerSlug string) error

CheckSemanticRouterRouteSlug refuses a Semantic Router slug an LLM already answers to or a Model Router already uses.

func ClaimEdgeStream

func ClaimEdgeStream(db *gorm.DB, edgeID, nodeID, session string) (bool, error)

ClaimEdgeStream records that nodeID now holds the edge's configuration stream, identified by session. The newest stream always wins: an edge has one live stream at a time, so a new one means the old one is gone. It reports whether the edge exists.

func ClearLegacyZeroBudgets

func ClearLegacyZeroBudgets(db *gorm.DB) error

ClearLegacyZeroBudgets rewrites App and LLM budgets of 0 (or less) to nil. Budgets used to treat anything at or below 0 as "no limit"; now nil is "no limit" and 0 is a budget of zero, so existing zeros must not start blocking traffic. It runs once: the settings row remembers it ran, because afterwards a 0 is a deliberate zero budget.

func CountAssociationsForLLM

func CountAssociationsForLLM(db *gorm.DB, llmID uint) (int64, error)

CountAssociationsForLLM returns the count of active plugin associations for an LLM

func CountAssociationsForPlugin

func CountAssociationsForPlugin(db *gorm.DB, pluginID uint) (int64, error)

CountAssociationsForPlugin returns the count of LLM associations for a plugin

func CountPluginDataByPluginID

func CountPluginDataByPluginID(db *gorm.DB, pluginID uint) (int64, error)

CountByPluginID returns the count of plugin data entries for a specific plugin

func CountPluginUpdatesAvailable

func CountPluginUpdatesAvailable(db *gorm.DB) (int64, error)

CountPluginUpdatesAvailable counts installed plugins with a newer marketplace version.

func CountSchemas

func CountSchemas(db *gorm.DB) (int64, error)

CountSchemas returns the total number of cached schemas

func CreateWithDefaultName

func CreateWithDefaultName(tx *gorm.DB, e *Embedder, prefix, model string) error

CreateWithDefaultName inserts e named "<prefix> · <model>" (with " (n)" when taken). Different configurations can share that default name, so a concurrent write may take it between the check and the insert; the insert then runs again with the next free name. Each attempt runs in a savepoint, so a failed insert does not abort the caller's transaction on Postgres.

On Postgres it also holds an advisory lock on the default name until the caller's transaction ends, so creates that would pick the same name take turns (and each sees the names committed before it) instead of colliding. It must run inside a transaction.

func DatasourceCatalogueMemberships

func DatasourceCatalogueMemberships(db *gorm.DB, catalogueIDs []uint) (map[uint][]uint, error)

DatasourceCatalogueMemberships maps datasource id -> ids of the given data catalogues it is in.

func DeactivateOrphanedPluginResourceTypes

func DeactivateOrphanedPluginResourceTypes(db *gorm.DB) (int64, error)

DeactivateOrphanedPluginResourceTypes retires active resource types whose plugin no longer exists (deleted while not loaded, before DeletePlugin retired them). Returns the number of types deactivated.

func DefaultGroupExists

func DefaultGroupExists(db *gorm.DB) (bool, error)

func DeleteAppPluginResources

func DeleteAppPluginResources(db *gorm.DB, appID uint) error

DeleteByApp removes all plugin resource associations for an app

func DeleteAppPluginResourcesByType

func DeleteAppPluginResourcesByType(db *gorm.DB, appID, resourceTypeID uint) error

DeleteByAppAndType removes all associations for an app and resource type

func DeleteAssociationsForLLM

func DeleteAssociationsForLLM(db *gorm.DB, llmID uint) error

DeleteAssociationsForLLM removes all plugin associations for a specific LLM

func DeleteAssociationsForPlugin

func DeleteAssociationsForPlugin(db *gorm.DB, pluginID uint) error

DeleteAssociationsForPlugin removes all LLM associations for a specific plugin

func DeleteEndpointAuthPlugins

func DeleteEndpointAuthPlugins(db *gorm.DB, objectType string, objectID uint) error

DeleteEndpointAuthPlugins detaches every auth plugin from an endpoint. The endpoint's delete calls it.

func DeleteEndpointAuthPluginsForPlugin

func DeleteEndpointAuthPluginsForPlugin(db *gorm.DB, pluginID uint) error

DeleteEndpointAuthPluginsForPlugin detaches a plugin from every endpoint, and removes the list of a custom_endpoint plugin itself. The plugin's delete calls it.

func DeleteExpiredSchemas

func DeleteExpiredSchemas(db *gorm.DB, maxAge time.Duration) (int64, error)

DeleteExpired deletes schemas older than the specified age

func DeleteGroupPluginResourcesByType

func DeleteGroupPluginResourcesByType(db *gorm.DB, groupID, resourceTypeID uint) error

DeleteByGroupAndType removes all entries for a group and resource type

func DeleteInstalledPluginVersion

func DeleteInstalledPluginVersion(db *gorm.DB, pluginID uint) error

DeleteInstalledPluginVersion removes the tracking row for a plugin. The row is hard-deleted: plugin_id carries a unique index, so a soft-deleted row would block tracking the same plugin again.

func DeletePluginPermissionResources

func DeletePluginPermissionResources(db *gorm.DB, pluginID uint) error

DeletePluginPermissionResources removes every row of a plugin.

func EffectiveInstanceAccessGrantedViaApp

func EffectiveInstanceAccessGrantedViaApp(typeValue bool, override *bool) bool

EffectiveInstanceAccessGrantedViaApp applies an optional per-instance override to the resolved type value.

func FailoverStatusCodeAllowed

func FailoverStatusCodeAllowed(code int) bool

FailoverStatusCodeAllowed reports whether a status may act as a failover trigger: any 5xx, plus 408 (request timeout) and 429 (rate limited).

func GetAccessiblePluginResourceInstanceIDs

func GetAccessiblePluginResourceInstanceIDs(db *gorm.DB, userID, resourceTypeID uint) ([]string, error)

GetAccessibleInstanceIDs returns instance IDs accessible to a user via their groups. Joins: user_groups → group_plugin_resources, filtered by resource type.

func GetEndpointAuthPluginIDs

func GetEndpointAuthPluginIDs(db *gorm.DB, objectType string, objectID uint) ([]uint, error)

GetEndpointAuthPluginIDs returns the auth plugins attached to an endpoint, in order.

func GetInstalledPluginVersions

func GetInstalledPluginVersions(db *gorm.DB, pluginIDs []uint) (map[uint]*InstalledPluginVersion, error)

GetInstalledPluginVersions returns the marketplace tracking rows for the given plugin IDs, keyed by plugin ID. Plugins that did not come from a marketplace have no entry.

func GetLatestVersionNumber

func GetLatestVersionNumber(db *gorm.DB, resourceType string, resourceID uint) (int, error)

GetLatestVersion returns the highest version number for a resource

func GetOrCreateDefaultClientTools

func GetOrCreateDefaultClientTools(db *gorm.DB) error

GetOrCreateDefaultClientTools seeds the built-in client tools on startup, the way default LLM configurations are seeded: the generative UI ("present") tool exists in every installation and sits in the Default tool catalogue, so administrators only have to pick it as a default tool of a chat room. Existing installations get it on their next start; once the tool exists only a raw-JSON definition is re-encoded (see encodeRawClientToolSpecs).

func GetOrCreateDefaultFilters

func GetOrCreateDefaultFilters(db *gorm.DB) error

GetOrCreateDefaultFilters seeds DefaultFilters by name, creating only the ones that do not exist yet so a renamed or edited filter is never overwritten and a deleted one is not resurrected on the next start (soft deletes are matched by Unscoped). Configs are stored normalised, as the admin API stores them, so edges receive explicit defaults.

func GetOrCreateDefaultLLMSettings

func GetOrCreateDefaultLLMSettings(db *gorm.DB) error

GetOrCreateDefaultLLMSettings ensures default LLM settings exist in the database. This function only seeds defaults if the llm_settings table is empty, preventing overwriting of user customizations.

func GetOrCreateDefaultLLMs

func GetOrCreateDefaultLLMs(db *gorm.DB) error

GetOrCreateDefaultLLMs ensures default LLM configurations exist in the database. This function creates OpenAI and Anthropic LLM configurations with secret references if they don't already exist, providing a quick-start experience for new users. Newly created LLMs are also added to the default catalogue if it exists.

func GetSubmissionStatusCounts

func GetSubmissionStatusCounts(db *gorm.DB) (map[string]int64, error)

GetStatusCounts returns counts grouped by status (for admin dashboard)

func GetTotalTokens

func GetTotalTokens(db *gorm.DB) (int64, error)

func GetTotalTokensByInteractionType

func GetTotalTokensByInteractionType(db *gorm.DB, interactionType InteractionType) (int64, error)

func GetUserGroupCount

func GetUserGroupCount(db *gorm.DB) (int64, error)

func GetValidHookTypes

func GetValidHookTypes() []string

GetValidHookTypes returns all valid hook types

func GrantKindForAuthMode

func GrantKindForAuthMode(authMode string) string

GrantKindForAuthMode maps a server's consumer auth mode to the grant kind.

func ImplausiblePerTokenPrice

func ImplausiblePerTokenPrice(field string, value float64) (bool, string)

ImplausiblePerTokenPrice reports whether a price looks like a per-million figure submitted into a per-token field, and names the field if so.

func InitModels

func InitModels(db *gorm.DB) error

func IsEmailUnique

func IsEmailUnique(db *gorm.DB, email string, userID uint) (bool, error)

func IsEndpointType

func IsEndpointType(t string) bool

IsEndpointType reports whether t is one of EndpointTypes.

func IsGroupNameUnique

func IsGroupNameUnique(db *gorm.DB, name string, groupID uint) (bool, error)

func IsNewerVersion

func IsNewerVersion(candidate, installed string) bool

IsNewerVersion reports whether candidate is a later version than installed. Both are compared as semver. An unparseable candidate is never newer; an unknown or unparseable installed version cannot be compared, so it is not reported as outdated either (the caller can still offer a version change).

func IsSelfObjectType

func IsSelfObjectType(objectType string) bool

IsSelfObjectType reports whether objectType uses the "self" plugin placeholder.

func IsUniqueViolation

func IsUniqueViolation(err error) bool

IsUniqueViolation reports whether err is a unique constraint violation, on Postgres or SQLite.

func IsValidHookType

func IsValidHookType(hookType string) bool

IsValidHookType validates if a hook type string is valid

func JSONScan

func JSONScan(value, dest interface{}) error

JSONScan is a helper function for implementing sql.Scanner for JSON types

func JSONValue

func JSONValue(v interface{}) (driver.Value, error)

JSONValue is a helper function for implementing driver.Valuer for JSON types

func LLMCatalogueMemberships

func LLMCatalogueMemberships(db *gorm.DB, catalogueIDs []uint) (map[uint][]uint, error)

LLMCatalogueMemberships maps LLM id -> ids of the given catalogues it is in.

func LLMRouteSlug

func LLMRouteSlug(name string) string

LLMRouteSlug is the route an LLM answers to on the gateway.

func ListInstalledPluginVersionsByMarketplaceIDs

func ListInstalledPluginVersionsByMarketplaceIDs(db *gorm.DB, marketplaceIDs []string) (map[string][]*InstalledPluginVersion, error)

ListInstalledPluginVersionsByMarketplaceIDs returns the tracking rows for the given marketplace plugin IDs, grouped by marketplace plugin ID.

func LockEmbedderConfig

func LockEmbedderConfig(tx *gorm.DB, parts ...string) error

LockEmbedderConfig takes a transaction-scoped Postgres advisory lock on an embedder configuration. It must run inside a transaction; it is a no-op on other databases.

func MCPServerCatalogueMemberships

func MCPServerCatalogueMemberships(db *gorm.DB, catalogueIDs []uint) (map[uint][]uint, error)

MCPServerCatalogueMemberships maps MCP server ids to the tool catalogues (among catalogueIDs) they belong to.

func MarkNamespacePushed

func MarkNamespacePushed(db *gorm.DB, namespace string, at time.Time) error

MarkNamespacePushed records that a configuration push was issued for the namespace at the given time. The row is created when the namespace has no sync status yet (a push before any snapshot was generated), with an empty checksum that the next snapshot fills in; that first fill is not a configuration change (see grpc.ControlServer.updateNamespaceSyncStatus).

func MergeLegacyNamespaceSyncStatus

func MergeLegacyNamespaceSyncStatus(db *gorm.DB) error

MergeLegacyNamespaceSyncStatus folds rows keyed by a non-canonical spelling of the default namespace ("" or "global") into the "default" row, keeping the newest snapshot facts and the latest push stamp, and hard-deletes the legacy rows (a tombstone would still hold the unique index). Runs at startup; a no-op once nothing is left to merge.

func MetadataSourcePlugin

func MetadataSourcePlugin(pluginID uint) string

MetadataSourcePlugin builds the source string for a plugin.

func MigrateEmbedders

func MigrateEmbedders(db *gorm.DB) error

MigrateEmbedders moves datasources' inline embedding settings onto Embedder rows: identical settings (vendor, endpoint, key, model) share one embedder, each datasource is linked to its embedder and its inline columns are cleared. Keys are plain values or $SECRET/ / $ENV/ references (never ciphertext), so comparing them as strings is exact. A shared embedder takes the highest privacy score of its datasources, so none of them fails the embedder privacy check afterwards.

It selects only datasources that still carry settings and no embedder, so once it has run it finds nothing. On Postgres an advisory lock keeps two replicas from migrating the same rows.

func MigrateProfiles

func MigrateProfiles(db *gorm.DB) error

MigrateProfiles creates or updates the profiles table. Profiles that predate the provisioning defaults are backfilled to "show both surfaces", which is what admin-created users get, so upgrading never hides the Portal or Chat from newly provisioned SSO users.

func MigrateTIBStores

func MigrateTIBStores(db *gorm.DB) error

MigrateTIBStores creates or updates the tables the identity broker's stores use (profiles and KV pairs). pkg/studio runs it under the migration lock; the stores run it again when SSO starts, a no-op by then.

func ModelRouterCatalogueMemberships

func ModelRouterCatalogueMemberships(db *gorm.DB, catalogueIDs []uint) (map[uint][]uint, error)

ModelRouterCatalogueMemberships maps Model Router ids to the LLM catalogues (among catalogueIDs) they belong to.

func ModelRouterPrivacyScores

func ModelRouterPrivacyScores(db *gorm.DB, ids []uint) (map[uint]int, error)

ModelRouterPrivacyScores maps router ids to their privacy score (see ModelRouterPrivacySQL). Routers that reach no active LLM are absent.

func NamespaceAliases

func NamespaceAliases(ns string) []string

NamespaceAliases lists the stored spellings that mean the same namespace as ns, canonical first, for queries over rows written before canonicalisation (edge rows registered under "", legacy sync rows).

func NewGormAuthRegisterBackend

func NewGormAuthRegisterBackend(db *gorm.DB) tap.AuthRegisterBackend

NewGormAuthRegisterBackend creates a new instance of GormAuthRegisterBackend and initializes it with the given database connection

func NewGormKVStore

func NewGormKVStore(db *gorm.DB) tap.AuthRegisterBackend

NewGormKVStore creates a new instance of GormKVStore and initializes it with the given database connection

func NormalizeDefaultAccess

func NormalizeDefaultAccess(mode string) string

NormalizeDefaultAccess maps a declared mode to a known one: anything other than DefaultAccessExplicit (including empty) is DefaultAccessAuto.

func OrderLLMFilterList

func OrderLLMFilterList(db *gorm.DB, llms []LLM) error

OrderLLMFilterList is OrderLLMFilters for a value slice, as Find returns.

func OrderLLMFilters

func OrderLLMFilters(db *gorm.DB, llms ...*LLM) error

OrderLLMFilters sorts each LLM's Filters by the persisted chain order in one query. Ties (rows from installs that predate order_index all carry 0) fall back to filter id, which is the order those installs saw before.

func PaginateAndSort

func PaginateAndSort(query *gorm.DB, pageSize int, pageNumber int, skipPagination bool, sort string) (*gorm.DB, int64, int, error)

func PluginResourceObjectType

func PluginResourceObjectType(pluginID uint, slug string) string

PluginResourceObjectType builds the governed-metadata object type slug for a plugin resource type.

func PushAttemptsJSON

func PushAttemptsJSON(h []PushAttempt) string

PushAttemptsJSON encodes an attempt history for a map-based update, which bypasses the History field's serializer.

func RecordSchemaVersion

func RecordSchemaVersion(db *gorm.DB, writtenBy string) error

RecordSchemaVersion records that the database now has this build's schema. Call it after every migration has run, under the migration lock. It never lowers the record: an older Studio started against a database a newer one migrated leaves the newer version in place (its own migrations only add), and logs that it did.

func ReleaseEdgeStream

func ReleaseEdgeStream(db *gorm.DB, edgeID, session string) (bool, error)

ReleaseEdgeStream records that the stream identified by session has ended, but only if it is still the edge's current stream: when the edge has already reconnected (to this replica or another), the newer stream's state is left alone. It reports whether it changed anything.

func ResetUseInLoginPageForAll

func ResetUseInLoginPageForAll(db *gorm.DB) error

func ResolveAccessGrantedViaApp

func ResolveAccessGrantedViaApp(declared *bool, plugin *Plugin) bool

ResolveAccessGrantedViaApp returns the effective AccessGrantedViaApp for a resource type. An explicit declaration wins. Otherwise a plugin that serves gateway custom endpoints and provides resources (the shape of a plugin that proxies its resources and checks the App's bindings on each request) grants access through App credentials; any other plugin does not.

func ResolveBudgetTeam

func ResolveBudgetTeam(db *gorm.DB, userID uint) (*uint, error)

ResolveBudgetTeam returns the team an App created by (or chat spend of) the given user is attributed to, or nil when no team applies:

  1. the user's budget-holding team, while they are still a member of it (SSO rewrites memberships at every login, so a stale choice is skipped);
  2. otherwise the user's first non-Default team, by lowest team ID;
  3. otherwise the Default team.

func ResolveBudgetTeams

func ResolveBudgetTeams(db *gorm.DB, userIDs []uint) (map[uint]*uint, error)

ResolveBudgetTeams applies ResolveBudgetTeam to many users with a fixed number of queries: their budget teams, their memberships of live teams, and the Default team. Users that do not exist (or have no team at all and no Default team exists) map to nil.

func ResolveSelfObjectType

func ResolveSelfObjectType(objectType string, pluginID uint) string

ResolveSelfObjectType rewrites "plugin_resource:self:<slug>" to the object type of pluginID's resource type. Any other value is returned unchanged.

func RevokeAPIKey

func RevokeAPIKey(db *gorm.DB, userID uint) error

RevokeAPIKey clears the user's API key. Column update: see TouchAPIKeyUse.

func SafeLogoURL

func SafeLogoURL(u string) string

SafeLogoURL returns u when it is safe to put in an <img src> the portal renders: an http(s) URL or a same-origin path (a single leading "/", no scheme). Anything else, such as a javascript: URL, becomes "".

func SameIDs

func SameIDs(a, b []uint) bool

func SaveTeamBudgetSettings

func SaveTeamBudgetSettings(db *gorm.DB, s *TeamBudgetSettings) error

SaveTeamBudgetSettings upserts the settings row.

func SecretNameFromReference

func SecretNameFromReference(value string) (string, bool)

SecretNameFromReference returns the secret name a $SECRET/<name> reference points at. Anything else (inline keys, $ENV/ references, empty) is not a secret reference.

func SemanticRouterCatalogueMemberships

func SemanticRouterCatalogueMemberships(db *gorm.DB, catalogueIDs []uint) (map[uint][]uint, error)

SemanticRouterCatalogueMemberships maps router ids to the LLM catalogues (among catalogueIDs) they belong to.

func SemanticRouterPrivacyScores

func SemanticRouterPrivacyScores(db *gorm.DB, ids []uint) (map[uint]int, error)

SemanticRouterPrivacyScores maps router ids to their privacy score (see SemanticRouterPrivacySQL). Routers that reach no active LLM are absent.

func SetDisabled

func SetDisabled(db *gorm.DB, userID uint, disabled bool) error

SetDisabled flips the account switch. Disabling also drops the live session and any pending password reset so the lock-out is immediate.

func SetEmailNotificationsEnabled

func SetEmailNotificationsEnabled(db *gorm.DB, userID uint, enabled bool) error

SetEmailNotificationsEnabled stores the user's email delivery preference. Column update: a Save of a struct carrying false would work, but an insert would not (default:true), so every writer goes through here.

func SetEndpointAuthPlugins

func SetEndpointAuthPlugins(db *gorm.DB, objectType string, objectID uint, pluginIDs []uint) error

SetEndpointAuthPlugins replaces an endpoint's auth plugin list; the slice order is the execution order. An empty list detaches them all.

func SetNotificationPreferences

func SetNotificationPreferences(db *gorm.DB, userID uint, inApp, email *bool) error

SetNotificationPreferences stores whichever of the two notification flags are given (nil leaves a flag alone) in one column update.

func SetNotificationsEnabled

func SetNotificationsEnabled(db *gorm.DB, userID uint, enabled bool) error

SetNotificationsEnabled stores the in-app (admin fan-out) notification flag. Column update: see TouchAPIKeyUse.

func SetSkipQuickStartForUser

func SetSkipQuickStartForUser(db *gorm.DB, userID uint) error

func SplitContext

func SplitContext(stored string) (contextText, userText string, hasContext bool)

SplitContext separates the context block the session stores in front of a human message from the text the user actually typed. It is the single place that knows the storage format, so the v2 history endpoint and anything else that materialises stored messages agree with the session itself.

func ToolCatalogueMemberships

func ToolCatalogueMemberships(db *gorm.DB, catalogueIDs []uint) (map[uint][]uint, error)

ToolCatalogueMemberships maps tool id -> ids of the given tool catalogues it is in.

func TouchAPIKeyUse

func TouchAPIKeyUse(db *gorm.DB, userID uint) error

TouchAPIKeyUse records that the user's API key authenticated a request. It is a column update so it never races a whole-struct Save elsewhere.

func TouchEdgeStream

func TouchEdgeStream(db *gorm.DB, edgeID, nodeID, session string) (reclaimed bool, err error)

TouchEdgeStream records a heartbeat received on the stream identified by session. If the row has lost its owner (a stale sweep cleared it, or the row was written by something else), the heartbeat proves this stream is the edge's live one, so it re-claims it. It never takes over from a different session. It reports whether it re-claimed.

func TykModeRank

func TykModeRank(mode string) int

TykModeRank orders modes so "lower of the two" is a comparison.

func UniqueEmbedderName

func UniqueEmbedderName(tx *gorm.DB, vendor, model string) (string, error)

UniqueEmbedderName is uniqueEmbedderName for the service layer.

func UpdatePluginOrder

func UpdatePluginOrder(db *gorm.DB, llmID uint, orderedPluginIDs []uint) error

UpdatePluginOrder updates the execution order for all plugins associated with an LLM

func UpsertPluginPermissionResources

func UpsertPluginPermissionResources(db *gorm.DB, pluginID uint, source string, rows []PluginPermissionResource, removeMissing bool) error

UpsertPluginPermissionResources writes rows for one plugin and source, deleting rows of that source not present when removeMissing is set.

func ValidateGroupsExist

func ValidateGroupsExist(db *gorm.DB, groupIDs []uint) (bool, error)

Types

type APICompatibility

type APICompatibility string

APICompatibility defines the API format the router accepts

const (
	APICompatOpenAI APICompatibility = "openai"
)

type AccessToken

type AccessToken struct {
	gorm.Model
	Token     string    `gorm:"type:varchar(255);uniqueIndex;not null"` // The access token itself
	ClientID  string    `gorm:"type:varchar(255);not null"`
	UserID    uint      `gorm:"not null"`
	Scope     string    `gorm:"type:varchar(255)"`
	ExpiresAt time.Time `gorm:"not null"`
	// AppID is the app the user selected at consent. It is what the token is
	// authorised against: the gateway resolves this app and checks the requested
	// tool against app.Tools, exactly as the app-secret and API-key paths do.
	// Nullable so pre-existing rows migrate, but a token without it authorises
	// nothing - see the OAuth branch of proxy.CredentialValidator.
	AppID *uint `gorm:"column:app_id;index"`
}

AccessToken represents an OAuth 2.0 access token.

type AgentConfig

type AgentConfig struct {
	gorm.Model
	ID          uint                   `json:"id" gorm:"primaryKey"`
	Name        string                 `json:"name" gorm:"not null"`
	Slug        string                 `json:"slug" gorm:"uniqueIndex;not null"`
	Description string                 `json:"description"`
	PluginID    uint                   `json:"plugin_id" gorm:"not null;index:idx_agent_plugin"`
	Plugin      *Plugin                `json:"plugin,omitempty" gorm:"foreignKey:PluginID"`
	AppID       uint                   `json:"app_id" gorm:"not null;index:idx_agent_app"`
	App         *App                   `json:"app,omitempty" gorm:"foreignKey:AppID"`
	Config      map[string]interface{} `json:"config" gorm:"serializer:json"` // Plugin-specific configuration from GetConfigSchema
	Groups      []Group                `json:"groups" gorm:"many2many:agent_groups;"`
	IsActive    bool                   `json:"is_active" gorm:"default:true;index:idx_agent_is_active"`
	Namespace   string                 `json:"namespace" gorm:"default:'';index:idx_agent_namespace"`
}

AgentConfig represents an agent plugin configuration in AI Studio Agents are separate from Chats and leverage Apps for resource access

func NewAgentConfig

func NewAgentConfig() *AgentConfig

NewAgentConfig creates a new AgentConfig instance

func (*AgentConfig) Activate

func (a *AgentConfig) Activate(db *gorm.DB) error

Activate activates the agent config

func (*AgentConfig) AddGroup

func (a *AgentConfig) AddGroup(db *gorm.DB, group *Group) error

AddGroup adds a group to the agent config

func (*AgentConfig) CountActive

func (a *AgentConfig) CountActive(db *gorm.DB) (int64, error)

CountActive returns the count of active agent configs

func (*AgentConfig) CountByPluginID

func (a *AgentConfig) CountByPluginID(db *gorm.DB, pluginID uint) (int64, error)

CountByPluginID returns the count of agent configs for a specific plugin

func (*AgentConfig) Create

func (a *AgentConfig) Create(db *gorm.DB) error

Create creates a new agent config

func (*AgentConfig) Deactivate

func (a *AgentConfig) Deactivate(db *gorm.DB) error

Deactivate deactivates the agent config

func (*AgentConfig) Delete

func (a *AgentConfig) Delete(db *gorm.DB) error

Delete soft deletes an agent config

func (*AgentConfig) Get

func (a *AgentConfig) Get(db *gorm.DB, id uint) error

Get retrieves an agent config by ID

func (*AgentConfig) GetBySlug

func (a *AgentConfig) GetBySlug(db *gorm.DB, slug string) error

GetBySlug retrieves an agent config by slug

func (*AgentConfig) GetGroups

func (a *AgentConfig) GetGroups(db *gorm.DB) error

GetGroups retrieves all groups associated with the agent config

func (*AgentConfig) HasAccessForUser

func (a *AgentConfig) HasAccessForUser(db *gorm.DB, userID uint) (bool, error)

HasAccessForUser checks if a user has access to this agent via groups

func (*AgentConfig) RemoveGroup

func (a *AgentConfig) RemoveGroup(db *gorm.DB, group *Group) error

RemoveGroup removes a group from the agent config

func (AgentConfig) TableName

func (AgentConfig) TableName() string

TableName returns the table name for the AgentConfig model

func (*AgentConfig) Update

func (a *AgentConfig) Update(db *gorm.DB) error

Update updates an existing agent config

func (*AgentConfig) Validate

func (a *AgentConfig) Validate(db *gorm.DB) error

Validate performs validation on the AgentConfig

type AgentConfigs

type AgentConfigs []AgentConfig

func (*AgentConfigs) GetByAppID

func (configs *AgentConfigs) GetByAppID(db *gorm.DB, appID uint) error

GetByAppID returns all agent configs for a specific app

func (*AgentConfigs) GetByPluginID

func (configs *AgentConfigs) GetByPluginID(db *gorm.DB, pluginID uint) error

GetByPluginID returns all agent configs for a specific plugin

func (*AgentConfigs) ListWithPagination

func (configs *AgentConfigs) ListWithPagination(db *gorm.DB, pageSize, pageNumber int, all bool, namespace string, isActive *bool) (int64, int, error)

ListWithPagination returns paginated list of agent configs with filtering

type App

type App struct {
	gorm.Model
	ID              uint   `json:"id" gorm:"primary_key"`
	Name            string `json:"name"`
	Description     string `json:"description"`
	UserID          uint   `json:"user_id" gorm:"foreignKey:ID"`
	CredentialID    uint   `json:"credential_id"`
	Credential      Credential
	MonthlyBudget   *float64   `json:"monthly_budget" gorm:"column:monthly_budget"`
	BudgetStartDate *time.Time `json:"budget_start_date" gorm:"column:budget_start_date"`
	IsOrphaned      bool       `json:"is_orphaned" gorm:"default:false"`
	IsActive        bool       `json:"is_active" gorm:"default:true"`
	// TeamID is the team (Group) the App's spend is attributed to, stamped
	// at creation (see ResolveBudgetTeam).
	TeamID   *uint                  `json:"team_id" gorm:"index"`
	Metadata map[string]interface{} `json:"metadata,omitempty" gorm:"serializer:json"`
	// Hub-and-Spoke Configuration
	Namespace   string       `json:"namespace" gorm:"default:'';index:idx_app_namespace"`
	Datasources []Datasource `json:"datasources" gorm:"many2many:app_datasources;"`
	LLMs        []LLM        `json:"llms" gorm:"many2many:app_llms;"`
	Tools       []Tool       `json:"tools" gorm:"many2many:app_tools;"`
	// MCPServers are Tyk-managed MCP servers the App may reach (Enterprise);
	// serialised by the App handlers, never through this struct.
	MCPServers []MCPServer `json:"-" gorm:"many2many:app_mcp_servers;"`
	// ModelRouters the App may call (Enterprise). A router grant lets the App
	// reach every LLM the router can pick, but only through the router;
	// serialised by the App handlers, never through this struct.
	ModelRouters []ModelRouter `json:"-" gorm:"many2many:app_model_routers;"`
	// SemanticRouters the App may call (Enterprise), granted like ModelRouters.
	SemanticRouters []SemanticRouter `json:"-" gorm:"many2many:app_semantic_routers;"`
	Tags            []Tag            `json:"tags" gorm:"many2many:app_tags;"`
}

func NewApp

func NewApp() *App

Note: Everything is mostly unchanged from your existing code NewApp creates a new App instance

func (*App) ActivateCredential

func (a *App) ActivateCredential(db *gorm.DB) error

ActivateCredential activates the credential associated with the app

func (*App) AddDatasource

func (a *App) AddDatasource(db *gorm.DB, datasource *Datasource) error

AddDatasource adds a datasource to the app

func (*App) AddLLM

func (a *App) AddLLM(db *gorm.DB, llm *LLM) error

AddLLM adds an LLM to the app

func (*App) AddTags

func (a *App) AddTags(db *gorm.DB, tagNames []string) error

AddTags adds tags to an app

func (*App) AddTool

func (a *App) AddTool(db *gorm.DB, tool *Tool) error

AddTool adds a tool to the app

func (*App) Count

func (a *App) Count(db *gorm.DB) (int64, error)

Count returns the total number of apps

func (*App) CountByUserID

func (a *App) CountByUserID(db *gorm.DB, userID uint) (int64, error)

CountByUserID returns the total number of apps for a specific user

func (*App) Create

func (a *App) Create(db *gorm.DB) error

Create a new app

func (*App) DeactivateCredential

func (a *App) DeactivateCredential(db *gorm.DB) error

DeactivateCredential deactivates the credential associated with the app

func (*App) Delete

func (a *App) Delete(db *gorm.DB) error

Delete an app

func (*App) Get

func (a *App) Get(db *gorm.DB, id uint) error

Get an app by ID

func (*App) GetByCredentialID

func (a *App) GetByCredentialID(db *gorm.DB, credentialID uint) error

GetByCredentialID gets an app by its credential ID

func (*App) GetByName

func (a *App) GetByName(db *gorm.DB, name string) error

GetByName gets an app by its name

func (*App) GetByUserID

func (a *App) GetByUserID(db *gorm.DB, userID uint) ([]App, error)

GetByUserID gets all apps for a specific user

func (*App) GetDatasources

func (a *App) GetDatasources(db *gorm.DB) error

GetDatasources retrieves all datasources associated with the app

func (*App) GetID

func (a *App) GetID() uint

GetID returns the app ID

func (*App) GetLLMs

func (a *App) GetLLMs(db *gorm.DB, pageSize, pageNumber int, all bool) ([]LLM, int64, int, error)

GetLLMs retrieves LLMs associated with the app with pagination support

func (*App) GetTools

func (a *App) GetTools(db *gorm.DB) ([]Tool, error)

GetTools retrieves all tools associated with the app

func (*App) List

func (a *App) List(db *gorm.DB) (Apps, error)

List returns all apps

func (*App) RemoveDatasource

func (a *App) RemoveDatasource(db *gorm.DB, datasource *Datasource) error

RemoveDatasource removes a datasource from the app

func (*App) RemoveLLM

func (a *App) RemoveLLM(db *gorm.DB, llm *LLM) error

RemoveLLM removes an LLM from the app

func (*App) RemoveTags

func (a *App) RemoveTags(db *gorm.DB, tagNames []string) error

RemoveTags removes tags from an app

func (*App) RemoveTool

func (a *App) RemoveTool(db *gorm.DB, tool *Tool) error

RemoveTool removes a tool from the app

func (*App) Update

func (a *App) Update(db *gorm.DB) error

Update an existing app

type AppBudgetUsageResponse

type AppBudgetUsageResponse struct {
	CurrentUsage  float64   `json:"current_usage"`
	MonthlyBudget *float64  `json:"monthly_budget"`
	Percentage    *float64  `json:"percentage"`
	StartDate     time.Time `json:"start_date"`
}

AppBudgetUsageResponse represents the budget usage for a specific app

type AppPluginResource

type AppPluginResource struct {
	gorm.Model
	ID                   uint   `json:"id" gorm:"primaryKey"`
	AppID                uint   `json:"app_id" gorm:"uniqueIndex:idx_apr_unique;index:idx_apr_app"`
	PluginResourceTypeID uint   `json:"plugin_resource_type_id" gorm:"uniqueIndex:idx_apr_unique"`
	InstanceID           string `json:"instance_id" gorm:"size:255;uniqueIndex:idx_apr_unique"`

	// Denormalized instance details (cached at bind time, refreshed on instance change)
	InstanceName         string `json:"instance_name" gorm:"size:255"`
	InstancePrivacyScore int    `json:"instance_privacy_score" gorm:"default:0"`
	InstanceMetadata     []byte `json:"instance_metadata"`

	// Relationships
	App                *App                `json:"app,omitempty" gorm:"foreignKey:AppID"`
	PluginResourceType *PluginResourceType `json:"plugin_resource_type,omitempty" gorm:"foreignKey:PluginResourceTypeID"`
}

AppPluginResource is the join table that associates Apps with plugin resource instances. This is the extensible equivalent of the hardcoded app_llms, app_datasources, app_tools tables.

func (AppPluginResource) TableName

func (AppPluginResource) TableName() string

type AppPluginResources

type AppPluginResources []AppPluginResource

func (*AppPluginResources) GetByApp

func (aprs *AppPluginResources) GetByApp(db *gorm.DB, appID uint) error

GetByApp returns all plugin resource associations for an app

type Apps

type Apps []App

func (*Apps) GetAppCount

func (a *Apps) GetAppCount(db *gorm.DB) (int64, error)

func (*Apps) GetByTag

func (a *Apps) GetByTag(db *gorm.DB, tagName string) error

GetByTag retrieves all apps with a specific tag

func (*Apps) ListByUserID

func (a *Apps) ListByUserID(db *gorm.DB, userID uint, pageSize int, pageNumber int, all bool, sort string) (int64, int, error)

ListByUserID returns all apps for a specific user with pagination

func (*Apps) ListWithFilters

func (a *Apps) ListWithFilters(db *gorm.DB, pageSize int, pageNumber int, all bool, sort, namespace string, isActive *bool, userID *uint) (int64, int, error)

ListWithFilters returns a paginated list of apps with namespace, active status, and owner filtering

func (*Apps) ListWithPagination

func (a *Apps) ListWithPagination(db *gorm.DB, pageSize int, pageNumber int, all bool, sort string) (int64, int, error)

ListWithPagination returns a paginated list of apps

func (*Apps) Search

func (a *Apps) Search(db *gorm.DB, searchTerm string, pageSize int, pageNumber int, all bool, sort string) (int64, int, error)

Search returns apps matching the given search term with pagination Searches across app name, description, and associated user's name and email

type AssociationData

type AssociationData struct {
	Name        string
	NeedsUpdate bool
	GetValue    func() interface{}
}

type AttestationTemplate

type AttestationTemplate struct {
	gorm.Model
	ID            uint   `json:"id" gorm:"primaryKey"`
	Name          string `json:"name"`
	Text          string `json:"text"`
	Required      bool   `json:"required"`
	AppliesToType string `json:"applies_to_type"` // datasource | tool | all
	Active        bool   `json:"active"`
	SortOrder     int    `json:"sort_order"`
}

func NewAttestationTemplate

func NewAttestationTemplate() *AttestationTemplate

func (*AttestationTemplate) Create

func (a *AttestationTemplate) Create(db *gorm.DB) error

func (*AttestationTemplate) Delete

func (a *AttestationTemplate) Delete(db *gorm.DB) error

func (*AttestationTemplate) Get

func (a *AttestationTemplate) Get(db *gorm.DB, id uint) error

func (*AttestationTemplate) Update

func (a *AttestationTemplate) Update(db *gorm.DB) error

type AttestationTemplates

type AttestationTemplates []AttestationTemplate

func (*AttestationTemplates) GetAll

func (a *AttestationTemplates) GetAll(db *gorm.DB, activeOnly bool) error

GetAll retrieves all attestation templates, optionally filtered

func (*AttestationTemplates) GetByType

func (a *AttestationTemplates) GetByType(db *gorm.DB, resourceType string, activeOnly bool) error

GetByType retrieves templates applicable to a specific resource type

type AuditRecord

type AuditRecord struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	RequestID string    `gorm:"size:64;index:idx_audit_req_id" json:"req_id"`
	Timestamp time.Time `gorm:"index:idx_audit_ts" json:"timestamp"`

	// Actor
	IP        string `gorm:"size:64;index:idx_audit_ip" json:"ip"`
	UserID    uint   `gorm:"index:idx_audit_user_id" json:"user_id"`
	UserEmail string `gorm:"size:255;index:idx_audit_user_email" json:"user"`
	UserName  string `gorm:"size:255" json:"user_name"`
	UserAgent string `gorm:"size:512" json:"user_agent,omitempty"`
	// AuthMethod is how the actor authenticated: "session" (browser
	// cookie) or "api_key" (user API key); empty for unauthenticated
	// requests such as failed logins.
	AuthMethod string `gorm:"size:16;index:idx_audit_auth_method" json:"auth_method,omitempty"`

	// What happened
	Action string `gorm:"size:128;index:idx_audit_action" json:"action"`
	Method string `gorm:"size:16;index:idx_audit_method" json:"method"`
	URL    string `gorm:"size:2048" json:"url"`
	Route  string `gorm:"size:255;index:idx_audit_route" json:"route"`
	Status int    `gorm:"index:idx_audit_status" json:"status"`

	// What it touched
	ResourceType string `gorm:"size:64;index:idx_audit_resource,priority:1" json:"resource_type"`
	ResourceID   string `gorm:"size:255;index:idx_audit_resource,priority:2" json:"resource_id"`
	ResourceName string `gorm:"size:255" json:"resource_name"`

	// Diff of changed fields for updates, and the final state for deletes.
	// Shape: {"field": {"old": <v>, "new": <v>}}. Sensitive columns are
	// redacted before storage.
	Diff RawJSON `gorm:"type:text" json:"diff"`

	// Populated only when detailed recording is enabled.
	RequestDump  RawJSON `gorm:"type:text" json:"request_dump"`
	ResponseDump RawJSON `gorm:"type:text" json:"response_dump"`

	Error      string `gorm:"size:1024" json:"error,omitempty"`
	DurationMs int64  `json:"duration_ms"`
}

AuditRecord is one entry in the platform audit trail: a single request made to the management API, who made it, from where, what it touched, and what changed. The field set mirrors the Tyk Dashboard audit log (req_id, ip, user, action, method, url, status, diff, request_dump, response_dump) with resource identification added because AI Studio objects are typed.

Records are append-only: there is no update path and retention is the only delete path. Deliberately not gorm.Model so there is no soft-delete column.

func (*AuditRecord) Create

func (r *AuditRecord) Create(db *gorm.DB) error

Create inserts a single audit record.

func (AuditRecord) TableName

func (AuditRecord) TableName() string

TableName matches the Tyk Dashboard audit collection name.

type AuditRecords

type AuditRecords []AuditRecord

AuditRecords is a slice helper for batch inserts.

func (AuditRecords) CreateBatch

func (rs AuditRecords) CreateBatch(db *gorm.DB, batchSize int) error

CreateBatch inserts records in chunks.

type AuthCode

type AuthCode struct {
	gorm.Model
	Code                string    `gorm:"type:varchar(255);uniqueIndex;not null"` // The authorization code itself
	ClientID            string    `gorm:"type:varchar(255);not null"`
	UserID              uint      `gorm:"not null"`
	RedirectURI         string    `gorm:"type:text;not null"`
	Scope               string    `gorm:"type:varchar(255)"`
	ExpiresAt           time.Time `gorm:"not null"`
	CodeChallenge       string    `gorm:"type:varchar(255)"` // For PKCE
	CodeChallengeMethod string    `gorm:"type:varchar(50)"`  // For PKCE (e.g., "S256")
	Used                bool      `gorm:"default:false"`
	AppID               *uint     `gorm:"column:app_id"` // Selected app ID for MCP OAuth
}

AuthCode represents an OAuth 2.0 authorization code.

type BrandingSettings

type BrandingSettings struct {
	gorm.Model
	ID              uint   `json:"id" gorm:"primaryKey"`
	LogoPath        string `json:"logo_path"`                   // Path to custom logo file (empty = use default)
	FaviconPath     string `json:"favicon_path"`                // Path to custom favicon file (empty = use default)
	AppTitle        string `json:"app_title"`                   // Custom application title
	PrimaryColor    string `json:"primary_color"`               // Hex color for primary brand color
	SecondaryColor  string `json:"secondary_color"`             // Hex color for secondary brand color
	BackgroundColor string `json:"background_color"`            // Hex color for background
	CustomCSS       string `json:"custom_css" gorm:"type:text"` // Custom CSS overrides
}

BrandingSettings stores system-wide UI customization settings Uses singleton pattern - only one record with ID=1 exists

func NewBrandingSettings

func NewBrandingSettings() *BrandingSettings

NewBrandingSettings creates a new BrandingSettings instance with default values

func (*BrandingSettings) Create

func (bs *BrandingSettings) Create(db *gorm.DB) error

Create creates the branding settings record Should only be called once during initialization

func (*BrandingSettings) Get

func (bs *BrandingSettings) Get(db *gorm.DB) error

Get retrieves the singleton branding settings record Creates default settings if none exist

func (*BrandingSettings) HasCustomFavicon

func (bs *BrandingSettings) HasCustomFavicon() bool

HasCustomFavicon returns true if a custom favicon has been set

func (bs *BrandingSettings) HasCustomLogo() bool

HasCustomLogo returns true if a custom logo has been set

func (*BrandingSettings) ResetToDefaults

func (bs *BrandingSettings) ResetToDefaults(db *gorm.DB) error

ResetToDefaults resets all settings to default values

func (*BrandingSettings) ToFrontendConfig

func (bs *BrandingSettings) ToFrontendConfig() map[string]interface{}

ToFrontendConfig converts branding settings to frontend-compatible format

func (*BrandingSettings) Update

func (bs *BrandingSettings) Update(db *gorm.DB) error

Update updates the existing branding settings

type BudgetUsage

type BudgetUsage struct {
	EntityID        uint       `json:"entity_id"`
	Name            string     `json:"name"`
	EntityType      string     `json:"entity_type"` // "LLM" or "App"
	Budget          *float64   `json:"budget"`
	Spent           float64    `json:"spent"`
	Usage           float64    `json:"usage"` // percentage
	BudgetStartDate *time.Time `json:"budget_start_date"`
	TotalCost       float64    `json:"total_cost"`   // cost for the specified date range
	TotalTokens     int64      `json:"total_tokens"` // total tokens for the specified date range
	UserID          uint       `json:"user_id"`      // ID of the user who owns the app
	UserEmail       *string    `json:"user_email"`   // Email of the user who owns the app (pointer to handle null case)
}

BudgetUsage represents budget usage information for an LLM or App

type CMessage

type CMessage struct {
	gorm.Model
	ID        uint   `gorm:"primaryKey"`
	Session   string `gorm:"index"`
	Content   []byte
	CreatedAt time.Time
	ChatID    uint `gorm:"index"`
}

CMessage is the GORM model for chat messages

func GetLastCMessagesForSession

func GetLastCMessagesForSession(db *gorm.DB, sessionID string, limit int) ([]CMessage, error)

func (*CMessage) UnmarshalContent

func (cm *CMessage) UnmarshalContent() any

type Catalogue

type Catalogue struct {
	gorm.Model
	ID   uint   `json:"id" gorm:"primary_key"`
	Name string `json:"name"`
	LLMs []LLM  `gorm:"many2many:catalogue_llms;"`
	// ModelRouters are published in LLM catalogues alongside the LLMs they
	// route to (Enterprise).
	ModelRouters []ModelRouter `json:"-" gorm:"many2many:catalogue_model_routers;"`
	// SemanticRouters are published the same way (Enterprise).
	SemanticRouters []SemanticRouter `json:"-" gorm:"many2many:catalogue_semantic_routers;"`
}

func GetOrCreateDefaultCatalogue

func GetOrCreateDefaultCatalogue(db *gorm.DB) (*Catalogue, error)

GetOrCreateDefaultCatalogue finds or creates the Default LLM catalogue by name This is safe for databases where auto-increment has been reset or cleared

func NewCatalogue

func NewCatalogue() *Catalogue

func (*Catalogue) AddLLM

func (c *Catalogue) AddLLM(db *gorm.DB, llm *LLM) error

func (*Catalogue) Create

func (c *Catalogue) Create(db *gorm.DB) error

func (*Catalogue) Delete

func (c *Catalogue) Delete(db *gorm.DB) error

func (*Catalogue) Get

func (c *Catalogue) Get(db *gorm.DB, id uint) error

func (*Catalogue) GetCatalogueLLMs

func (c *Catalogue) GetCatalogueLLMs(db *gorm.DB) error

func (*Catalogue) IsDefault

func (c *Catalogue) IsDefault() bool

IsDefault checks if this catalogue is the default catalogue

func (*Catalogue) LLMNames

func (c *Catalogue) LLMNames() []string

Add this new method

func (*Catalogue) RemoveLLM

func (c *Catalogue) RemoveLLM(db *gorm.DB, llm *LLM) error

func (*Catalogue) Update

func (c *Catalogue) Update(db *gorm.DB) error

type Catalogues

type Catalogues []Catalogue

func (*Catalogues) GetAll

func (c *Catalogues) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

func (*Catalogues) GetByNameStub

func (c *Catalogues) GetByNameStub(db *gorm.DB, stub string) error

type ChartData

type ChartData struct {
	Labels []string  `json:"labels"`
	Data   []float64 `json:"data"`
}

ChartData represents data for charts

type Chat

type Chat struct {
	gorm.Model
	ID                  uint         `gorm:"primaryKey" json:"id"`
	Name                string       `json:"name"`
	Description         string       `json:"description"`
	Groups              []Group      `gorm:"many2many:chat_groups;"`
	LLMSettingsID       uint         `json:"llm_settings_id"`
	LLMSettings         *LLMSettings `gorm:"foreignKey:LLMSettingsID" json:"llm_settings"`
	LLMID               uint         `json:"llm_id"`
	LLM                 *LLM         `gorm:"foreignKey:LLMID" json:"llm"`
	Filters             []*Filter    `gorm:"many2many:chat_filters;"`
	RagResultsPerSource int          `json:"rag_results_per_source"`
	SupportsTools       bool         `json:"supports_tools"`
	SystemPrompt        string       `json:"system_prompt"`
	DefaultDataSource   *Datasource  `gorm:"foreignKey:DefaultDataSourceID;constraint:OnDelete:SET NULL" json:"default_data_source"`
	DefaultDataSourceID *uint        `json:"default_data_source_id"`
	ExtraContext        []FileStore  `gorm:"many2many:chat_filestores;" json:"extra_context"`
	DefaultTools        []*Tool      `gorm:"many2many:chat_tools;" json:"default_tools"`
	PromptTemplatesJSON string       `json:"-" gorm:"column:prompt_templates_json"`
}

func (*Chat) AddExtraContext

func (cs *Chat) AddExtraContext(db *gorm.DB, fileStore *FileStore) error

AddFileStore adds a FileStore to the Tool

func (*Chat) Create

func (c *Chat) Create(db *gorm.DB) error

Create a new chat

func (*Chat) Delete

func (c *Chat) Delete(db *gorm.DB) error

Delete a chat

func (*Chat) Get

func (c *Chat) Get(db *gorm.DB, id uint) error

Get a chat by ID

func (*Chat) GetExtraContext

func (cs *Chat) GetExtraContext(db *gorm.DB) ([]FileStore, error)

GetFileStores gets all FileStores associated with the Tool

func (*Chat) GetPromptTemplates

func (c *Chat) GetPromptTemplates() ([]PromptTemplate, error)

GetPromptTemplates deserializes the JSON templates

func (*Chat) RemoveExtraContext

func (cs *Chat) RemoveExtraContext(db *gorm.DB, fileStore *FileStore) error

RemoveFileStore removes a FileStore from the Tool

func (*Chat) SetExtraContext

func (cs *Chat) SetExtraContext(db *gorm.DB, fileStores []FileStore) error

SetFileStores replaces all existing FileStore associations with new ones

func (*Chat) SetPromptTemplates

func (c *Chat) SetPromptTemplates(templates []PromptTemplate) error

SetPromptTemplates serializes templates to JSON

func (*Chat) Update

func (c *Chat) Update(db *gorm.DB) error

Update an existing chat

func (*Chat) UpdatePromptTemplates

func (c *Chat) UpdatePromptTemplates(db *gorm.DB, templates []PromptTemplate) error

UpdatePromptTemplates updates just the prompt templates for a chat

type ChatHistoryRecord

type ChatHistoryRecord struct {
	gorm.Model
	ID             uint   `gorm:"primaryKey"`
	SessionID      string `gorm:"index"`
	ChatID         uint   `gorm:"index"`
	UserID         uint   `gorm:"index"`
	Name           string
	TitleGenerated bool `gorm:"default:false"` // Tracks if the title was auto-generated
}

func GetLatestChatHistoryRecord

func GetLatestChatHistoryRecord(db *gorm.DB, userID uint) (*ChatHistoryRecord, error)

GetLatestChatHistoryRecord retrieves the most recent ChatHistoryRecord for a given UserID

func ListChatHistoryRecordsByUserID

func ListChatHistoryRecordsByUserID(db *gorm.DB, userID uint, pageSize int, pageNumber int, all bool) ([]ChatHistoryRecord, int64, int, error)

ListByUserID retrieves all ChatHistoryRecords for a given UserID

func ListChatHistoryRecordsByUserIDPaginated

func ListChatHistoryRecordsByUserIDPaginated(db *gorm.DB, userID uint, pageSize int, pageNumber int, all bool) ([]ChatHistoryRecord, int64, int, error)

ListChatHistoryRecordsByUserIDPaginated retrieves ChatHistoryRecords for a given UserID with pagination

func SearchChatHistoryRecords

func SearchChatHistoryRecords(db *gorm.DB, userID uint, searchTerm string, pageSize int, pageNumber int, all bool) ([]ChatHistoryRecord, int64, int, error)

SearchChatHistoryRecords searches for ChatHistoryRecords by name for a given UserID with pagination

func (*ChatHistoryRecord) Create

func (chr *ChatHistoryRecord) Create(db *gorm.DB) error

Create a new ChatHistoryRecord

func (*ChatHistoryRecord) Delete

func (chr *ChatHistoryRecord) Delete(db *gorm.DB) error

Delete a ChatHistoryRecord

func (*ChatHistoryRecord) Get

func (chr *ChatHistoryRecord) Get(db *gorm.DB, id uint) error

Get a ChatHistoryRecord by ID

func (*ChatHistoryRecord) GetByChatID

func (chr *ChatHistoryRecord) GetByChatID(db *gorm.DB, chatID uint) error

GetByChatID retrieves a ChatHistoryRecord by ChatID

func (*ChatHistoryRecord) GetBySessionID

func (chr *ChatHistoryRecord) GetBySessionID(db *gorm.DB, sessionID string) error

GetBySessionID retrieves a ChatHistoryRecord by SessionID

func (*ChatHistoryRecord) MarkTitleGenerated

func (chr *ChatHistoryRecord) MarkTitleGenerated(db *gorm.DB) error

MarkTitleGenerated marks the chat history record as having its title auto-generated

func (*ChatHistoryRecord) ShouldGenerateTitle

func (chr *ChatHistoryRecord) ShouldGenerateTitle(userMessage string) bool

ShouldGenerateTitle checks if a title should be auto-generated for this chat Returns true if the title hasn't been generated and the user message is substantial

func (*ChatHistoryRecord) Update

func (chr *ChatHistoryRecord) Update(db *gorm.DB) error

Update an existing ChatHistoryRecord

func (*ChatHistoryRecord) UpdateName

func (chr *ChatHistoryRecord) UpdateName(db *gorm.DB, newName string) error

type Chats

type Chats []Chat

func (*Chats) GetByGroupID

func (cs *Chats) GetByGroupID(db *gorm.DB, groupID uint) error

Get chats by group ID

func (*Chats) GetByLLMID

func (cs *Chats) GetByLLMID(db *gorm.DB, llmID uint) error

Get chats by LLM ID

func (*Chats) GetByLLMSettingsID

func (cs *Chats) GetByLLMSettingsID(db *gorm.DB, llmSettingsID uint) error

Get chats by LLMSettings ID

func (*Chats) GetChatCount

func (c *Chats) GetChatCount(db *gorm.DB) (int64, error)

func (*Chats) List

func (cs *Chats) List(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

List all chats

type ClientToolDefinition

type ClientToolDefinition struct {
	// Parameters is the JSON schema of the arguments the model supplies.
	Parameters map[string]interface{} `json:"parameters"`
	UI         ClientToolUI           `json:"ui"`
}

ClientToolDefinition is the OASSpec payload of a ToolTypeClient tool.

type ClientToolUI

type ClientToolUI struct {
	// Kind is "form" (the user fills ResponseSchema), "approval" (the user
	// approves or rejects what the model asked for) or "present"
	// (generative UI drawn from the built-in vocabulary).
	Kind string `json:"kind"`
	// ResponseSchema is the JSON schema of the value the user provides for
	// kind "form". Optional; a single free-text field is used when absent.
	ResponseSchema map[string]interface{} `json:"response_schema,omitempty"`
	// Title and Description label the card shown to the user.
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
}

ClientToolUI tells the chat UI how to collect the tool's result.

type ClusterEvent

type ClusterEvent struct {
	ID        int64     `json:"id" gorm:"primaryKey;autoIncrement"`
	Topic     string    `json:"topic" gorm:"size:255;not null"`
	Origin    string    `json:"origin" gorm:"size:128;not null"`
	Payload   []byte    `json:"payload"`
	CreatedAt time.Time `json:"created_at" gorm:"not null;index"`
}

ClusterEvent is one entry of the cluster event log: an event every other replica must see (pkg/cluster). Readers track the ids they have handled; rows are pruned after the retention window.

type ClusterLease

type ClusterLease struct {
	Name       string    `json:"name" gorm:"primaryKey;size:64"`
	Holder     string    `json:"holder" gorm:"size:128;not null"`
	AcquiredAt time.Time `json:"acquired_at"`
	RenewedAt  time.Time `json:"renewed_at"`
	ExpiresAt  time.Time `json:"expires_at" gorm:"not null"`
}

ClusterLease is a named lease held by at most one replica at a time: the cluster's leader for singleton work (pkg/cluster.Leadership). Taking and renewing it are conditional writes against the database's clock.

type ClusterNode

type ClusterNode struct {
	NodeID    string    `json:"node_id" gorm:"primaryKey;size:128"`
	Hostname  string    `json:"hostname" gorm:"size:255"`
	Version   string    `json:"version" gorm:"size:64"`
	StartedAt time.Time `json:"started_at"`
	LastSeen  time.Time `json:"last_seen" gorm:"index"`
	// PID, BootID (the running kernel) and PIDNamespace locate the
	// replica's process, so a replica restarted on the same host after a
	// crash can tell that the lease holder is its dead predecessor and
	// take over at once (pkg/cluster.Leadership). Empty on rows written
	// before they existed.
	PID          int    `json:"pid" gorm:"column:pid"`
	BootID       string `json:"boot_id" gorm:"column:boot_id;size:64"`
	PIDNamespace string `json:"pid_namespace" gorm:"column:pid_namespace;size:64"`
	// Label names the replica for operators (a full Studio "studio" or
	// "dashboard", a headless control plane "mdcb-<host>"). Empty on rows
	// written before labels existed.
	Label string `json:"label" gorm:"column:label;size:64"`
	// LeaderEligible is false for a replica that never takes the leader
	// lease (a headless control plane). Nil on rows written before it
	// existed, which means eligible. A pointer without a gorm default: a
	// bool with default:true would turn an explicit false into true.
	LeaderEligible *bool `json:"leader_eligible" gorm:"column:leader_eligible"`
}

ClusterNode is one running Studio replica. Each replica refreshes its row every few seconds (pkg/cluster); a row whose LastSeen is older than the liveness window belongs to a replica that has stopped or lost the database, and anything it claimed is up for others to take over.

func (ClusterNode) CanLead

func (n ClusterNode) CanLead() bool

CanLead reports whether the replica may take the leader lease.

type ComplianceEvent

type ComplianceEvent struct {
	gorm.Model
	AppID       uint      `json:"app_id" gorm:"index:idx_ce_app_time,priority:1"`
	UserID      uint      `json:"user_id" gorm:"index"`
	LLMID       uint      `json:"llm_id" gorm:"index"`
	FilterName  string    `json:"filter_name" gorm:"index"`
	FilterScope string    `json:"filter_scope"`            // "proxy_request", "proxy_response", "chat_request", "chat_response", "file_reference", "tool_response"
	EventType   string    `json:"event_type" gorm:"index"` // Free-form: "pii_redacted", "content_rewritten", "silent_failure", etc.
	Severity    string    `json:"severity" gorm:"index"`   // "info", "warning", "critical"
	Description string    `json:"description"`
	Metadata    string    `json:"metadata"` // JSON blob for arbitrary key-value data
	Vendor      string    `json:"vendor"`
	ModelName   string    `json:"model_name"`
	TimeStamp   time.Time `json:"timestamp" gorm:"index:idx_ce_time;index:idx_ce_app_time,priority:2"`
}

ComplianceEvent records a compliance-relevant event reported by a filter script. Scripts can flag any type of compliance event (redactions, rewrites, PII detection, silent failures, etc.) by setting compliance_events in their output object.

type Credential

type Credential struct {
	gorm.Model
	ID     uint   `json:"id" gorm:"primaryKey"`
	KeyID  string `json:"key_id" gorm:"uniqueIndex"`
	Secret string `json:"secret"`
	Active bool   `json:"active" gorm:"default:false"`
}

func NewCredential

func NewCredential() (*Credential, error)

func (*Credential) Activate

func (c *Credential) Activate(db *gorm.DB) error

func (*Credential) Create

func (c *Credential) Create(db *gorm.DB) error

func (*Credential) Deactivate

func (c *Credential) Deactivate(db *gorm.DB) error

func (*Credential) Delete

func (c *Credential) Delete(db *gorm.DB) error

func (*Credential) Get

func (c *Credential) Get(db *gorm.DB, id uint) error

func (*Credential) GetByKeyID

func (c *Credential) GetByKeyID(db *gorm.DB, keyID string) error

func (*Credential) GetBySecret

func (c *Credential) GetBySecret(db *gorm.DB, secret string) error

func (*Credential) Update

func (c *Credential) Update(db *gorm.DB) error

type Credentials

type Credentials []Credential

func (*Credentials) GetActive

func (cl *Credentials) GetActive(db *gorm.DB) error

func (*Credentials) GetAll

func (cl *Credentials) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

type DataCatalogue

type DataCatalogue struct {
	gorm.Model
	ID               uint         `json:"id" gorm:"primaryKey"`
	Name             string       `json:"name"`
	ShortDescription string       `json:"short_description"`
	LongDescription  string       `json:"long_description"`
	Icon             string       `json:"icon"`
	Datasources      []Datasource `json:"data_sources" gorm:"many2many:data_catalogue_data_sources;"`
	Tags             []Tag        `json:"tags" gorm:"many2many:data_catalogue_tags;"`
}

func GetOrCreateDefaultDataCatalogue

func GetOrCreateDefaultDataCatalogue(db *gorm.DB) (*DataCatalogue, error)

GetOrCreateDefaultDataCatalogue finds or creates the Default data catalogue by name This is safe for databases where auto-increment has been reset or cleared

func NewDataCatalogue

func NewDataCatalogue() *DataCatalogue

func (*DataCatalogue) AddDatasource

func (dc *DataCatalogue) AddDatasource(db *gorm.DB, datasource *Datasource) error

Add a data source to the data catalogue

func (*DataCatalogue) AddTag

func (dc *DataCatalogue) AddTag(db *gorm.DB, tag *Tag) error

Add a tag to the data catalogue

func (*DataCatalogue) Create

func (dc *DataCatalogue) Create(db *gorm.DB) error

Create a new data catalogue

func (*DataCatalogue) Delete

func (dc *DataCatalogue) Delete(db *gorm.DB) error

Delete a data catalogue

func (*DataCatalogue) Get

func (dc *DataCatalogue) Get(db *gorm.DB, id uint) error

Get a data catalogue by ID

func (*DataCatalogue) IsDefault

func (dc *DataCatalogue) IsDefault() bool

IsDefault checks if this data catalogue is the default data catalogue

func (*DataCatalogue) RemoveDatasource

func (dc *DataCatalogue) RemoveDatasource(db *gorm.DB, datasource *Datasource) error

Remove a data source from the data catalogue

func (*DataCatalogue) RemoveTag

func (dc *DataCatalogue) RemoveTag(db *gorm.DB, tag *Tag) error

Remove a tag from the data catalogue

func (*DataCatalogue) Update

func (dc *DataCatalogue) Update(db *gorm.DB) error

Update an existing data catalogue

type DataCatalogues

type DataCatalogues []DataCatalogue

func (*DataCatalogues) GetAll

func (dc *DataCatalogues) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

Get all data catalogues

func (*DataCatalogues) GetByDatasource

func (dc *DataCatalogues) GetByDatasource(db *gorm.DB, datasourceID uint) error

Get data catalogues by datasource

func (*DataCatalogues) GetByTag

func (dc *DataCatalogues) GetByTag(db *gorm.DB, tagName string) error

Get data catalogues by tag

func (*DataCatalogues) Search

func (dc *DataCatalogues) Search(db *gorm.DB, query string) error

Search data catalogues by name, short description, and long description

type Dataset

type Dataset struct {
	Label string    `json:"label"`
	Data  []float64 `json:"data"`
	Yaxis string    `json:"yAxisID"`
}

Dataset represents a single dataset in a multi-axis chart

type Datasource

type Datasource struct {
	gorm.Model
	ID               uint   `json:"id" gorm:"primaryKey"`
	Name             string `json:"name" gorm:"index"`
	ShortDescription string `json:"short_description"`
	LongDescription  string `json:"long_description"`
	Icon             string `json:"icon"`
	Url              string `json:"url"`
	PrivacyScore     int    `json:"privacy_score"`
	UserID           uint   `json:"user_id" gorm:"foreignKey:ID;index:idx_ds_user_community"`
	Tags             []Tag  `json:"tags" gorm:"many2many:datasource_tags;"`

	DBConnString string `json:"db_conn_string" gorm:"index"`
	DBSourceType string `json:"db_source_type"`
	DBConnAPIKey string `json:"db_conn_api_key"`
	DBName       string `json:"db_name"`

	// EmbedderID is the embedder that turns this datasource's text into
	// vectors. The embed_vendor/url/api_key/model columns it replaced stay in
	// the table (cleared by MigrateEmbedders) until a later release drops
	// them; runtime code reads the embedder, never those columns.
	EmbedderID *uint     `json:"embedder_id" gorm:"index"`
	Embedder   *Embedder `json:"-" gorm:"foreignKey:EmbedderID"`

	Files []FileStore `gorm:"many2many:datasource_filestores;" json:"files"`

	Active    bool
	Namespace string `json:"namespace" gorm:"default:'';index:idx_datasource_namespace"`

	// UGC (User-Generated Content) fields
	CommunitySubmitted bool  `json:"community_submitted" gorm:"index:idx_ds_user_community"`
	SubmissionID       *uint `json:"submission_id"`

	// Plugin-stored metadata
	Metadata JSONMap `json:"metadata" gorm:"type:json"`
	// contains filtered or unexported fields
}

func NewDatasource

func NewDatasource() *Datasource

func (*Datasource) AddFileStore

func (d *Datasource) AddFileStore(db *gorm.DB, fileStore *FileStore) error

AddFileStore adds a FileStore to the DS

func (*Datasource) AddTags

func (d *Datasource) AddTags(db *gorm.DB, tagNames []string) error

Add tags to a datasource

func (*Datasource) AfterDelete

func (d *Datasource) AfterDelete(tx *gorm.DB) error

AfterDelete drops the datasource's secret references.

func (*Datasource) AfterSave

func (d *Datasource) AfterSave(tx *gorm.DB) error

AfterSave keeps the secret_references rows for this datasource current.

func (*Datasource) Create

func (d *Datasource) Create(db *gorm.DB) error

Create a new datasource

func (*Datasource) Delete

func (d *Datasource) Delete(db *gorm.DB) error

Delete a datasource

func (*Datasource) EmbedFields

func (d *Datasource) EmbedFields(resolveSecrets bool) LegacyEmbed

EmbedFields is FlattenedEmbed with the choice of resolving secret references (true for runtime and edge use). The datasource needs its Embedder (and that embedder's LLM) preloaded.

func (*Datasource) FlattenedEmbed

func (d *Datasource) FlattenedEmbed() LegacyEmbed

FlattenedEmbed returns the datasource's embedder as the legacy inline fields, with references as stored (not resolved). A datasource without a resolvable embedder flattens to empty fields.

func (*Datasource) Get

func (d *Datasource) Get(db *gorm.DB, id uint) error

Get a datasource by ID

func (*Datasource) LegacyEmbedInput

func (d *Datasource) LegacyEmbedInput() (LegacyEmbed, bool)

LegacyEmbedInput returns the embed_* keys this datasource was decoded from, if the JSON carried any.

func (Datasource) MarshalJSON

func (d Datasource) MarshalJSON() ([]byte, error)

MarshalJSON adds the flattened embed_* keys.

func (*Datasource) RedactEmbedKey

func (d *Datasource) RedactEmbedKey()

RedactEmbedKey makes the datasource's JSON carry a redacted embedder key. It copies the JSON-only state first, so a redacted copy of a datasource (a struct copy shares the pointer) leaves the original untouched.

func (*Datasource) RemoveFileStore

func (d *Datasource) RemoveFileStore(db *gorm.DB, fileStore *FileStore) error

RemoveFileStore removes a FileStore from the DS

func (*Datasource) RemoveTags

func (d *Datasource) RemoveTags(db *gorm.DB, tagNames []string) error

Remove tags from a datasource

func (*Datasource) SetEmbedder

func (d *Datasource) SetEmbedder(e *Embedder)

SetEmbedder links the datasource to an embedder (nil unlinks).

func (*Datasource) UnmarshalJSON

func (d *Datasource) UnmarshalJSON(data []byte) error

UnmarshalJSON reads the datasource and keeps any embed_* keys aside.

func (*Datasource) Update

func (d *Datasource) Update(db *gorm.DB) error

Update an existing datasource

type Datasources

type Datasources []Datasource

func (*Datasources) GetActiveDataSources

func (d *Datasources) GetActiveDataSources(db *gorm.DB) error

func (*Datasources) GetAll

func (d *Datasources) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

Get all datasources

func (*Datasources) GetAllWithFilters

func (d *Datasources) GetAllWithFilters(db *gorm.DB, pageSize int, pageNumber int, all bool, isActive *bool, userID *uint) (int64, int, error)

GetAllWithFilters returns all datasources with filtering by active status and user ID

func (*Datasources) GetByMaxPrivacyScore

func (d *Datasources) GetByMaxPrivacyScore(db *gorm.DB, maxScore int) error

Filter datasources by maximum privacy score

func (*Datasources) GetByMinPrivacyScore

func (d *Datasources) GetByMinPrivacyScore(db *gorm.DB, minScore int) error

Filter datasources by minimum privacy score

func (*Datasources) GetByPrivacyScoreRange

func (d *Datasources) GetByPrivacyScoreRange(db *gorm.DB, minScore, maxScore int) error

Filter datasources by privacy score range

func (*Datasources) GetByTag

func (d *Datasources) GetByTag(db *gorm.DB, tagName string) error

Fetch datasources by tag

func (*Datasources) GetByUserID

func (d *Datasources) GetByUserID(db *gorm.DB, userID uint) error

Get all datasources belonging to a specific user

func (*Datasources) Search

func (d *Datasources) Search(db *gorm.DB, query string) error

Search datasources by name, short description and long description

type EdgeInstance

type EdgeInstance struct {
	gorm.Model
	ID            uint                   `json:"id" gorm:"primaryKey"`
	EdgeID        string                 `json:"edge_id" gorm:"uniqueIndex;not null"`
	Namespace     string                 `json:"namespace" gorm:"default:'';index:idx_edge_instances_namespace"`
	Version       string                 `json:"version"`
	BuildHash     string                 `json:"build_hash"`
	Metadata      map[string]interface{} `json:"metadata" gorm:"serializer:json"`
	LastHeartbeat *time.Time             `json:"last_heartbeat" gorm:"index:idx_edge_instances_heartbeat"`
	Status        string                 `json:"status" gorm:"default:'registered';index:idx_edge_instances_status"`
	SessionID     string                 `json:"session_id"`
	// OwnerNodeID is the Studio replica holding the edge's configuration
	// stream, and StreamSessionID identifies that stream. Writes that end a
	// stream are conditional on StreamSessionID, so a replica the edge has
	// left cannot overwrite the state its new replica recorded.
	OwnerNodeID     string `json:"owner_node_id" gorm:"size:128;index:idx_edge_instances_owner"`
	StreamSessionID string `json:"stream_session_id" gorm:"size:64"`
	// Sync tracking fields
	LoadedChecksum string         `json:"loaded_checksum" gorm:"size:64"`
	LoadedVersion  string         `json:"loaded_version" gorm:"size:64"`
	SyncStatus     string         `json:"sync_status" gorm:"size:20;default:'unknown';index:idx_edge_instances_sync_status"`
	LastSyncAck    *time.Time     `json:"last_sync_ack"`
	CreatedAt      time.Time      `json:"created_at"`
	UpdatedAt      time.Time      `json:"updated_at"`
	DeletedAt      gorm.DeletedAt `json:"deleted_at,omitempty" gorm:"index"`
}

EdgeInstance represents a registered edge instance in hub-and-spoke mode

func NewEdgeInstance

func NewEdgeInstance() *EdgeInstance

NewEdgeInstance creates a new EdgeInstance

func (*EdgeInstance) CleanupStaleEdges

func (e *EdgeInstance) CleanupStaleEdges(db *gorm.DB, maxAge time.Duration) error

CleanupStaleEdges marks edges as disconnected if they haven't sent heartbeat in maxAge

func (*EdgeInstance) CountActiveEdges

func (e *EdgeInstance) CountActiveEdges(db *gorm.DB) (int64, error)

CountActiveEdges returns the count of active edges

func (*EdgeInstance) CountEdgesBySyncStatus

func (e *EdgeInstance) CountEdgesBySyncStatus(db *gorm.DB, namespace string) (map[string]int64, error)

CountEdgesBySyncStatus returns the count of edges by sync status in a namespace

func (*EdgeInstance) CountEdgesInNamespace

func (e *EdgeInstance) CountEdgesInNamespace(db *gorm.DB, namespace string) (int64, error)

CountEdgesInNamespace returns the count of edges in a specific namespace

func (*EdgeInstance) Create

func (e *EdgeInstance) Create(db *gorm.DB) error

Create creates a new edge instance

func (*EdgeInstance) Delete

func (e *EdgeInstance) Delete(db *gorm.DB) error

Delete permanently deletes an edge instance We use hard delete (not soft delete) to allow edges to re-register with the same edge_id

func (*EdgeInstance) Get

func (e *EdgeInstance) Get(db *gorm.DB, id uint) error

Get retrieves an edge instance by ID

func (*EdgeInstance) GetByEdgeID

func (e *EdgeInstance) GetByEdgeID(db *gorm.DB, edgeID string) error

GetByEdgeID retrieves an edge instance by edge ID

func (*EdgeInstance) IsHealthy

func (e *EdgeInstance) IsHealthy(maxAge time.Duration) bool

IsHealthy checks if the edge instance is considered healthy

func (*EdgeInstance) LatestSyncAck

func (e *EdgeInstance) LatestSyncAck(db *gorm.DB, namespace string) (*EdgeInstance, error)

LatestSyncAck returns the edge in the namespace that most recently confirmed it was in sync with the namespace's configuration (its LastSyncAck, set only when its loaded checksum matched), or nil when no edge ever did. The pending-changes preview uses that ack as the reference point when no push was recorded: the configuration as of then reached an edge, whether or not the edge is connected now and whatever changed since (a change moves the namespace to a new checksum, so requiring the current one reported everything as never pushed after any edit, and requiring a connected edge did so whenever the edges were offline).

func (*EdgeInstance) MarkEdgesAsPendingInNamespace

func (e *EdgeInstance) MarkEdgesAsPendingInNamespace(db *gorm.DB, namespace string) error

MarkEdgesAsPendingInNamespace marks all active edges in a namespace as pending sync

func (*EdgeInstance) MarkStaleEdges

func (e *EdgeInstance) MarkStaleEdges(db *gorm.DB, staleThreshold time.Duration) error

MarkStaleEdges marks edges that have been pending sync for too long as stale

func (*EdgeInstance) Update

func (e *EdgeInstance) Update(db *gorm.DB) error

Update updates an existing edge instance

func (*EdgeInstance) UpdateHeartbeat

func (e *EdgeInstance) UpdateHeartbeat(db *gorm.DB) error

UpdateHeartbeat updates the last heartbeat timestamp

func (*EdgeInstance) UpdateStatus

func (e *EdgeInstance) UpdateStatus(db *gorm.DB, status string) error

UpdateStatus updates the edge instance status

func (*EdgeInstance) UpdateSyncStatus

func (e *EdgeInstance) UpdateSyncStatus(db *gorm.DB, checksum, version, status string) error

UpdateSyncStatus updates the sync status for an edge

type EdgeInstances

type EdgeInstances []EdgeInstance

func (*EdgeInstances) ListActiveEdges

func (edges *EdgeInstances) ListActiveEdges(db *gorm.DB) error

ListActiveEdges returns all active (connected/registered) edges

func (*EdgeInstances) ListEdgesByStatus

func (edges *EdgeInstances) ListEdgesByStatus(db *gorm.DB, status string) error

ListEdgesByStatus returns edges with a specific status

func (*EdgeInstances) ListEdgesBySyncStatus

func (edges *EdgeInstances) ListEdgesBySyncStatus(db *gorm.DB, syncStatus string) error

ListEdgesBySyncStatus returns edges with a specific sync status

func (*EdgeInstances) ListEdgesInNamespace

func (edges *EdgeInstances) ListEdgesInNamespace(db *gorm.DB, namespace string) error

ListEdgesInNamespace returns all edges in a specific namespace, under any spelling of it (see NamespaceAliases).

type EdgePushCommand

type EdgePushCommand struct {
	ID          int64  `json:"id" gorm:"primaryKey;autoIncrement"`
	OperationID string `json:"operation_id" gorm:"size:64;not null;uniqueIndex:idx_edge_push_commands_op_edge"`
	EdgeID      string `` /* 140-byte string literal not displayed */
	Namespace   string `json:"namespace" gorm:"size:255"`
	// The janitor's and dispatcher's queries lead with status; the
	// composite indexes serve them (see Coordinator.janitor, dispatch).
	Status string `` /* 253-byte string literal not displayed */

	Attempts    int `json:"attempts"`
	MaxAttempts int `json:"max_attempts"`
	// ClaimedBy is the replica delivering it, on StreamSessionID; the claim
	// lapses at ClaimExpiresAt if the command is never sent.
	ClaimedBy       string     `json:"claimed_by" gorm:"size:128"`
	ClaimExpiresAt  *time.Time `json:"claim_expires_at" gorm:"index:idx_edge_push_commands_status_claim,priority:2"`
	StreamSessionID string     `json:"stream_session_id" gorm:"size:64"`
	SentAt          *time.Time `json:"sent_at"`

	// Phase and Message are the edge's latest report (or, once terminal,
	// the reason for the outcome).
	Phase   string     `json:"phase" gorm:"size:32"`
	PhaseAt *time.Time `json:"phase_at"`
	Message string     `json:"message" gorm:"type:text"`
	// Warning explains a succeeded_with_warning outcome.
	Warning string `json:"warning" gorm:"type:text"`

	// ExpectedChecksum is the namespace's checksum when the edge answered
	// READY, LoadedChecksum the one the edge had loaded then.
	ExpectedChecksum string `json:"expected_checksum" gorm:"size:64"`
	LoadedChecksum   string `json:"loaded_checksum" gorm:"size:64"`

	History []PushAttempt `json:"history" gorm:"serializer:json;type:text"`

	// Version increases with every change. Replicas change a command by
	// reading it, checking the change still applies and writing it back
	// only if Version is unchanged, so no change (or history entry) is
	// lost to a concurrent one.
	Version int64 `json:"-" gorm:"not null;default:0"`

	DeadlineAt  time.Time  `json:"deadline_at" gorm:"index:idx_edge_push_commands_status_deadline,priority:2"`
	CreatedAt   time.Time  `json:"created_at" gorm:"index:idx_edge_push_commands_status_created,priority:2"`
	UpdatedAt   time.Time  `json:"updated_at"`
	CompletedAt *time.Time `json:"completed_at"`
}

EdgePushCommand is the push of one operation to one edge.

type EmailSender

type EmailSender interface {
	SendEmail(to, subject, body string) error
}

EmailSender defines the interface for sending emails

type Embedder

type Embedder struct {
	gorm.Model
	ID          uint   `json:"id" gorm:"primaryKey"`
	Name        string `json:"name" gorm:"uniqueIndex:idx_embedder_name;not null"`
	Description string `json:"description"`

	// LLMID links the embedder to an LLM. When set, Vendor, Endpoint, APIKey
	// and PrivacyScore are ignored in favour of the LLM's.
	LLMID *uint `json:"llm_id" gorm:"index"`
	LLM   *LLM  `json:"-" gorm:"foreignKey:LLMID"`

	// Vendor is the client used to call the endpoint (its API compatibility),
	// not necessarily who serves the model.
	Vendor Vendor `json:"vendor"`
	// Endpoint is the base URL. For Vertex it is "project:location".
	Endpoint string `json:"endpoint"`
	// APIKey is a plain value or a $SECRET/ or $ENV/ reference, as on LLMs.
	APIKey string `json:"api_key"`
	// ModelName is the embedding model (column "model"; gorm.Model owns the
	// Go name).
	ModelName    string `json:"model" gorm:"column:model;not null"`
	PrivacyScore int    `json:"privacy_score"`

	UserID uint `json:"user_id"`
}

Embedder is a reusable embedding configuration: the client (API compatibility), endpoint, credentials and model used to turn text into vectors. Datasources and Semantic Routers reference one by id.

An Embedder is either linked to an LLM, in which case the vendor, endpoint, key and privacy score come from that LLM live, or standalone, in which case it carries its own. Runtime code never reads these fields directly: it asks for a resolved EmbedderSpec (Spec, GetEmbedderResolved).

func FindOrCreateLinkedEmbedder

func FindOrCreateLinkedEmbedder(db *gorm.DB, llmID uint, model string, userID uint) (e *Embedder, created bool, err error)

FindOrCreateLinkedEmbedder returns the embedder linked to the LLM with this model, creating one (named "<LLM name> · <model>") when there is none. created reports whether it was made now.

Concurrent calls for the same LLM and model create one embedder (see LockEmbedderConfig).

func (*Embedder) AfterDelete

func (e *Embedder) AfterDelete(tx *gorm.DB) error

AfterDelete drops the embedder's secret references.

func (*Embedder) AfterSave

func (e *Embedder) AfterSave(tx *gorm.DB) error

AfterSave keeps the secret_references rows for this embedder current. A linked embedder carries no credentials of its own (its LLM's are indexed under the LLM).

func (*Embedder) Create

func (e *Embedder) Create(db *gorm.DB) error

Create inserts the embedder.

func (*Embedder) Delete

func (e *Embedder) Delete(db *gorm.DB) error

Delete removes the embedder for good. It is a hard delete: a soft-deleted row would keep its name in the unique index. Callers check references first.

func (*Embedder) EffectivePrivacyScore

func (e *Embedder) EffectivePrivacyScore() int

EffectivePrivacyScore is the score the embedder is trusted with: its own for a standalone embedder, the LLM's for a linked one (0 if the LLM is not loaded or gone).

func (*Embedder) Get

func (e *Embedder) Get(db *gorm.DB, id uint) error

Get loads an embedder by id with its LLM.

func (*Embedder) IsLinked

func (e *Embedder) IsLinked() bool

IsLinked reports whether the embedder takes its connection from an LLM.

func (*Embedder) Spec

func (e *Embedder) Spec(resolveSecrets bool) (*EmbedderSpec, error)

Spec resolves the embedder. A linked embedder needs its LLM preloaded. With resolveSecrets, $SECRET/ and $ENV/ references in the key and endpoint are replaced by their values; without, they are returned as stored.

func (*Embedder) Update

func (e *Embedder) Update(db *gorm.DB) error

Update saves the embedder's own fields.

func (*Embedder) UsableInNamespace

func (e *Embedder) UsableInNamespace(ns string) error

UsableInNamespace reports whether the embedder may serve a datasource or router in namespace ns. A linked embedder carries its LLM's credentials, and edges only receive an LLM in its own namespace (or everywhere when it is global): so an LLM scoped to a namespace may only embed for objects in that namespace. A standalone embedder has no namespace. The LLM must be loaded for a linked embedder.

func (*Embedder) Validate

func (e *Embedder) Validate() error

Validate checks the embedder's shape. Whether the vendor actually serves embeddings is checked by the service layer (it needs the vendor drivers).

type EmbedderSpec

type EmbedderSpec struct {
	EmbedderID   uint
	Vendor       Vendor
	Endpoint     string
	APIKey       string
	Model        string
	PrivacyScore int
}

EmbedderSpec is an embedder resolved to what a client needs: a linked embedder's LLM fields are filled in, and secret references resolved when asked. It is the only shape runtime embedding code consumes.

func GetEmbedderResolved

func GetEmbedderResolved(db *gorm.DB, id uint) (*EmbedderSpec, error)

GetEmbedderResolved loads an embedder and resolves it, secrets included. This is how runtime code obtains an embedding configuration by id.

type Embedders

type Embedders []Embedder

Embedders is a list of embedders.

func (*Embedders) GetAll

func (es *Embedders) GetAll(db *gorm.DB, pageSize, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

GetAll lists embedders with their LLMs, paged unless all is set.

type EndpointAuthPlugin

type EndpointAuthPlugin struct {
	ObjectType string    `json:"object_type" gorm:"primaryKey;size:32;index:idx_endpoint_auth_plugins_order,priority:1"`
	ObjectID   uint      `json:"object_id" gorm:"primaryKey;autoIncrement:false;index:idx_endpoint_auth_plugins_order,priority:2"`
	PluginID   uint      `json:"plugin_id" gorm:"primaryKey;autoIncrement:false;index:idx_endpoint_auth_plugins_plugin"`
	OrderIndex int       `json:"order_index" gorm:"default:0;index:idx_endpoint_auth_plugins_order,priority:3"`
	CreatedAt  time.Time `json:"created_at"`
}

EndpointAuthPlugin attaches an auth plugin to a gateway endpoint other than an LLM. When an endpoint has any, they alone authenticate its requests, in OrderIndex order, as an LLM's attached auth plugins do.

The list lives in its own table rather than on the Datasource, Tool or router structs so the full-replace updates those objects get (the REST forms, the plugin SDK) cannot clear it, and their RPC shapes stay as they are. Rows are hard-deleted: there is no history to keep, and a tombstone would collide with the primary key when the same plugin is attached again.

func GetAllEndpointAuthPlugins

func GetAllEndpointAuthPlugins(db *gorm.DB) ([]EndpointAuthPlugin, error)

GetAllEndpointAuthPlugins returns every attachment, grouped by endpoint and ordered within it. The configuration snapshot reads them in one query.

type ErrorResponse

type ErrorResponse struct {
	Errors []struct {
		Title  string `json:"title"`
		Detail string `json:"detail"`
	} `json:"errors"`
}

ErrorResponse represents an error response

type ExportSourceType

type ExportSourceType string

ExportSourceType indicates whether the export is for an App, LLM, or User chat history

const (
	ExportSourceApp  ExportSourceType = "app"
	ExportSourceLLM  ExportSourceType = "llm"
	ExportSourceUser ExportSourceType = "user"
)

type ExportStatus

type ExportStatus string

ExportStatus represents the current state of an export job

const (
	ExportStatusPending    ExportStatus = "pending"
	ExportStatusProcessing ExportStatus = "processing"
	ExportStatusCompleted  ExportStatus = "completed"
	ExportStatusFailed     ExportStatus = "failed"
	ExportStatusExpired    ExportStatus = "expired"
)

type FileStore

type FileStore struct {
	gorm.Model
	ID              uint      `gorm:"primary_key" json:"id"`
	FileName        string    `json:"file_name"`
	Description     string    `json:"description"`
	Content         string    `json:"content"`
	Length          int       `json:"length"`
	LastProcessedOn time.Time `json:"last_processed_on"`
}

func NewFileStore

func NewFileStore() *FileStore

NewFileStore creates a new FileStore instance

func (*FileStore) Create

func (f *FileStore) Create(db *gorm.DB) error

Create a new filestore entry

func (*FileStore) Delete

func (f *FileStore) Delete(db *gorm.DB) error

Delete a filestore entry

func (*FileStore) Get

func (f *FileStore) Get(db *gorm.DB, id uint) error

Get a filestore entry by ID

func (*FileStore) GetByFileName

func (f *FileStore) GetByFileName(db *gorm.DB, fileName string) error

GetByFileName gets a filestore entry by its filename

func (*FileStore) Update

func (f *FileStore) Update(db *gorm.DB) error

Update an existing filestore entry

type FileStores

type FileStores []FileStore

FileStores represents a collection of FileStore

func (*FileStores) GetAll

func (f *FileStores) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

GetAll retrieves all filestore entries with pagination

func (*FileStores) Search

func (f *FileStores) Search(db *gorm.DB, query string) error

Search retrieves all filestore entries matching the given query in filename or description

type Filter

type Filter struct {
	gorm.Model
	ID             uint   `json:"id" gorm:"primaryKey"`
	Name           string `json:"name"`
	Description    string `json:"description"`
	Script         []byte `json:"script"`
	ResponseFilter bool   `json:"response_filter" gorm:"default:false"` // true = response filter, false = request filter
	// Kind is FilterKindScript (default) or FilterKindGuardrail.
	Kind string `json:"kind" gorm:"default:'script';index:idx_filter_kind"`
	// Config is the guardrail configuration (guardrails.Config) when Kind is
	// FilterKindGuardrail; unused for scripts.
	Config JSONMap `json:"config" gorm:"type:json"`
	// Hub-and-Spoke Configuration
	Namespace string `json:"namespace" gorm:"default:'';index:idx_filter_namespace"`
}

func DefaultFilters

func DefaultFilters() []Filter

DefaultFilters are the guardrail filters seeded on first start. They use the built-in pattern library, so they work with no external service, and they are created unattached: a filter enforces nothing until an administrator attaches it to an LLM, chat or tool, which is the deliberate "present but inactive" state for a fresh install.

func NewFilter

func NewFilter() *Filter

func (*Filter) Create

func (f *Filter) Create(db *gorm.DB) error

Create a new filter

func (*Filter) Delete

func (f *Filter) Delete(db *gorm.DB) error

Delete a filter

func (*Filter) Get

func (f *Filter) Get(db *gorm.DB, id uint) error

Get a filter by ID

func (*Filter) GetAll

func (f *Filter) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) ([]Filter, int64, int, error)

GetAll retrieves all filters

func (*Filter) GetAllWithFilters

func (f *Filter) GetAllWithFilters(db *gorm.DB, pageSize int, pageNumber int, all bool, namespace string) ([]Filter, int64, int, error)

GetAllWithFilters retrieves all filters with namespace filtering

func (*Filter) GetByName

func (f *Filter) GetByName(db *gorm.DB, name string) error

GetByName gets a filter by its name

func (*Filter) IsGuardrail

func (f *Filter) IsGuardrail() bool

IsGuardrail reports whether the filter runs a provider rather than a script.

func (*Filter) Update

func (f *Filter) Update(db *gorm.DB) error

Update an existing filter

type GormAuthRegisterBackend

type GormAuthRegisterBackend struct {
	DB *gorm.DB
}

GormAuthRegisterBackend implements AuthRegisterBackend using GORM

func (*GormAuthRegisterBackend) DeleteKey

func (g *GormAuthRegisterBackend) DeleteKey(_, _ string) error

DeleteKey deletes the value from the database for the specified key and orgId

func (*GormAuthRegisterBackend) GetAll

func (g *GormAuthRegisterBackend) GetAll(_ string) []interface{}

GetAll retrieves all values from the database for the specified orgId

func (*GormAuthRegisterBackend) GetKey

func (g *GormAuthRegisterBackend) GetKey(key, _ string, val interface{}) error

GetKey retrieves the value from the database for the specified key and orgId

func (*GormAuthRegisterBackend) Init

func (g *GormAuthRegisterBackend) Init(config interface{}) error

Init initializes the GormAuthRegisterBackend with the given configuration

func (*GormAuthRegisterBackend) SetKey

func (g *GormAuthRegisterBackend) SetKey(_, _ string, _ interface{}) error

SetKey stores the given value in the database with the specified key and orgId

type GormKVStore

type GormKVStore struct {
	DB *gorm.DB
}

GormKVStore implements AuthRegisterBackend using GORM

func (*GormKVStore) DeleteKey

func (store *GormKVStore) DeleteKey(key, orgID string) error

DeleteKey deletes a key-value pair for a given key and organization

func (*GormKVStore) GetAll

func (store *GormKVStore) GetAll(orgID string) []interface{}

GetAll retrieves all key-value pairs for a given organization

func (*GormKVStore) GetKey

func (store *GormKVStore) GetKey(key, orgID string, val interface{}) error

GetKey retrieves a value for a given key and organization

func (*GormKVStore) Init

func (store *GormKVStore) Init(config interface{}) error

Init initializes the GormKVStore with the given configuration

func (*GormKVStore) SetKey

func (store *GormKVStore) SetKey(key, orgID string, val interface{}) error

SetKey sets a key-value pair in the store for a given organization

type Group

type Group struct {
	gorm.Model
	ID             uint            `json:"id" gorm:"primaryKey"`
	Name           string          `json:"name"`
	Users          []User          `json:"users" gorm:"many2many:user_groups;"`
	Catalogues     []Catalogue     `json:"catalogues" gorm:"many2many:group_catalogues;"`
	DataCatalogues []DataCatalogue `json:"data_catalogues" gorm:"many2many:group_datacatalogues;"`
	ToolCatalogues []ToolCatalogue `json:"tool_catalogues" gorm:"many2many:group_toolcatalogues;"`
}

func GetOrCreateDefaultGroup

func GetOrCreateDefaultGroup(db *gorm.DB) (*Group, error)

GetOrCreateDefaultGroup finds or creates the Default group by name This is safe for databases where auto-increment has been reset or cleared

func NewGroup

func NewGroup() *Group

func (*Group) AddCatalogue

func (g *Group) AddCatalogue(db *gorm.DB, catalogue *Catalogue) error

func (*Group) AddDataCatalogue

func (g *Group) AddDataCatalogue(db *gorm.DB, dataCatalogue *DataCatalogue) error

func (*Group) AddToolCatalogue

func (g *Group) AddToolCatalogue(db *gorm.DB, toolCatalogue *ToolCatalogue) error

func (*Group) AddUser

func (g *Group) AddUser(db *gorm.DB, user *User) error

func (*Group) ClearAssociations

func (g *Group) ClearAssociations(db *gorm.DB) error

func (*Group) Create

func (g *Group) Create(db *gorm.DB) error

func (*Group) Delete

func (g *Group) Delete(db *gorm.DB) error

func (*Group) ExtractAssociationsIDs

func (g *Group) ExtractAssociationsIDs() (userIDs, catalogueIDs, dataCatalogueIDs, toolCatalogueIDs []uint)

func (*Group) Get

func (g *Group) Get(db *gorm.DB, id uint, preloads ...string) error

func (*Group) GetAssociationsToUpdate

func (g *Group) GetAssociationsToUpdate(userIDs, catalogueIDs, dataCatalogueIDs, toolCatalogueIDs []uint) []AssociationData

func (*Group) GetCatalogues

func (g *Group) GetCatalogues(db *gorm.DB) error

func (*Group) GetCataloguesCount

func (g *Group) GetCataloguesCount() int

func (*Group) GetDataCatalogues

func (g *Group) GetDataCatalogues(db *gorm.DB) error

func (*Group) GetDataCataloguesCount

func (g *Group) GetDataCataloguesCount() int

func (*Group) GetGroupUsers

func (g *Group) GetGroupUsers(db *gorm.DB) error

func (*Group) GetMembersCount

func (g *Group) GetMembersCount(memberCounts []GroupMemberCount) int

func (*Group) GetToolCatalogues

func (g *Group) GetToolCatalogues(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

func (*Group) GetToolCataloguesCount

func (g *Group) GetToolCataloguesCount() int

func (*Group) IsDefault

func (g *Group) IsDefault() bool

IsDefault checks if this group is the default group

func (*Group) ParseAssociations

func (g *Group) ParseAssociations(userIDs, catalogueIDs, dataCatalogueIDs, toolCatalogueIDs []uint)

func (*Group) RemoveCatalogue

func (g *Group) RemoveCatalogue(db *gorm.DB, catalogue *Catalogue) error

func (*Group) RemoveDataCatalogue

func (g *Group) RemoveDataCatalogue(db *gorm.DB, dataCatalogue *DataCatalogue) error

func (*Group) RemoveToolCatalogue

func (g *Group) RemoveToolCatalogue(db *gorm.DB, toolCatalogue *ToolCatalogue) error

func (*Group) RemoveUser

func (g *Group) RemoveUser(db *gorm.DB, user *User) error

func (*Group) ReplaceAssociation

func (g *Group) ReplaceAssociation(db *gorm.DB, associationName string, values interface{}) error

func (*Group) Update

func (g *Group) Update(db *gorm.DB) error

type GroupMemberCount

type GroupMemberCount struct {
	GroupID uint
	Count   int64
}

type GroupPluginResource

type GroupPluginResource struct {
	gorm.Model
	ID                   uint   `json:"id" gorm:"primaryKey"`
	GroupID              uint   `json:"group_id" gorm:"uniqueIndex:idx_gpr_unique;index:idx_gpr_group"`
	PluginResourceTypeID uint   `json:"plugin_resource_type_id" gorm:"uniqueIndex:idx_gpr_unique"`
	InstanceID           string `json:"instance_id" gorm:"size:255;uniqueIndex:idx_gpr_unique"`

	// Relationships
	Group              *Group              `json:"group,omitempty" gorm:"foreignKey:GroupID"`
	PluginResourceType *PluginResourceType `json:"plugin_resource_type,omitempty" gorm:"foreignKey:PluginResourceTypeID"`
}

GroupPluginResource maps Groups directly to plugin resource instances for access control. This replaces the Catalogue pattern used by built-in types (LLMs, Datasources, Tools). Access chain: User → Group → GroupPluginResource → Instance

func GetAllAccessiblePluginResources

func GetAllAccessiblePluginResources(db *gorm.DB, userID uint) ([]GroupPluginResource, error)

GetAllAccessibleByUser returns all plugin resource access entries for a user (across all groups).

func (GroupPluginResource) TableName

func (GroupPluginResource) TableName() string

type GroupPluginResources

type GroupPluginResources []GroupPluginResource

func (*GroupPluginResources) GetByGroup

func (gprs *GroupPluginResources) GetByGroup(db *gorm.DB, groupID uint) error

GetByGroup returns all plugin resource access entries for a group

func (*GroupPluginResources) GetByGroupAndType

func (gprs *GroupPluginResources) GetByGroupAndType(db *gorm.DB, groupID, resourceTypeID uint) error

GetByGroupAndType returns entries for a specific group and resource type

type Groups

type Groups []Group

func (*Groups) GetAll

func (g *Groups) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, sort string, preloads ...string) (int64, int, error)

func (*Groups) GetByNameStub

func (g *Groups) GetByNameStub(db *gorm.DB, stub string) error

func (*Groups) GetGroupsByUserID

func (g *Groups) GetGroupsByUserID(db *gorm.DB, userID uint) error

func (*Groups) GetGroupsMemberCounts

func (gs *Groups) GetGroupsMemberCounts(db *gorm.DB) ([]GroupMemberCount, error)

func (*Groups) List

func (gs *Groups) List(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

func (*Groups) SearchByTerm

func (g *Groups) SearchByTerm(db *gorm.DB, term string, pageSize int, pageNumber int, all bool, sort string, preloads ...string) (int64, int, error)

type ITokenResponse

type ITokenResponse interface {
	GetPromptTokens() int
	GetResponseTokens() int
	GetChoiceCount() int
	GetToolCount() int
	GetModel() string
	GetCacheWritePromptTokens() int
	GetCacheReadPromptTokens() int
}

type InstalledPluginVersion

type InstalledPluginVersion struct {
	gorm.Model
	ID                  uint      `json:"id" gorm:"primaryKey"`
	PluginID            uint      `json:"plugin_id" gorm:"uniqueIndex;not null"`                                    // References plugins.id
	MarketplacePluginID string    `json:"marketplace_plugin_id" gorm:"size:255;index:idx_installed_marketplace_id"` // e.g. "com.tyk.echo-agent"
	InstalledVersion    string    `json:"installed_version" gorm:"size:100"`
	AvailableVersion    string    `json:"available_version" gorm:"size:100"`
	UpdateAvailable     bool      `json:"update_available" gorm:"default:false;index:idx_update_available"`
	AutoUpdate          bool      `json:"auto_update" gorm:"default:false"`
	LastChecked         time.Time `json:"last_checked"`
	InstallSource       string    `json:"install_source" gorm:"size:100"` // marketplace, manual, oci
	CreatedAt           time.Time `json:"created_at"`
	UpdatedAt           time.Time `json:"updated_at"`

	// Relationships
	Plugin *Plugin `json:"plugin,omitempty" gorm:"foreignKey:PluginID"`
}

InstalledPluginVersion tracks installed plugins and their available updates

func CheckForUpdates

func CheckForUpdates(db *gorm.DB) ([]*InstalledPluginVersion, error)

CheckForUpdates checks if updates are available for installed plugins

func GetInstalledPluginVersion

func GetInstalledPluginVersion(db *gorm.DB, pluginID uint) (*InstalledPluginVersion, error)

GetInstalledPluginVersion gets version tracking for an installed plugin

func (InstalledPluginVersion) TableName

func (InstalledPluginVersion) TableName() string

TableName returns the table name for InstalledPluginVersion

type InteractionType

type InteractionType string
const (
	ChatInteraction  InteractionType = "chat"
	ProxyInteraction InteractionType = "proxy"
)

type JSONMap

type JSONMap map[string]interface{}

JSONMap is a custom type for map[string]interface{} to implement sql.Scanner and driver.Valuer

func (*JSONMap) Scan

func (j *JSONMap) Scan(value interface{}) error

Implement the sql.Scanner interface for JSONMap

func (JSONMap) Value

func (j JSONMap) Value() (driver.Value, error)

Implement the driver.Valuer interface for JSONMap

type KVPair

type KVPair struct {
	StoreKey   string `gorm:"primary_key"`
	OrgID      string `gorm:"index"`
	StoreValue json.RawMessage
}

KVPair represents a key-value pair in the store

type LLM

type LLM struct {
	gorm.Model
	ID               uint   `json:"id" gorm:"primary_key"`
	Name             string `json:"name"`
	APIKey           string `json:"api_key"`
	APIEndpoint      string `json:"api_endpoint"`
	DefaultModel     string `json:"default_model"`
	PrivacyScore     int    `json:"privacy_score"`
	ShortDescription string `json:"short_description"`
	LongDescription  string `json:"long_description"`
	LogoURL          string `json:"logo"`
	Vendor           Vendor `json:"vendor"`
	Active           bool   `json:"active"`
	// Budget
	MonthlyBudget   *float64   `json:"monthly_budget" gorm:"column:monthly_budget"`
	BudgetStartDate *time.Time `json:"budget_start_date" gorm:"column:budget_start_date"`
	// Hub-and-Spoke Configuration
	Namespace string `json:"namespace" gorm:"default:'';index:idx_llm_namespace"`
	// Body logging control - when true, request/response bodies are NOT stored in proxy logs
	DontLogBodies bool `json:"dont_log_bodies" gorm:"default:false"`

	Filters       []*Filter `json:"filters" gorm:"many2many:llm_filters;"`
	Plugins       []*Plugin `json:"plugins" gorm:"many2many:llm_plugins;"`
	AllowedModels []string  `json:"allowed_models" gorm:"serializer:json"`

	// Plugin-stored metadata
	Metadata JSONMap `json:"metadata" gorm:"type:json"`

	// Failover is the ordered waterfall of (LLM, model) pairs the proxy tries
	// when this LLM's upstream fails. Empty means no failover. Stored via
	// Scanner/Valuer rather than serializer:json because the row is an audit
	// snapshot target and serializer-tagged fields break that map scan.
	Failover LLMFailover `json:"failover" gorm:"type:json"`
}

func NewLLM

func NewLLM() *LLM

func SemanticRouterReachableLLMs

func SemanticRouterReachableLLMs(db *gorm.DB, routerID uint) ([]LLM, error)

SemanticRouterReachableLLMs lists the active LLMs a router's routes can send a request to: its LLM targets and the active vendors of the Model Routers it hands off to. (Its embedding and judge LLMs see the prompt but never answer it, so they are not listed here.)

func (*LLM) AfterDelete

func (l *LLM) AfterDelete(tx *gorm.DB) error

AfterDelete drops the LLM's secret references (soft deletes included).

func (*LLM) AfterSave

func (l *LLM) AfterSave(tx *gorm.DB) error

AfterSave keeps the secret_references rows for this LLM current. The row is re-read because a partial update (Model(&llm).Update("active", ...)) reaches the hook with only the fields the caller set.

func (*LLM) Create

func (l *LLM) Create(db *gorm.DB) error

func (*LLM) Delete

func (l *LLM) Delete(db *gorm.DB) error

func (*LLM) Get

func (l *LLM) Get(db *gorm.DB, id uint) error

func (*LLM) GetByName

func (l *LLM) GetByName(db *gorm.DB, name string) error

func (*LLM) Update

func (l *LLM) Update(db *gorm.DB) error

type LLMChatLogEntry

type LLMChatLogEntry struct {
	gorm.Model
	ID        uint `gorm:"primaryKey"`
	Name      string
	Vendor    string
	TimeStamp time.Time
	Prompt    string
	Response  string
	Tokens    int
	UserID    uint
	ChatID    string
	SessionID string
}

LLMChatLogEntry for storing extra logs

type LLMChatRecord

type LLMChatRecord struct {
	gorm.Model
	ID     uint `gorm:"primaryKey"`
	Name   string
	Vendor string
	// Add LLMID so we can track usage for that specific LLM object:
	LLMID                  uint `gorm:"index:idx_llm_chat_records_llm_time,priority:1"`
	TotalTimeMS            int
	PromptTokens           int
	ResponseTokens         int
	TotalTokens            int
	TimeStamp              time.Time `` /* 180-byte string literal not displayed */
	UserID                 uint      `gorm:"index"`
	Choices                int
	ToolCalls              int
	ChatID                 string
	AppID                  uint `gorm:"index:idx_llm_chat_records_app_time,priority:1"`
	Cost                   float64
	Currency               string
	InteractionType        InteractionType `gorm:"type:string;default:'chat'"`
	CacheWritePromptTokens int
	CacheReadPromptTokens  int
	// TeamID is the team the spend is attributed to: the App's team for
	// proxy and edge traffic, the user's budget team for chat.
	TeamID *uint `gorm:"index:idx_llm_chat_records_team_time,priority:1"`
	// OnBehalfOf and ActingAgent are who the call was for and the agent that
	// made it, when an auth plugin said (a delegated token's sub, and its act
	// or azp). UserID stays the App owner. Audit only.
	OnBehalfOf  string `gorm:"size:255"`
	ActingAgent string `gorm:"size:255"`
}

LLMChatRecord logs usage for cost and analytics.

Rows are insert-only: never update or delete them. The hub budget sync (grpc budgetUsageTracker) and usage telemetry (TokenTotals) read only the rows added since their last pass, found by id, so a changed or removed row would stay counted as it was.

type LLMFailover

type LLMFailover struct {
	Targets  []LLMFailoverTarget  `json:"targets"`
	Triggers *LLMFailoverTriggers `json:"triggers,omitempty"`
}

LLMFailover is the ordered waterfall tried when an LLM's upstream fails. It is stored as a JSON column on the LLM row. An empty Targets list means no failover and is persisted as SQL NULL, so untouched LLMs stay NULL.

Only the primary's waterfall is consulted for a request; a fallback's own waterfall is never followed, so chains cannot loop.

func (LLMFailover) EffectiveTriggers

func (f LLMFailover) EffectiveTriggers() ResolvedFailoverTriggers

EffectiveTriggers applies the defaults. Status codes below 500 other than 408 and 429 are dropped here as well as at validation time, so a row that bypassed the API cannot make a 403 fail over.

func (LLMFailover) Enabled

func (f LLMFailover) Enabled() bool

Enabled reports whether there is anything to fall over to.

func (*LLMFailover) Scan

func (f *LLMFailover) Scan(value interface{}) error

Scan implements sql.Scanner. A NULL column is an empty waterfall.

func (LLMFailover) Value

func (f LLMFailover) Value() (driver.Value, error)

Value implements driver.Valuer. No targets is stored as NULL rather than as "{}" so existing rows and LLMs that never had a waterfall look the same.

type LLMFailoverTarget

type LLMFailoverTarget struct {
	LLMID uint   `json:"llm_id"`
	Model string `json:"model"`
}

LLMFailoverTarget is one rung of the waterfall: which LLM entry to try and which model to ask it for. Model is required and must satisfy the target LLM's allowed-models list; that is checked when the primary is saved and again at request time, because the target's list can change later.

type LLMFailoverTriggers

type LLMFailoverTriggers struct {
	StatusCodes          []int `json:"status_codes,omitempty"`
	OnTimeout            *bool `json:"on_timeout,omitempty"`
	OnConnectionError    *bool `json:"on_connection_error,omitempty"`
	AttemptTimeoutSecond int   `json:"attempt_timeout_seconds,omitempty"`
}

LLMFailoverTriggers narrows when the waterfall is consulted. Nil pointers mean "use the default", so a stored config that predates a new knob keeps the documented behaviour.

type LLMFilter

type LLMFilter struct {
	LLMID      uint `json:"llm_id" gorm:"primaryKey"`
	FilterID   uint `json:"filter_id" gorm:"primaryKey"`
	OrderIndex int  `json:"order_index" gorm:"not null;default:0"`
}

LLMFilter is the llm_filters join row. OrderIndex is the filter's position in the LLM's chain as the admin arranged it: filters run top to bottom and the first block wins, so the order has to be persisted rather than left to whatever order the preload happens to return (id order). The same column exists on the edge schema and the snapshot sends FilterIds in this order.

func (LLMFilter) TableName

func (LLMFilter) TableName() string

type LLMPlugin

type LLMPlugin struct {
	LLMID          uint                   `json:"llm_id" gorm:"primaryKey;index:idx_llm_plugins_llm_id"`
	PluginID       uint                   `json:"plugin_id" gorm:"primaryKey"`
	OrderIndex     int                    `json:"order_index" gorm:"default:0;index:idx_llm_plugins_order"`
	IsActive       bool                   `json:"is_active" gorm:"default:true"`
	ConfigOverride map[string]interface{} `json:"config_override" gorm:"serializer:json"`
	CreatedAt      time.Time              `json:"created_at"`
	UpdatedAt      time.Time              `json:"updated_at"`

	// Relationships
	LLM    *LLM    `json:"llm,omitempty" gorm:"foreignKey:LLMID"`
	Plugin *Plugin `json:"plugin,omitempty" gorm:"foreignKey:PluginID"`
}

LLMPlugin represents the many-to-many relationship between LLMs and plugins

func NewLLMPlugin

func NewLLMPlugin() *LLMPlugin

NewLLMPlugin creates a new LLMPlugin association

func (*LLMPlugin) Activate

func (lp *LLMPlugin) Activate(db *gorm.DB) error

Activate activates this LLM-Plugin association

func (*LLMPlugin) Create

func (lp *LLMPlugin) Create(db *gorm.DB) error

Create creates a new LLM-Plugin association

func (*LLMPlugin) Deactivate

func (lp *LLMPlugin) Deactivate(db *gorm.DB) error

Deactivate deactivates this LLM-Plugin association

func (*LLMPlugin) Delete

func (lp *LLMPlugin) Delete(db *gorm.DB) error

Delete removes an LLM-Plugin association

func (*LLMPlugin) Get

func (lp *LLMPlugin) Get(db *gorm.DB, llmID, pluginID uint) error

Get retrieves an LLM-Plugin association by LLM ID and Plugin ID

func (*LLMPlugin) Update

func (lp *LLMPlugin) Update(db *gorm.DB) error

Update updates an existing LLM-Plugin association

func (*LLMPlugin) UpdateConfig

func (lp *LLMPlugin) UpdateConfig(db *gorm.DB, config map[string]interface{}) error

UpdateConfig updates the configuration override for this association

func (*LLMPlugin) UpdateOrder

func (lp *LLMPlugin) UpdateOrder(db *gorm.DB, newOrder int) error

UpdateOrder updates the execution order for this association

type LLMPlugins

type LLMPlugins []LLMPlugin

func (*LLMPlugins) GetActiveAssociations

func (llmPlugins *LLMPlugins) GetActiveAssociations(db *gorm.DB) error

GetActiveAssociations returns all active LLM-Plugin associations

func (*LLMPlugins) GetLLMsForPlugin

func (llmPlugins *LLMPlugins) GetLLMsForPlugin(db *gorm.DB, pluginID uint) error

GetLLMsForPlugin returns all LLMs associated with a specific plugin

func (*LLMPlugins) GetPluginsForLLM

func (llmPlugins *LLMPlugins) GetPluginsForLLM(db *gorm.DB, llmID uint) error

GetPluginsForLLM returns all active plugins for a specific LLM, ordered by execution order

type LLMSettings

type LLMSettings struct {
	gorm.Model
	ID                uint                   `gorm:"primaryKey" json:"id"`
	MaxLength         int                    `json:"max_length"`
	MaxTokens         int                    `json:"max_tokens"`
	Metadata          map[string]interface{} `gorm:"serializer:json" json:"metadata"`
	MinLength         int                    `json:"min_length"`
	ModelName         string                 `json:"model_name"`
	RepetitionPenalty float64                `json:"repetition_penalty"`
	Seed              int                    `json:"seed"`
	StopWords         []string               `gorm:"serializer:json" json:"stop_words"`
	Temperature       float64                `json:"temperature"`
	TopK              int                    `json:"top_k"`
	TopP              float64                `json:"top_p"`
	SystemPrompt      string                 `json:"system_prompt"`
}

func DefaultLLMSettings

func DefaultLLMSettings() []LLMSettings

DefaultLLMSettings returns a slice of default LLM settings for popular SOTA models. These settings are based on official vendor documentation as of December 2025.

func NewLLMSettings

func NewLLMSettings() *LLMSettings

func (*LLMSettings) Create

func (ls *LLMSettings) Create(db *gorm.DB) error

Create a new LLMSettings

func (*LLMSettings) Delete

func (ls *LLMSettings) Delete(db *gorm.DB) error

Delete an LLMSettings

func (*LLMSettings) GenerateOptionsFromSettings

func (ls *LLMSettings) GenerateOptionsFromSettings(tools []llms.Tool, mode string, streamingFunc func(ctx context.Context, chunk []byte) error) []llms.CallOption

func (*LLMSettings) Get

func (ls *LLMSettings) Get(db *gorm.DB, id uint) error

Get an LLMSettings by ID

func (*LLMSettings) GetByModel

func (ls *LLMSettings) GetByModel(db *gorm.DB, model string) error

Get LLMSettings by Model

func (*LLMSettings) Update

func (ls *LLMSettings) Update(db *gorm.DB) error

Update an existing LLMSettings

type LLMSettingsSlice

type LLMSettingsSlice []LLMSettings

func (*LLMSettingsSlice) GetAll

func (ls *LLMSettingsSlice) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

Get all LLMSettings

func (*LLMSettingsSlice) SearchByModelStub

func (ls *LLMSettingsSlice) SearchByModelStub(db *gorm.DB, modelStub string) error

Search LLMSettings by Model name stub

type LLMVendorProvider

type LLMVendorProvider interface {
	GetTokenCounts(choice *llms.ContentChoice) (int, int, int)
	GetDriver(LLMConfig *LLM, settings *LLMSettings, mem schema.Memory, streamingFunc func(ctx context.Context, chunk []byte) error) (llms.Model, error)
	GetEmbedder(spec *EmbedderSpec) (*embeddings.EmbedderImpl, error)
	AnalyzeResponse(llm *LLM, app *App, statusCode int, body []byte, r *http.Request) (*LLM, *App, ITokenResponse, error)
	AnalyzeStreamingResponse(llm *LLM, app *App, statusCode int, resps []byte, r *http.Request, chunks [][]byte) (*LLM, *App, ITokenResponse, error)
	ProxySetAuthHeader(r *http.Request, llm *LLM) error
	ProxyScreenRequest(llm *LLM, r *http.Request, isStreamingChannel bool) error

	ProvidesEmbedder() bool
}

type LLMs

type LLMs []LLM

func (*LLMs) GetActiveLLMs

func (l *LLMs) GetActiveLLMs(db *gorm.DB) error

func (*LLMs) GetAll

func (l *LLMs) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

func (*LLMs) GetByMaxPrivacyScore

func (l *LLMs) GetByMaxPrivacyScore(db *gorm.DB, score int) error

func (*LLMs) GetByMinPrivacyScore

func (l *LLMs) GetByMinPrivacyScore(db *gorm.DB, score int) error

func (*LLMs) GetByNameStub

func (l *LLMs) GetByNameStub(db *gorm.DB, stub string) error

func (*LLMs) GetByPrivacyScoreRange

func (l *LLMs) GetByPrivacyScoreRange(db *gorm.DB, min, max int) error

func (*LLMs) GetLLMCount

func (l *LLMs) GetLLMCount(db *gorm.DB) (int64, error)

type LegacyEmbed

type LegacyEmbed struct {
	Vendor string `json:"embed_vendor"`
	URL    string `json:"embed_url"`
	APIKey string `json:"embed_api_key"`
	Model  string `json:"embed_model"`
}

LegacyEmbed is the inline embedding configuration a datasource JSON document carried.

type MCPAccessGrant

type MCPAccessGrant struct {
	gorm.Model
	AppID           uint       `gorm:"index;uniqueIndex:idx_mcp_grants_open,where:revoked_at IS NULL" json:"app_id"`
	MCPServerID     uint       `gorm:"column:mcp_server_id;index;uniqueIndex:idx_mcp_grants_open,where:revoked_at IS NULL" json:"mcp_server_id"`
	UserID          uint       `gorm:"index" json:"user_id"`
	GrantKind       string     `gorm:"size:16;not null" json:"grant_kind"`
	CredentialID    *string    `gorm:"size:36;index" json:"credential_id"`
	GrantedAt       time.Time  `json:"granted_at"`
	GrantedByUserID uint       `json:"granted_by_user_id"`
	RevokedAt       *time.Time `gorm:"index" json:"revoked_at"`
	RevokeReason    string     `gorm:"size:255" json:"revoke_reason,omitempty"`
}

MCPAccessGrant records that an App (and so its owner) has access to an MCP server, whether or not Studio minted a key for it. One open row per (app, server); revoked rows are kept for the access report.

func (*MCPAccessGrant) IsOpen

func (g *MCPAccessGrant) IsOpen() bool

IsOpen reports whether the grant is current.

func (MCPAccessGrant) TableName

func (MCPAccessGrant) TableName() string

type MCPAuthDetails

type MCPAuthDetails struct {
	// Header, Query or Cookie name the token scheme reads (auth_token, basic, jwt).
	HeaderName string `json:"header_name,omitempty"`
	QueryName  string `json:"query_name,omitempty"`
	CookieName string `json:"cookie_name,omitempty"`
	// Schemes lists every enabled scheme name with its resolved type.
	Schemes []MCPAuthScheme `json:"schemes,omitempty"`
	// PRM is the OAuth 2.1 protected resource metadata when advertised.
	PRM *MCPProtectedResourceMetadata `json:"prm,omitempty"`
}

MCPAuthDetails describes how a client authenticates to the proxy. Never carries secrets.

type MCPAuthScheme

type MCPAuthScheme struct {
	Name string `json:"name"`
	Type string `json:"type"` // an MCPAuth* value
}

MCPAuthScheme is one security scheme on the proxy.

type MCPCredential

type MCPCredential struct {
	ID           string         `gorm:"primaryKey;size:36" json:"id"`
	AppID        uint           `` /* 134-byte string literal not displayed */
	ConnectionID uint           `` /* 141-byte string literal not displayed */
	Purpose      string         `` /* 158-byte string literal not displayed */
	App          *App           `gorm:"foreignKey:AppID" json:"-"`
	Connection   *TykConnection `gorm:"foreignKey:ConnectionID" json:"-"`

	Status string `gorm:"size:16;index;not null" json:"status"`

	TykKeyHash       string `gorm:"size:128;index" json:"tyk_key_hash"`
	TykKeyPlainToken string `gorm:"type:text" json:"-"`
	Alias            string `gorm:"size:255" json:"alias"`

	AppliedPolicyIDsJSON  string `gorm:"column:applied_policy_ids;type:text" json:"-"`
	ExternalPolicyIDsJSON string `gorm:"column:external_policy_ids;type:text" json:"-"`
	DesiredPolicyIDsJSON  string `gorm:"column:desired_policy_ids;type:text" json:"-"`
	Drift                 string `gorm:"size:16;index;not null;default:none" json:"drift"`
	DriftDetail           string `gorm:"size:1024" json:"drift_detail,omitempty"`

	ExpiresAt *time.Time `json:"expires_at"`

	MintedByUserID   uint       `json:"minted_by_user_id"`
	MintedAt         *time.Time `json:"minted_at"`
	RevealedToUserID uint       `json:"revealed_to_user_id"`
	RevealedAt       *time.Time `json:"revealed_at"`
	RevokedByUserID  uint       `json:"revoked_by_user_id"`
	RevokedAt        *time.Time `json:"revoked_at"`
	RevokeReason     string     `gorm:"size:255" json:"revoke_reason,omitempty"`
	RevokeMode       string     `gorm:"size:16" json:"revoke_mode,omitempty"`

	LastSyncedAt *time.Time `json:"last_synced_at"`
	LastError    string     `gorm:"size:1024" json:"last_error,omitempty"`
	LockVersion  int        `gorm:"not null;default:0" json:"lock_version"`
	CreatedAt    time.Time  `json:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at"`
}

MCPCredential is the ledger row for one Tyk key Studio minted for an App on one connection. The key's plaintext is never stored: it is returned once by the mint call. TykKeyPlainToken is only used when the Dashboard runs with key hashing disabled, where the key id is the plaintext and is needed to address the key; it is encrypted at rest.

func (*MCPCredential) AfterFind

func (c *MCPCredential) AfterFind(tx *gorm.DB) error

AfterFind decrypts the plaintext key id.

func (*MCPCredential) AfterSave

func (c *MCPCredential) AfterSave(tx *gorm.DB) error

AfterSave restores plaintext on the in-memory struct.

func (*MCPCredential) AppliedPolicyIDs

func (c *MCPCredential) AppliedPolicyIDs() []string

AppliedPolicyIDs are the Studio-owned policy ids the key carries.

func (*MCPCredential) BeforeSave

func (c *MCPCredential) BeforeSave(tx *gorm.DB) error

BeforeSave encrypts the plaintext key id (unhashed Dashboards only), refusing to store it when the encryption key is not configured.

func (*MCPCredential) DesiredPolicyIDs

func (c *MCPCredential) DesiredPolicyIDs() []string

func (*MCPCredential) ExternalPolicyIDs

func (c *MCPCredential) ExternalPolicyIDs() []string

func (*MCPCredential) IsLive

func (c *MCPCredential) IsLive() bool

IsLive reports whether the credential occupies the App's slot.

func (*MCPCredential) KeyRef

func (c *MCPCredential) KeyRef() (string, bool)

KeyRef returns the identifier to address the key on the Dashboard and whether it is a hash.

func (*MCPCredential) SetAppliedPolicyIDs

func (c *MCPCredential) SetAppliedPolicyIDs(ids []string)

func (*MCPCredential) SetDesiredPolicyIDs

func (c *MCPCredential) SetDesiredPolicyIDs(ids []string)

func (*MCPCredential) SetExternalPolicyIDs

func (c *MCPCredential) SetExternalPolicyIDs(ids []string)

func (MCPCredential) TableName

func (MCPCredential) TableName() string

func (*MCPCredential) ToResponse

func (c *MCPCredential) ToResponse() MCPCredentialResponse

ToResponse converts the credential to its API shape.

type MCPCredentialResponse

type MCPCredentialResponse struct {
	ID                string     `json:"id"`
	AppID             uint       `json:"app_id"`
	AppName           string     `json:"app_name,omitempty"`
	ConnectionID      uint       `json:"connection_id"`
	ConnectionName    string     `json:"connection_name,omitempty"`
	Purpose           string     `json:"purpose"`
	Status            string     `json:"status"`
	TykKeyHash        string     `json:"tyk_key_hash"`
	KeyHint           string     `json:"key_hint,omitempty"`
	Alias             string     `json:"alias"`
	AppliedPolicyIDs  []string   `json:"applied_policy_ids"`
	ExternalPolicyIDs []string   `json:"external_policy_ids"`
	DesiredPolicyIDs  []string   `json:"desired_policy_ids"`
	Drift             string     `json:"drift"`
	DriftDetail       string     `json:"drift_detail,omitempty"`
	ExpiresAt         *time.Time `json:"expires_at,omitempty"`
	MintedByUserID    uint       `json:"minted_by_user_id"`
	MintedAt          *time.Time `json:"minted_at,omitempty"`
	RevealedToUserID  uint       `json:"revealed_to_user_id"`
	RevealedAt        *time.Time `json:"revealed_at,omitempty"`
	RevokedByUserID   uint       `json:"revoked_by_user_id,omitempty"`
	RevokedAt         *time.Time `json:"revoked_at,omitempty"`
	RevokeReason      string     `json:"revoke_reason,omitempty"`
	RevokeMode        string     `json:"revoke_mode,omitempty"`
	LastSyncedAt      *time.Time `json:"last_synced_at,omitempty"`
	LastError         string     `json:"last_error,omitempty"`
	LockVersion       int        `json:"lock_version"`
	CreatedAt         time.Time  `json:"created_at"`
	UpdatedAt         time.Time  `json:"updated_at"`
}

MCPCredentialResponse is the API shape of a credential. It never carries the key.

type MCPGatewayTags

type MCPGatewayTags struct {
	Enabled bool     `json:"enabled"`
	Tags    []string `json:"tags"`
}

MCPGatewayTags mirrors x-tyk-api-gateway.server.gatewayTags.

type MCPPrimitive

type MCPPrimitive struct {
	Type        string                 `json:"type"` // tool | resource | prompt
	Name        string                 `json:"name"`
	Description string                 `json:"description,omitempty"`
	Annotations map[string]interface{} `json:"annotations,omitempty"`
	// Auth records per-primitive overrides from the definition.
	Auth *MCPPrimitiveAuth `json:"auth,omitempty"`
	// Source names the REST operation behind a REST-to-MCP tool.
	Source string `json:"source,omitempty"`
}

MCPPrimitive is one tool, resource or prompt known to Studio.

type MCPPrimitiveAuth

type MCPPrimitiveAuth struct {
	IgnoreAuthentication bool     `json:"ignore_authentication,omitempty"`
	Scopes               []string `json:"scopes,omitempty"`
}

MCPPrimitiveAuth is the per-primitive authentication override.

type MCPProtectedResourceMetadata

type MCPProtectedResourceMetadata struct {
	Resource             string   `json:"resource,omitempty"`
	AuthorizationServers []string `json:"authorization_servers,omitempty"`
	ScopesSupported      []string `json:"scopes_supported,omitempty"`
	AutoDeriveScopes     bool     `json:"auto_derive_scopes,omitempty"`
	WellKnownPath        string   `json:"well_known_path,omitempty"`
	// URL is the absolute metadata URL when the endpoint URL is known.
	URL string `json:"url,omitempty"`
}

MCPProtectedResourceMetadata mirrors RFC 9728 as configured on the proxy.

type MCPServer

type MCPServer struct {
	gorm.Model
	ConnectionID *uint          `gorm:"index;uniqueIndex:idx_mcp_servers_live_conn_api,where:deleted_at IS NULL" json:"connection_id"`
	Connection   *TykConnection `gorm:"foreignKey:ConnectionID" json:"-"`
	// TykAPIID is x-tyk-api-gateway.info.id; empty while pending_platform.
	TykAPIID string `gorm:"size:64;uniqueIndex:idx_mcp_servers_live_conn_api,where:deleted_at IS NULL" json:"tyk_api_id"`

	Name           string `gorm:"size:200;not null" json:"name"`
	NameOverridden bool   `json:"name_overridden"`
	// Soft-deleted rows keep their slug and api id out of the way: the unique
	// indexes only cover live rows, so a deleted server can be re-imported or
	// re-registered under the same name.
	Slug            string `gorm:"size:200;uniqueIndex:idx_mcp_servers_live_slug,where:deleted_at IS NULL" json:"slug"`
	Description     string `gorm:"size:2048" json:"description"`
	LongDescription string `gorm:"type:text" json:"long_description"`
	LogoURL         string `gorm:"size:2048" json:"logo_url"`
	TagsJSON        string `gorm:"column:tags;type:text" json:"-"`

	Kind            string `gorm:"size:16;not null;default:remote" json:"kind"`
	ListenPath      string `gorm:"size:512" json:"listen_path"`
	ListenPathStrip bool   `json:"listen_path_strip"`
	TransportPath   string `gorm:"size:512" json:"transport_path"`
	EndpointURL     string `gorm:"size:2048" json:"endpoint_url"`
	// EndpointURLsJSON is map[tag]url when the proxy is segmented.
	EndpointURLsJSON string `gorm:"column:endpoint_urls;type:text" json:"-"`
	// UpstreamURL is admin-only; never in portal responses.
	UpstreamURL string `gorm:"size:2048" json:"-"`
	SourceAPIID string `gorm:"size:64" json:"source_api_id"`

	AuthMode        string `gorm:"size:32;not null;default:custom" json:"auth_mode"`
	AuthDetailsJSON string `gorm:"column:auth_details;type:text" json:"-"`
	PrimitivesJSON  string `gorm:"column:primitives;type:text" json:"-"`
	GatewayTagsJSON string `gorm:"column:gateway_tags;type:text" json:"-"`

	// Definition is the last synced OAS document with upstream.authentication
	// values masked. DefinitionHash is over the unmasked canonical form.
	Definition     string `gorm:"type:text" json:"-"`
	DefinitionHash string `gorm:"size:64" json:"definition_hash"`
	DashboardState string `gorm:"size:20;index;not null;default:active" json:"dashboard_state"`
	Origin         string `gorm:"size:16;not null;default:dashboard" json:"origin"`
	SubmissionID   *uint  `gorm:"index" json:"submission_id"`

	// PrivacyScore is nil until an administrator sets it; publish refuses meanwhile.
	PrivacyScore *int `json:"privacy_score"`
	IsActive     bool `gorm:"index" json:"is_active"`
	Brokerable   bool `json:"brokerable"`

	OwnerUserID        uint `json:"owner_user_id"`
	CommunitySubmitted bool `json:"community_submitted"`

	LastSeenAt   *time.Time `json:"last_seen_at"`
	LastSyncedAt *time.Time `json:"last_synced_at"`
	LockVersion  int        `gorm:"not null;default:0" json:"lock_version"`

	// Portal visibility follows the platform rule: catalogues bundle assets,
	// teams are granted catalogues. MCP servers live in tool catalogues.
	ToolCatalogues []ToolCatalogue `gorm:"many2many:tool_catalogue_mcp_servers;" json:"-"`
}

MCPServer is an MCP proxy managed by a Tyk Gateway, catalogued in AI Studio. Definition-derived columns follow the Dashboard on every sync; Studio-owned presentation and governance columns never do.

func (*MCPServer) AuthDetails

func (m *MCPServer) AuthDetails() MCPAuthDetails

AuthDetails decodes the authentication details.

func (*MCPServer) CanPublish

func (m *MCPServer) CanPublish() (bool, string)

CanPublish reports whether the server may be made visible in the portal.

func (*MCPServer) EndpointURLs

func (m *MCPServer) EndpointURLs() map[string]string

EndpointURLs decodes the per-tag endpoint URLs.

func (*MCPServer) GatewayTags

func (m *MCPServer) GatewayTags() MCPGatewayTags

GatewayTags decodes the segmentation tags.

func (*MCPServer) Primitives

func (m *MCPServer) Primitives() []MCPPrimitive

Primitives decodes the known primitives.

func (*MCPServer) SetAuthDetails

func (m *MCPServer) SetAuthDetails(d MCPAuthDetails)

SetAuthDetails encodes the authentication details.

func (*MCPServer) SetEndpointURLs

func (m *MCPServer) SetEndpointURLs(u map[string]string)

SetEndpointURLs encodes the per-tag endpoint URLs.

func (*MCPServer) SetGatewayTags

func (m *MCPServer) SetGatewayTags(t MCPGatewayTags)

SetGatewayTags encodes the segmentation tags.

func (*MCPServer) SetPrimitives

func (m *MCPServer) SetPrimitives(p []MCPPrimitive)

SetPrimitives encodes the known primitives.

func (*MCPServer) SetTags

func (m *MCPServer) SetTags(tags []string)

SetTags encodes the presentation tags.

func (MCPServer) TableName

func (MCPServer) TableName() string

func (*MCPServer) Tags

func (m *MCPServer) Tags() []string

Tags decodes the presentation tags.

func (*MCPServer) ToResponse

func (m *MCPServer) ToResponse(detail bool) MCPServerResponse

ToResponse converts the server to its administrator API shape.

type MCPServerCatalogueView

type MCPServerCatalogueView struct {
	ID   uint   `json:"id"`
	Name string `json:"name"`
}

MCPServerCatalogueView names a tool catalogue the server belongs to.

type MCPServerPolicyPin

type MCPServerPolicyPin struct {
	gorm.Model
	MCPServerID uint `gorm:"column:mcp_server_id;index;uniqueIndex:idx_mcp_pins_server_policy" json:"mcp_server_id"`
	// PolicyID is the tyk_policies row id (not the Tyk-side policy id).
	PolicyID      uint       `gorm:"index;uniqueIndex:idx_mcp_pins_server_policy" json:"policy_id"`
	TykPolicy     *TykPolicy `gorm:"foreignKey:PolicyID;references:ID" json:"-"`
	Role          string     `gorm:"size:16;not null" json:"role"`
	Position      int        `json:"position"`
	InvalidReason string     `gorm:"size:1024" json:"invalid_reason"`
}

MCPServerPolicyPin is one policy in a server's bundle.

func (MCPServerPolicyPin) TableName

func (MCPServerPolicyPin) TableName() string

func (*MCPServerPolicyPin) ToView

ToView converts a pin (with its policy preloaded) to the API shape.

type MCPServerPolicyPinView

type MCPServerPolicyPinView struct {
	ID            uint              `json:"id"`
	Role          string            `json:"role"`
	Position      int               `json:"position"`
	InvalidReason string            `json:"invalid_reason,omitempty"`
	Policy        TykPolicyResponse `json:"policy"`
}

MCPServerPolicyPinView is the API shape of a pin with its policy summary.

type MCPServerResponse

type MCPServerResponse struct {
	ID                 uint              `json:"id"`
	ConnectionID       *uint             `json:"connection_id"`
	ConnectionName     string            `json:"connection_name,omitempty"`
	TykAPIID           string            `json:"tyk_api_id"`
	Name               string            `json:"name"`
	NameOverridden     bool              `json:"name_overridden"`
	Slug               string            `json:"slug"`
	Description        string            `json:"description"`
	LongDescription    string            `json:"long_description"`
	LogoURL            string            `json:"logo_url"`
	Tags               []string          `json:"tags"`
	Kind               string            `json:"kind"`
	ListenPath         string            `json:"listen_path"`
	TransportPath      string            `json:"transport_path"`
	EndpointURL        string            `json:"endpoint_url"`
	EndpointURLs       map[string]string `json:"endpoint_urls"`
	UpstreamURL        string            `json:"upstream_url"`
	SourceAPIID        string            `json:"source_api_id,omitempty"`
	AuthMode           string            `json:"auth_mode"`
	AuthDetails        MCPAuthDetails    `json:"auth_details"`
	Primitives         []MCPPrimitive    `json:"primitives"`
	GatewayTags        MCPGatewayTags    `json:"gateway_tags"`
	DefinitionHash     string            `json:"definition_hash"`
	DashboardState     string            `json:"dashboard_state"`
	Origin             string            `json:"origin"`
	SubmissionID       *uint             `json:"submission_id,omitempty"`
	PrivacyScore       *int              `json:"privacy_score"`
	IsActive           bool              `json:"is_active"`
	Brokerable         bool              `json:"brokerable"`
	OwnerUserID        uint              `json:"owner_user_id"`
	CommunitySubmitted bool              `json:"community_submitted"`
	LastSeenAt         *time.Time        `json:"last_seen_at,omitempty"`
	LastSyncedAt       *time.Time        `json:"last_synced_at,omitempty"`
	LockVersion        int               `json:"lock_version"`
	CreatedAt          time.Time         `json:"created_at"`
	UpdatedAt          time.Time         `json:"updated_at"`
	// Detail-only fields.
	Definition       string                   `json:"definition,omitempty"`
	ToolCatalogueIDs []uint                   `json:"tool_catalogue_ids,omitempty"`
	ToolCatalogues   []MCPServerCatalogueView `json:"tool_catalogues,omitempty"`
	Bundle           []MCPServerPolicyPinView `json:"bundle,omitempty"`
}

MCPServerResponse is the administrator API shape. Upstream URL and the definition are admin-only; the portal projection lives in the catalogue.

type MCPSyncRun

type MCPSyncRun struct {
	ID           uint       `gorm:"primaryKey" json:"id"`
	ConnectionID uint       `gorm:"index" json:"connection_id"`
	NodeID       string     `gorm:"size:255" json:"node_id"`
	StartedAt    time.Time  `gorm:"index" json:"started_at"`
	FinishedAt   *time.Time `json:"finished_at"`
	Status       string     `gorm:"size:16" json:"status"`
	Trigger      string     `gorm:"size:16" json:"trigger"` // schedule | manual

	ProxiesSeen    int `json:"proxies_seen"`
	ProxiesAdded   int `json:"proxies_added"`
	ProxiesUpdated int `json:"proxies_updated"`
	ProxiesMissing int `json:"proxies_missing"`
	ProxiesResumed int `json:"proxies_resumed"`

	PoliciesSeen    int `json:"policies_seen"`
	PoliciesUpdated int `json:"policies_updated"`
	PoliciesMissing int `json:"policies_missing"`

	CredentialsChecked int `json:"credentials_checked"`
	CredentialsDrifted int `json:"credentials_drifted"`

	Error string `gorm:"size:2048" json:"error,omitempty"`
}

MCPSyncRun records one discovery sync of a connection. Append-only; pruned by retention.

func (MCPSyncRun) TableName

func (MCPSyncRun) TableName() string

type ManifestMetadata

type ManifestMetadata struct {
	Vocabularies []ManifestVocabulary `json:"vocabularies,omitempty"`
	Schemas      []ManifestSchema     `json:"schemas,omitempty"`
}

ManifestMetadata declares governed-metadata vocabularies and schemas contributed by a plugin. Contributed schemas are created inactive and advisory; admins opt them in.

type ManifestPermissionResource

type ManifestPermissionResource struct {
	Key         string   `json:"key"`
	Label       string   `json:"label"`
	Description string   `json:"description,omitempty"`
	Actions     []string `json:"actions"`
	Sensitive   bool     `json:"sensitive,omitempty"`
}

ManifestPermissionResource declares one plugin sub-resource.

type ManifestRBAC

type ManifestRBAC struct {
	// Sensitive withholds the plugin's read from read-only system roles
	// (Viewer, Auditor), like the platform's sensitive data classes.
	Sensitive bool `json:"sensitive,omitempty"`
	// Resources are the sub-resources the plugin declares.
	Resources []ManifestPermissionResource `json:"resources,omitempty"`
	// RPCMethods maps admin RPC method names to the permission they need.
	RPCMethods map[string]string `json:"rpc_methods,omitempty"`
}

ManifestRBAC is the manifest's "rbac" block: the permission resources a plugin contributes to the role editor and how its admin RPC methods map onto them. Every plugin with an admin surface already gets a base resource ("plugin:<manifest id>" with read/write/execute); this block adds sub-resources ("plugin:<manifest id>:<key>") and per-method requirements.

"rbac": {
  "sensitive": false,
  "resources": [
    {"key": "asset-types", "label": "Asset types", "actions": ["read","write","delete"]},
    {"key": "assets", "label": "Assets", "actions": ["read","write","delete","publish"]}
  ],
  "rpc_methods": {
    "admin_list_types": "asset-types:read",
    "admin_upsert_type": "asset-types:write",
    "admin_stats": "read"
  }
}

rpc_methods values are plugin-relative: "read"/"write"/"execute" name the base resource, "<key>:<action>" a declared sub-resource, and a value with the "plugin:" prefix or a platform resource ("plugins:execute") is used as is. Methods not listed need the base write.

func (*ManifestRBAC) Validate

func (r *ManifestRBAC) Validate() error

Validate checks the block's shape: kebab-case keys, unique within the plugin, labels present, actions known, read offered first.

type ManifestResourceType

type ManifestResourceType struct {
	Slug                string `json:"slug" binding:"required"`
	Name                string `json:"name" binding:"required"`
	Description         string `json:"description"`
	Icon                string `json:"icon"`
	HasPrivacyScore     bool   `json:"has_privacy_score"`
	SupportsSubmissions bool   `json:"supports_submissions"`
	SupportsMetadata    bool   `json:"supports_metadata"` // Instances can carry governed metadata (Enterprise)
	// AccessGrantedViaApp declares that an App credential grants access to
	// instances. Omitted (nil) means the platform default: true when the
	// plugin also declares the custom_endpoint hook, false otherwise.
	AccessGrantedViaApp *bool `json:"access_granted_via_app,omitempty"`
	// PortalDetailPath is a same-origin path template ("{id}" is replaced)
	// to an instance's page in the portal.
	PortalDetailPath string `json:"portal_detail_path,omitempty"`
	// DefaultAccess is "auto" (default: active instances join the Default
	// team) or "explicit" (only granted teams; Enterprise builds only).
	DefaultAccess string `json:"default_access,omitempty"`
	FormComponent *struct {
		Tag        string `json:"tag"`
		EntryPoint string `json:"entry_point"`
	} `json:"form_component,omitempty"`
	// SubmissionSchema is an optional JSON Schema (object) describing the
	// payload of community submissions for this type. It may be given inline
	// as an object or as a JSON-encoded string.
	SubmissionSchema json.RawMessage `json:"submission_schema,omitempty"`
}

ManifestResourceType declares a resource type in the plugin manifest

func (ManifestResourceType) ParseSubmissionSchema

func (m ManifestResourceType) ParseSubmissionSchema() (string, error)

ParseSubmissionSchema returns the submission schema as a JSON string ("" when absent) or an error describing why the manifest value is unusable: a string literal that is not valid JSON, or a value that is not a JSON object.

func (ManifestResourceType) SubmissionSchemaString

func (m ManifestResourceType) SubmissionSchemaString() string

SubmissionSchemaString returns the submission schema as a JSON string, unwrapping it when the manifest encoded it as a string literal. Malformed values are rejected by ValidateManifest (see ParseSubmissionSchema), so a loaded manifest never reaches this with a value that cannot be unwrapped.

type ManifestSchema

type ManifestSchema struct {
	Slug        string             `json:"slug"`
	Name        string             `json:"name"`
	Description string             `json:"description,omitempty"`
	AppliesTo   []string           `json:"applies_to"`
	Fields      []MetadataFieldDef `json:"fields"`
}

ManifestSchema declares a governed metadata schema in the plugin manifest.

type ManifestVocabulary

type ManifestVocabulary struct {
	Slug        string           `json:"slug"`
	Name        string           `json:"name"`
	Description string           `json:"description,omitempty"`
	Terms       []VocabularyTerm `json:"terms"`
}

ManifestVocabulary declares a controlled vocabulary in the plugin manifest.

type MarketplaceConfig

type MarketplaceConfig struct {
	gorm.Model
	ID          uint      `json:"id" gorm:"primaryKey"`
	Key         string    `json:"key" gorm:"uniqueIndex;not null;size:100"` // e.g. "sync_interval", "default_index_url"
	Value       string    `json:"value" gorm:"type:text"`
	Description string    `json:"description" gorm:"type:text"`
	IsEditable  bool      `json:"is_editable" gorm:"default:true"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

MarketplaceConfig holds marketplace configuration

func (MarketplaceConfig) TableName

func (MarketplaceConfig) TableName() string

TableName returns the table name for MarketplaceConfig

type MarketplaceIndex

type MarketplaceIndex struct {
	gorm.Model
	ID           uint      `json:"id" gorm:"primaryKey"`
	SourceURL    string    `json:"source_url" gorm:"uniqueIndex;not null;size:500"` // URL of index.yaml
	APIVersion   string    `json:"api_version" gorm:"size:50"`
	LastSynced   time.Time `json:"last_synced"`
	LastModified time.Time `json:"last_modified"`        // From HTTP Last-Modified header
	ETag         string    `json:"etag" gorm:"size:255"` // From HTTP ETag header
	PluginCount  int       `json:"plugin_count"`
	SyncStatus   string    `json:"sync_status" gorm:"size:50"` // success, error, in_progress
	SyncError    string    `json:"sync_error" gorm:"type:text"`
	IsDefault    bool      `json:"is_default" gorm:"default:false"` // Is this the default Tyk marketplace
	IsActive     bool      `json:"is_active" gorm:"default:true;index:idx_marketplace_index_active"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

MarketplaceIndex represents the cached marketplace index metadata

func GetAllActiveMarketplaceIndexes

func GetAllActiveMarketplaceIndexes(db *gorm.DB) ([]*MarketplaceIndex, error)

GetAllActiveIndexes retrieves all active marketplace indexes

func GetDefaultMarketplaceIndex

func GetDefaultMarketplaceIndex(db *gorm.DB) (*MarketplaceIndex, error)

GetMarketplaceIndex retrieves the active default marketplace index

func (MarketplaceIndex) TableName

func (MarketplaceIndex) TableName() string

TableName returns the table name for MarketplaceIndex

type MarketplacePlugin

type MarketplacePlugin struct {
	gorm.Model
	ID          uint     `json:"id" gorm:"primaryKey"`
	PluginID    string   `json:"plugin_id" gorm:"uniqueIndex:idx_marketplace_plugin_version_source;not null;size:255"` // e.g. "com.tyk.echo-agent"
	Version     string   `json:"version" gorm:"uniqueIndex:idx_marketplace_plugin_version_source;not null;size:100"`
	Name        string   `json:"name" gorm:"not null;size:255"`
	Description string   `json:"description" gorm:"type:text"`
	Category    string   `json:"category" gorm:"size:100;index:idx_marketplace_category"`
	Keywords    []string `json:"keywords" gorm:"serializer:json"`
	Maturity    string   `json:"maturity" gorm:"size:50"` // alpha, beta, stable
	Publisher   string   `json:"publisher" gorm:"size:100;index:idx_marketplace_publisher"`
	License     string   `json:"license" gorm:"size:100"`

	// OCI Distribution
	OCIRegistry   string   `json:"oci_registry" gorm:"size:255"`
	OCIRepository string   `json:"oci_repository" gorm:"size:500"`
	OCITag        string   `json:"oci_tag" gorm:"size:100"`
	OCIDigest     string   `json:"oci_digest" gorm:"size:255;index:idx_marketplace_digest"`
	OCIPlatforms  []string `json:"oci_platforms" gorm:"serializer:json"`

	// Links
	IconURL          string   `json:"icon_url" gorm:"size:500"`
	DocumentationURL string   `json:"documentation_url" gorm:"size:500"`
	RepositoryURL    string   `json:"repository_url" gorm:"size:500"`
	SupportURL       string   `json:"support_url" gorm:"size:500"`
	HomepageURL      string   `json:"homepage_url" gorm:"size:500"`
	IssuesURL        string   `json:"issues_url" gorm:"size:500"`
	Screenshots      []string `json:"screenshots" gorm:"serializer:json"`

	// Capabilities
	PrimaryHook string   `json:"primary_hook" gorm:"size:50"`
	Hooks       []string `json:"hooks" gorm:"serializer:json"`

	// Requirements
	MinStudioVersion string   `json:"min_studio_version" gorm:"size:50"`
	APIVersions      []string `json:"api_versions" gorm:"serializer:json"`
	Dependencies     []string `json:"dependencies" gorm:"serializer:json"`

	// Permissions
	RequiredServices []string `json:"required_services" gorm:"serializer:json"`
	RequiredKV       []string `json:"required_kv" gorm:"serializer:json"`
	RequiredRPC      []string `json:"required_rpc" gorm:"serializer:json"`
	RequiredUI       []string `json:"required_ui" gorm:"serializer:json"`

	// Config Schema
	ConfigSchemaURL string `json:"config_schema_url" gorm:"size:500"`

	// Verification
	AttestationEnabled bool   `json:"attestation_enabled" gorm:"default:false"`
	AttestationURL     string `json:"attestation_url" gorm:"size:500"`

	// Maintainers (JSON array)
	Maintainers string `json:"maintainers" gorm:"type:text"` // JSON array of {name, email, organization}

	// Metadata
	PluginCreatedAt   time.Time `json:"plugin_created_at"`
	PluginUpdatedAt   time.Time `json:"plugin_updated_at"`
	Deprecated        bool      `json:"deprecated" gorm:"default:false;index:idx_marketplace_deprecated"`
	DeprecatedMessage string    `json:"deprecated_message" gorm:"type:text"`
	ReplacementPlugin string    `json:"replacement_plugin" gorm:"size:255"`

	// Enterprise
	EnterpriseOnly bool `json:"enterprise_only" gorm:"default:false;index:idx_marketplace_enterprise"`

	// Cache info
	LastSynced    time.Time `json:"last_synced"`
	SyncedFromURL string    `json:"synced_from_url" gorm:"uniqueIndex:idx_marketplace_plugin_version_source;size:500"`

	// Full manifest data (for reference)
	ManifestData string `json:"manifest_data" gorm:"type:text"` // Full YAML/JSON manifest
	ManifestURL  string `json:"manifest_url" gorm:"size:500"`   // URL of this version's manifest.yaml; its directory also holds CHANGELOG.md

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

MarketplacePlugin represents a cached plugin entry from the marketplace index

func GetAllPluginVersions

func GetAllPluginVersions(db *gorm.DB, pluginID string) ([]*MarketplacePlugin, error)

GetAllVersions returns all versions of a specific plugin from marketplace, sorted by semver descending

func ListMarketplacePlugins

func ListMarketplacePlugins(db *gorm.DB, pageSize, pageNumber int, category, publisher, maturity, search string, includeDeprecated bool) ([]*MarketplacePlugin, int64, int, error)

ListMarketplacePlugins returns paginated marketplace plugins with filtering. Only the highest semver version of each plugin_id is returned.

func (*MarketplacePlugin) GetByPluginIDAndVersion

func (mp *MarketplacePlugin) GetByPluginIDAndVersion(db *gorm.DB, pluginID, version string) error

GetMarketplacePlugin retrieves a marketplace plugin by plugin_id and version

func (*MarketplacePlugin) GetLatestVersion

func (mp *MarketplacePlugin) GetLatestVersion(db *gorm.DB, pluginID string) error

GetLatestVersion retrieves the latest version of a marketplace plugin by semver

func (*MarketplacePlugin) OCIReference

func (mp *MarketplacePlugin) OCIReference() string

OCIReference returns the oci:// command for this marketplace version. It is pinned to the digest when the index records one and falls back to the tag, so what gets installed is the artifact the marketplace entry describes.

func (MarketplacePlugin) TableName

func (MarketplacePlugin) TableName() string

TableName returns the table name for MarketplacePlugin

type MetadataFieldDef

type MetadataFieldDef struct {
	Key         string `json:"key"`
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
	Type        string `json:"type"`

	Required bool   `json:"required"`
	Severity string `json:"severity,omitempty"` // error (default) | warning
	// RequiredOnPublish makes the field mandatory only when the object goes
	// live (activate / enable): a submitter can save a draft without it, but
	// the publish is refused until it is filled. Independent of Required.
	RequiredOnPublish bool `json:"required_on_publish,omitempty"`

	VocabularySlug string   `json:"vocabulary_slug,omitempty"`
	Pattern        string   `json:"pattern,omitempty"`
	Min            *float64 `json:"min,omitempty"`
	Max            *float64 `json:"max,omitempty"`
	MaxLength      int      `json:"max_length,omitempty"`

	WarnIfPast     bool `json:"warn_if_past,omitempty"` // date fields: warn when the value is in the past
	PortalVisible  bool `json:"portal_visible"`
	GatewayVisible bool `json:"gateway_visible"`
	Order          int  `json:"order"`
}

MetadataFieldDef is one field in a MetadataSchema.

type MetadataSchema

type MetadataSchema struct {
	gorm.Model
	ID          uint   `json:"id" gorm:"primaryKey"`
	Name        string `json:"name" gorm:"size:255"`
	Slug        string `json:"slug" gorm:"size:100;uniqueIndex:idx_metadata_schema_slug"`
	Description string `json:"description"`

	AppliesTo []string           `json:"applies_to" gorm:"serializer:json"`
	Fields    []MetadataFieldDef `json:"fields" gorm:"serializer:json"`

	Enforcement string `json:"enforcement" gorm:"size:20;default:'advisory'"`
	Active      bool   `json:"active"`
	Source      string `json:"source" gorm:"size:50;default:'admin'"`
	Order       int    `json:"order" gorm:"default:0"`
	Version     int    `json:"version" gorm:"default:1"`
}

MetadataSchema is an admin- or plugin-defined set of governed metadata fields that applies to one or more object types.

func (*MetadataSchema) AppliesToType

func (s *MetadataSchema) AppliesToType(objectType string) bool

AppliesToType reports whether the schema applies to the given object type.

func (*MetadataSchema) Create

func (s *MetadataSchema) Create(db *gorm.DB) error

func (*MetadataSchema) Delete

func (s *MetadataSchema) Delete(db *gorm.DB) error

func (*MetadataSchema) Get

func (s *MetadataSchema) Get(db *gorm.DB, id uint) error

func (*MetadataSchema) GetBySlug

func (s *MetadataSchema) GetBySlug(db *gorm.DB, slug string) error

func (*MetadataSchema) IsPluginSourced

func (s *MetadataSchema) IsPluginSourced() bool

IsPluginSourced reports whether the schema was contributed by a plugin manifest.

func (MetadataSchema) TableName

func (MetadataSchema) TableName() string

func (*MetadataSchema) Update

func (s *MetadataSchema) Update(db *gorm.DB) error

type MetadataSchemas

type MetadataSchemas []MetadataSchema

func (*MetadataSchemas) GetAll

func (ss *MetadataSchemas) GetAll(db *gorm.DB, activeOnly bool) error

GetAll returns all schemas ordered for deterministic resolution.

type MetadataVocabularies

type MetadataVocabularies []MetadataVocabulary

func (*MetadataVocabularies) GetAll

func (vs *MetadataVocabularies) GetAll(db *gorm.DB) error

type MetadataVocabulary

type MetadataVocabulary struct {
	gorm.Model
	ID          uint             `json:"id" gorm:"primaryKey"`
	Name        string           `json:"name" gorm:"size:255"`
	Slug        string           `json:"slug" gorm:"size:100;uniqueIndex:idx_metadata_vocab_slug"`
	Description string           `json:"description"`
	Terms       []VocabularyTerm `json:"terms" gorm:"serializer:json"`
	Source      string           `json:"source" gorm:"size:50;default:'admin'"`
}

MetadataVocabulary is a shared controlled vocabulary referenced by vocabulary / multi_vocabulary fields.

func (*MetadataVocabulary) Create

func (v *MetadataVocabulary) Create(db *gorm.DB) error

func (*MetadataVocabulary) Delete

func (v *MetadataVocabulary) Delete(db *gorm.DB) error

func (*MetadataVocabulary) Get

func (v *MetadataVocabulary) Get(db *gorm.DB, id uint) error

func (*MetadataVocabulary) GetBySlug

func (v *MetadataVocabulary) GetBySlug(db *gorm.DB, slug string) error

func (*MetadataVocabulary) HasTerm

func (v *MetadataVocabulary) HasTerm(value string) (bool, bool)

HasTerm reports whether the vocabulary contains the value; the second result is whether that term is deprecated.

func (MetadataVocabulary) TableName

func (MetadataVocabulary) TableName() string

func (*MetadataVocabulary) TermLabel

func (v *MetadataVocabulary) TermLabel(value string) string

TermLabel returns the label for a value (or the value itself when unknown).

func (*MetadataVocabulary) Update

func (v *MetadataVocabulary) Update(db *gorm.DB) error

type ModelMapping

type ModelMapping struct {
	gorm.Model
	ID          uint   `json:"id" gorm:"primaryKey"`
	VendorID    uint   `json:"vendor_id" gorm:"not null;index:idx_mapping_vendor"`
	SourceModel string `json:"source_model" gorm:"not null"` // Model name from request
	TargetModel string `json:"target_model" gorm:"not null"` // Model name to send to this vendor
}

ModelMapping allows renaming models for a specific vendor e.g., map "gpt-4" to "claude-3-opus" when routing to Anthropic vendor

func NewModelMapping

func NewModelMapping() *ModelMapping

NewModelMapping creates a new ModelMapping instance

func (*ModelMapping) Get

func (m *ModelMapping) Get(db *gorm.DB, id uint) error

Get retrieves a ModelMapping by ID

func (*ModelMapping) GetMappingForModel

func (m *ModelMapping) GetMappingForModel(db *gorm.DB, vendorID uint, sourceModel string) error

GetMappingForModel finds a mapping for a specific source model for a vendor

type ModelMappings

type ModelMappings []ModelMapping

func (*ModelMappings) GetByVendorID

func (m *ModelMappings) GetByVendorID(db *gorm.DB, vendorID uint) error

GetByVendorID retrieves all mappings for a vendor

type ModelPool

type ModelPool struct {
	gorm.Model
	ID                 uint               `json:"id" gorm:"primaryKey"`
	RouterID           uint               `json:"router_id" gorm:"not null;index:idx_pool_router"`
	Name               string             `json:"name" gorm:"not null"`
	ModelPattern       string             `json:"model_pattern" gorm:"not null"` // Glob pattern, e.g., "claude-*"
	SelectionAlgorithm SelectionAlgorithm `json:"selection_algorithm" gorm:"default:'round_robin'"`
	Priority           int                `json:"priority" gorm:"default:0"` // Higher priority pools are checked first
	Vendors            []*PoolVendor      `json:"vendors" gorm:"foreignKey:PoolID;constraint:OnDelete:CASCADE"`
}

ModelPool groups vendors that handle specific model patterns Uses glob patterns (e.g., "claude-*", "gpt-4*") to match incoming model names

func NewModelPool

func NewModelPool() *ModelPool

NewModelPool creates a new ModelPool instance

func (*ModelPool) Delete

func (p *ModelPool) Delete(db *gorm.DB) error

Delete removes a ModelPool and cascades to vendors and mappings Note: GORM soft delete does not trigger DB-level CASCADE constraints, so we must manually delete children

func (*ModelPool) Get

func (p *ModelPool) Get(db *gorm.DB, id uint) error

Get retrieves a ModelPool by ID with relationships

type ModelPools

type ModelPools []ModelPool

func (*ModelPools) GetByRouterID

func (p *ModelPools) GetByRouterID(db *gorm.DB, routerID uint) error

GetByRouterID retrieves all pools for a router, ordered by priority

type ModelPrice

type ModelPrice struct {
	gorm.Model

	ID        uint   `gorm:"primaryKey"`
	ModelName string `gorm:"uniqueIndex:idx_model_vendor" json:"model_name"`
	Vendor    string `gorm:"uniqueIndex:idx_model_vendor" json:"vendor"`
	// All four prices are PER TOKEN, not per million tokens.
	//
	// The admin form collects per-million figures and divides by 1e6 before
	// posting, and the UI's own column header says "per million" -- so an API
	// client posting the number straight off a vendor's pricing page stores
	// every figure 1,000,000x too high, silently, and every cost, budget and
	// budget alert downstream is wrong. See MaxPlausiblePerTokenPrice.
	//
	// Note the directions, which the names do not make obvious: CPT is charged
	// against *output* (completion) tokens and CPIT against *input* (prompt)
	// tokens. See proxy/bedrock_translator.go and proxy/analyze_utils.go.
	CPT          float64 `json:"cpt"`            // Price per OUTPUT (completion) token
	CPIT         float64 `json:"cpit"`           // Price per INPUT (prompt) token
	CacheWritePT float64 `json:"cache_write_pt"` // Price per token for cache writes
	CacheReadPT  float64 `json:"cache_read_pt"`  // Price per token for cache reads
	Currency     string  `json:"currency"`
}

func (*ModelPrice) Create

func (mp *ModelPrice) Create(db *gorm.DB) error

Create a new ModelPrice

func (*ModelPrice) Delete

func (mp *ModelPrice) Delete(db *gorm.DB) error

Delete a ModelPrice

func (*ModelPrice) Get

func (mp *ModelPrice) Get(db *gorm.DB, id uint) error

Get a ModelPrice by ID

func (*ModelPrice) GetByModelName

func (mp *ModelPrice) GetByModelName(db *gorm.DB, modelName string) error

GetByModelName retrieves a ModelPrice by its model name

func (*ModelPrice) GetByModelNameAndVendor

func (mp *ModelPrice) GetByModelNameAndVendor(db *gorm.DB, modelName string, vendor string) error

GetByModelNameAndVendor retrieves a ModelPrice by its model name and vendor

func (*ModelPrice) GetOrCreateByModelName

func (mp *ModelPrice) GetOrCreateByModelName(db *gorm.DB, modelName string) error

GetOrCreateByModelName retrieves a ModelPrice by its model name, or creates it if not found

func (*ModelPrice) Update

func (mp *ModelPrice) Update(db *gorm.DB) error

Update an existing ModelPrice

type ModelPrices

type ModelPrices []ModelPrice

func (*ModelPrices) CreateMultiple

func (mps *ModelPrices) CreateMultiple(db *gorm.DB) error

CreateMultiple creates multiple ModelPrices at once

func (*ModelPrices) DeleteMultiple

func (mps *ModelPrices) DeleteMultiple(db *gorm.DB) error

DeleteMultiple deletes multiple ModelPrices at once

func (*ModelPrices) GetAll

func (mps *ModelPrices) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

GetAll retrieves all ModelPrices

func (*ModelPrices) GetByVendor

func (mps *ModelPrices) GetByVendor(db *gorm.DB, vendor string) error

GetByVendor retrieves all ModelPrices for a specific vendor

func (*ModelPrices) UpdateMultiple

func (mps *ModelPrices) UpdateMultiple(db *gorm.DB) error

UpdateMultiple updates multiple ModelPrices at once

type ModelRouter

type ModelRouter struct {
	gorm.Model
	ID          uint         `json:"id" gorm:"primaryKey"`
	Name        string       `json:"name" gorm:"not null"`
	Slug        string       `json:"slug" gorm:"uniqueIndex:idx_router_slug_namespace;not null"`
	Description string       `json:"description"`
	APICompat   string       `json:"api_compat" gorm:"default:'openai'"` // Currently only 'openai' supported
	Active      bool         `json:"active" gorm:"default:false"`
	Namespace   string       `json:"namespace" gorm:"default:'';uniqueIndex:idx_router_slug_namespace;index:idx_router_namespace"`
	Pools       []*ModelPool `json:"pools" gorm:"foreignKey:RouterID;constraint:OnDelete:CASCADE"`

	// Portal presentation. A router is published like an LLM: it sits in LLM
	// catalogues, teams are granted the catalogues, and Apps are granted the
	// router, which lets them reach every LLM its pools can pick, through it.
	ShortDescription string `json:"short_description"`
	LongDescription  string `json:"long_description"`
	LogoURL          string `json:"logo_url"`

	Catalogues []Catalogue `json:"-" gorm:"many2many:catalogue_model_routers;"`
}

ModelRouter is the top-level entity that defines a routing endpoint Routes are exposed at /router/{slug}/* and route requests to LLM vendors based on model name pattern matching

func NewModelRouter

func NewModelRouter() *ModelRouter

NewModelRouter creates a new ModelRouter instance

func (*ModelRouter) AdvertisedModels

func (r *ModelRouter) AdvertisedModels() []string

AdvertisedModels lists the model names a client can ask this router for by name: the literal (glob-free) entries of its pool patterns and the source models of its vendor mappings. Pools must be loaded. The gateway serves a router's models as "{slug}/{model}".

func (*ModelRouter) Create

func (r *ModelRouter) Create(db *gorm.DB) error

Create creates a new ModelRouter with all nested relationships

func (*ModelRouter) Delete

func (r *ModelRouter) Delete(db *gorm.DB) error

Delete removes a ModelRouter for good, with its pools, vendors, mappings, App grants and catalogue memberships. It is a hard delete: a soft-deleted row keeps its slug in the (slug, namespace) unique index, so a new router could never take the slug again. The system event and audit log carry the history.

func (*ModelRouter) Get

func (r *ModelRouter) Get(db *gorm.DB, id uint) error

Get retrieves a ModelRouter by ID with all relationships

func (*ModelRouter) GetBySlug

func (r *ModelRouter) GetBySlug(db *gorm.DB, slug string, namespace string) error

GetBySlug retrieves a ModelRouter by slug within a namespace

func (*ModelRouter) Update

func (r *ModelRouter) Update(db *gorm.DB) error

Update updates a ModelRouter and its relationships

type ModelRouters

type ModelRouters []ModelRouter

func (*ModelRouters) GetActiveRouters

func (r *ModelRouters) GetActiveRouters(db *gorm.DB) error

GetActiveRouters retrieves all active ModelRouters

func (*ModelRouters) GetActiveRoutersByNamespace

func (r *ModelRouters) GetActiveRoutersByNamespace(db *gorm.DB, namespace string) error

GetActiveRoutersByNamespace retrieves all active ModelRouters for a namespace

func (*ModelRouters) GetAll

func (r *ModelRouters) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

GetAll retrieves all ModelRouters with pagination

func (*ModelRouters) GetByNamespace

func (r *ModelRouters) GetByNamespace(db *gorm.DB, namespace string) error

GetByNamespace retrieves all ModelRouters for a specific namespace

type MultiAxisChartData

type MultiAxisChartData struct {
	Labels   []string  `json:"labels"`
	Datasets []Dataset `json:"datasets"`
}

MultiAxisChartData represents data for a chart with multiple y-axes

type NamespaceSyncStatus

type NamespaceSyncStatus struct {
	gorm.Model
	Namespace        string    `gorm:"uniqueIndex;not null" json:"namespace"`
	ExpectedChecksum string    `gorm:"size:64;not null" json:"expected_checksum"`
	ConfigVersion    string    `gorm:"size:64;not null" json:"config_version"`
	LastConfigChange time.Time `gorm:"not null" json:"last_config_change"`
	// LastPushAt is when an administrator last issued a configuration push
	// (edge, namespace or global reload) for this namespace; nil until the
	// first push. The pending-changes preview lists what changed since it.
	LastPushAt *time.Time `json:"last_push_at"`
}

NamespaceSyncStatus tracks the expected configuration checksum for each namespace

func (*NamespaceSyncStatus) Delete

func (n *NamespaceSyncStatus) Delete(db *gorm.DB) error

Delete removes the sync status for a namespace

func (*NamespaceSyncStatus) GetAll

func (n *NamespaceSyncStatus) GetAll(db *gorm.DB) ([]NamespaceSyncStatus, error)

GetAll retrieves all namespace sync statuses

func (*NamespaceSyncStatus) GetByNamespace

func (n *NamespaceSyncStatus) GetByNamespace(db *gorm.DB, namespace string) error

GetByNamespace retrieves sync status for a namespace under any of its spellings, preferring the canonical row. The fallback keeps databases restored from before canonicalisation working until MergeLegacyNamespaceSyncStatus has run.

func (NamespaceSyncStatus) TableName

func (NamespaceSyncStatus) TableName() string

TableName specifies the table name for the NamespaceSyncStatus model

func (*NamespaceSyncStatus) Upsert

func (n *NamespaceSyncStatus) Upsert(db *gorm.DB) error

Upsert updates or creates the sync status for a namespace. The namespace is canonicalised; a legacy row under another spelling is updated in place rather than shadowed by a second row.

type Notification

type Notification struct {
	ID             uint           `json:"id" gorm:"primaryKey"`
	CreatedAt      time.Time      `json:"created_at"`
	UpdatedAt      time.Time      `json:"updated_at"`
	DeletedAt      gorm.DeletedAt `json:"-" gorm:"index"`
	NotificationID string         `json:"notification_id" gorm:"uniqueIndex"` // Unique ID to prevent duplicates
	Type           string         `json:"type"`                               // e.g. "budget_alert", "system_update", etc.
	Title          string         `json:"title"`
	Content        string         `json:"content"`
	// The inbox is always read per user, newest first: one composite index
	// serves the page query, the unread badge and the counts.
	UserID uint      `json:"user_id" gorm:"index:idx_notifications_user_sent,priority:1"`
	Read   bool      `json:"read"`                                                        // For UI display
	SentAt time.Time `json:"sent_at" gorm:"index:idx_notifications_user_sent,priority:2"` // When the notification was sent
	// Link is the in-app path the notification points at, e.g.
	// "/admin/apps/3"; empty when there is nothing to open.
	Link string `json:"link"`
}

Notification is one in-app notification for one recipient. The JSON names are what the bell panel consumes; the same columns as gorm.Model are spelled out so they serialise in lowercase too.

func (Notification) TableName

func (Notification) TableName() string

TableName specifies the table name for the Notification model

type OAuthClient

type OAuthClient struct {
	gorm.Model
	ClientID     string `gorm:"type:varchar(255);uniqueIndex;not null"`
	ClientSecret string `gorm:"type:varchar(255);not null"` // Store hashed
	ClientName   string `gorm:"type:varchar(255);not null"`
	RedirectURIs string `gorm:"type:text;not null"` // Comma-separated or JSON array
	UserID       *uint  `gorm:"index"`              // Foreign key to users table, nullable for system clients
	User         User   // GORM association
	Scope        string `gorm:"type:varchar(255)"` // Space-separated scopes
}

OAuthClient represents an OAuth 2.0 client application.

type ObjectMetadata

type ObjectMetadata struct {
	gorm.Model
	ID         uint   `json:"id" gorm:"primaryKey"`
	ObjectType string `json:"object_type" gorm:"size:200;index:idx_objmeta_type;uniqueIndex:idx_objmeta_type_id"`
	ObjectID   string `json:"object_id" gorm:"size:200;uniqueIndex:idx_objmeta_type_id"`

	Values JSONMap `json:"values" gorm:"type:json"`

	ValidationStatus string     `json:"validation_status" gorm:"size:20;default:'unvalidated'"`
	ValidationResult JSONMap    `json:"validation_result" gorm:"type:json"`
	LastValidatedAt  *time.Time `json:"last_validated_at"`

	UpdatedByUserID uint   `json:"updated_by_user_id"`
	UpdatedBySource string `json:"updated_by_source" gorm:"size:50"`
}

ObjectMetadata holds the governed metadata values for one object.

func (*ObjectMetadata) GetByObject

func (o *ObjectMetadata) GetByObject(db *gorm.DB, objectType, objectID string) error

func (ObjectMetadata) TableName

func (ObjectMetadata) TableName() string

type ObjectMetadataAudit

type ObjectMetadataAudit struct {
	gorm.Model
	ID           uint     `json:"id" gorm:"primaryKey"`
	ObjectType   string   `json:"object_type" gorm:"size:200;index:idx_objmeta_audit_obj"`
	ObjectID     string   `json:"object_id" gorm:"size:200;index:idx_objmeta_audit_obj"`
	Action       string   `json:"action" gorm:"size:20"` // set | merge | delete
	UserID       uint     `json:"user_id"`
	Source       string   `json:"source" gorm:"size:50"`
	Before       JSONMap  `json:"before" gorm:"type:json"`
	After        JSONMap  `json:"after" gorm:"type:json"`
	HookExecuted []string `json:"hooks_executed" gorm:"serializer:json"`
}

ObjectMetadataAudit records every change to an object's governed metadata.

func (ObjectMetadataAudit) TableName

func (ObjectMetadataAudit) TableName() string

type PaginatedProxyLogs

type PaginatedProxyLogs struct {
	Data []ProxyLogResponse `json:"data"`
	Meta struct {
		TotalCount int64 `json:"total_count"`
		TotalPages int   `json:"total_pages"`
		PageSize   int   `json:"page_size"`
		PageNumber int   `json:"page_number"`
	} `json:"meta"`
}

PaginatedProxyLogs represents a paginated list of proxy logs

type PendingOAuthRequest

type PendingOAuthRequest struct {
	gorm.Model
	ID                  string    `gorm:"type:varchar(255);uniqueIndex;not null"` // The auth_req_id (e.g., UUID)
	ClientID            string    `gorm:"type:varchar(255);not null"`
	UserID              uint      `gorm:"not null"` // The user who needs to consent
	RedirectURI         string    `gorm:"type:text;not null"`
	Scope               string    `gorm:"type:varchar(255)"`
	State               string    `gorm:"type:varchar(255)"` // Optional
	CodeChallenge       string    `gorm:"type:varchar(255);not null"`
	CodeChallengeMethod string    `gorm:"type:varchar(50);not null"`
	ExpiresAt           time.Time `gorm:"not null"` // When this pending request becomes invalid
}

PendingOAuthRequest stores the details of an OAuth authorization request that is awaiting user consent.

type Plugin

type Plugin struct {
	gorm.Model
	ID                  uint                   `json:"id" gorm:"primaryKey"`
	Name                string                 `json:"name" gorm:"not null"`
	Description         string                 `json:"description"`
	Command             string                 `json:"command" gorm:"not null;size:500"`
	Checksum            string                 `json:"checksum" gorm:"size:255"` // Optional - for future use
	Config              map[string]interface{} `json:"config" gorm:"serializer:json"`
	HookType            string                 `json:"hook_type" gorm:"not null;size:50;index:idx_plugins_hook_type"`
	HookTypes           []string               `json:"hook_types" gorm:"serializer:json"`          // All hook types this plugin supports
	HookTypesCustomized bool                   `json:"hook_types_customized" gorm:"default:false"` // True if user overrode manifest hooks
	IsActive            bool                   `json:"is_active" gorm:"index:idx_plugins_is_active"`
	CreatedAt           time.Time              `json:"created_at"`
	UpdatedAt           time.Time              `json:"updated_at"`
	DeletedAt           gorm.DeletedAt         `json:"deleted_at,omitempty" gorm:"index"`

	// Hub-and-Spoke Configuration
	Namespace string `json:"namespace" gorm:"default:'';index:idx_plugin_namespace"`

	// OCI Support
	OCIReference string                 `json:"oci_reference" gorm:"size:500"`   // OCI artifact reference (for OCI plugins)
	Manifest     map[string]interface{} `json:"manifest" gorm:"serializer:json"` // Plugin manifest for UI extensions

	// Service Access Control (for AI Studio plugins)
	ServiceAccessAuthorized bool     `json:"service_access_authorized" gorm:"default:false;index:idx_plugins_service_access"` // Admin authorization for service access
	ServiceScopes           []string `json:"service_scopes" gorm:"serializer:json"`                                           // Authorized service scopes from manifest

	// Relationships
	LLMs []LLM `json:"llms,omitempty" gorm:"many2many:llm_plugins;"`
}

Plugin represents a plugin configuration in the hub-and-spoke system

func NewPlugin

func NewPlugin() *Plugin

NewPlugin creates a new Plugin instance

func (*Plugin) AuthorizeServiceAccess

func (p *Plugin) AuthorizeServiceAccess(db *gorm.DB, scopes []string) error

AuthorizeServiceAccess grants service access to the plugin with specified scopes

func (*Plugin) CountActivePlugins

func (p *Plugin) CountActivePlugins(db *gorm.DB) (int64, error)

CountActivePlugins returns the count of active plugins

func (*Plugin) CountPlugins

func (p *Plugin) CountPlugins(db *gorm.DB) (int64, error)

CountPlugins returns the total number of plugins

func (*Plugin) CountPluginsByHookType

func (p *Plugin) CountPluginsByHookType(db *gorm.DB, hookType string) (int64, error)

CountPluginsByHookType returns the count of plugins by hook type

func (*Plugin) Create

func (p *Plugin) Create(db *gorm.DB) error

Create creates a new plugin

func (*Plugin) Delete

func (p *Plugin) Delete(db *gorm.DB) error

Delete soft deletes a plugin

func (*Plugin) Get

func (p *Plugin) Get(db *gorm.DB, id uint) error

Get retrieves a plugin by ID

func (*Plugin) GetAllHookTypes

func (p *Plugin) GetAllHookTypes() []string

GetAllHookTypes returns all hook types (primary + additional)

func (*Plugin) GetCapabilityCategory

func (p *Plugin) GetCapabilityCategory() string

GetCapabilityCategory returns a human-readable category string

func (*Plugin) HasAdminSurface

func (p *Plugin) HasAdminSurface() bool

HasAdminSurface reports whether the plugin is something an administrator uses directly (pages, portal pages, resource types) and therefore gets a per-plugin permission resource. Pure request-path plugins (auth, rate limiting) are governed by the platform-level plugins resource alone.

func (*Plugin) HasServiceAccess

func (p *Plugin) HasServiceAccess() bool

HasServiceAccess returns true if the plugin is authorized for service access

func (*Plugin) HasServiceScope

func (p *Plugin) HasServiceScope(scope string) bool

HasServiceScope returns true if the plugin has the specified service scope

func (*Plugin) IsGRPCPlugin

func (p *Plugin) IsGRPCPlugin() bool

IsGRPCPlugin returns true if this plugin connects to external gRPC

func (*Plugin) IsLocalPlugin

func (p *Plugin) IsLocalPlugin() bool

IsLocalPlugin returns true if this plugin is a local binary

func (*Plugin) IsOCIPlugin

func (p *Plugin) IsOCIPlugin() bool

IsOCIPlugin returns true if this plugin uses OCI (determined by command prefix)

func (*Plugin) IsValidHookType

func (p *Plugin) IsValidHookType() bool

IsValidHookType validates if the hook type is supported

func (*Plugin) ManifestRBAC

func (p *Plugin) ManifestRBAC() *ManifestRBAC

ManifestRBAC decodes the "rbac" block of the stored manifest, or nil when the manifest is unknown or declares none.

func (*Plugin) PermissionKey

func (p *Plugin) PermissionKey() string

PermissionKey is the RBAC resource key that stands for this plugin: "plugin:<manifest id>" (e.g. "plugin:com.tyk.enterprise.asset-catalog") so it survives an uninstall and reinstall, falling back to "plugin:id-<database id>" for a plugin whose manifest is not known yet. Plugin-declared sub-resources are "<PermissionKey>:<sub-key>".

func (*Plugin) RPCMethodPermission

func (p *Plugin) RPCMethodPermission(method string) string

RPCMethodPermission returns the plugin-relative permission the manifest declares for an admin RPC method ("" when undeclared, meaning base write).

func (*Plugin) RevokeServiceAccess

func (p *Plugin) RevokeServiceAccess(db *gorm.DB) error

RevokeServiceAccess revokes service access from the plugin

func (*Plugin) SupportsHookType

func (p *Plugin) SupportsHookType(hookType string) bool

SupportsHookType checks if plugin supports a specific hook type

func (Plugin) TableName

func (Plugin) TableName() string

TableName returns the table name for the Plugin model

func (*Plugin) Update

func (p *Plugin) Update(db *gorm.DB) error

Update updates an existing plugin

func (*Plugin) UpdateServiceScopes

func (p *Plugin) UpdateServiceScopes(db *gorm.DB, scopes []string) error

UpdateServiceScopes updates the authorized service scopes for the plugin

func (*Plugin) ValidateHookTypes

func (p *Plugin) ValidateHookTypes() error

ValidateHookTypes validates all hook types are valid

type PluginCapabilities

type PluginCapabilities struct {
	Hooks       []string `json:"hooks" binding:"required,min=1"`
	PrimaryHook string   `json:"primary_hook,omitempty"`
}

PluginCapabilities declares plugin hook capabilities

type PluginConfigSchema

type PluginConfigSchema struct {
	gorm.Model
	ID          uint           `json:"id" gorm:"primaryKey"`
	Command     string         `json:"command" gorm:"uniqueIndex;not null;size:500"` // Plugin command as cache key
	SchemaJSON  string         `json:"schema_json" gorm:"type:text"`                 // JSON Schema as text
	LastFetched time.Time      `json:"last_fetched"`                                 // When schema was last fetched
	CreatedAt   time.Time      `json:"created_at"`
	UpdatedAt   time.Time      `json:"updated_at"`
	DeletedAt   gorm.DeletedAt `json:"deleted_at,omitempty" gorm:"index"`
}

PluginConfigSchema represents cached configuration schemas for plugins Cache is keyed by Command to allow sharing schemas between plugins with same command

func NewPluginConfigSchema

func NewPluginConfigSchema() *PluginConfigSchema

NewPluginConfigSchema creates a new PluginConfigSchema instance

func (*PluginConfigSchema) Create

func (pcs *PluginConfigSchema) Create(db *gorm.DB) error

Create creates a new plugin config schema

func (*PluginConfigSchema) Delete

func (pcs *PluginConfigSchema) Delete(db *gorm.DB) error

Delete soft deletes a plugin config schema

func (*PluginConfigSchema) GetByCommand

func (pcs *PluginConfigSchema) GetByCommand(db *gorm.DB, command string) error

Get retrieves a plugin config schema by command

func (*PluginConfigSchema) IsStale

func (pcs *PluginConfigSchema) IsStale(maxAge time.Duration) bool

IsStale checks if the cached schema is older than the specified duration

func (*PluginConfigSchema) Update

func (pcs *PluginConfigSchema) Update(db *gorm.DB) error

Update updates an existing plugin config schema

func (*PluginConfigSchema) Upsert

func (pcs *PluginConfigSchema) Upsert(db *gorm.DB, command string, schemaJSON string) error

Upsert creates or updates a plugin config schema by command Uses PostgreSQL's ON CONFLICT clause for atomic upsert (no race conditions)

type PluginConfigSchemas

type PluginConfigSchemas []PluginConfigSchema

PluginConfigSchemas is a collection of PluginConfigSchema

func (*PluginConfigSchemas) ListAll

func (schemas *PluginConfigSchemas) ListAll(db *gorm.DB) error

ListAll returns all plugin config schemas

func (*PluginConfigSchemas) ListByCommands

func (schemas *PluginConfigSchemas) ListByCommands(db *gorm.DB, commands []string) error

ListByCommands returns schemas for specific commands

type PluginData

type PluginData struct {
	ID         uint           `json:"id" gorm:"primaryKey"`
	PluginID   uint           `json:"plugin_id" gorm:"not null;index:idx_plugin_data_plugin_id;uniqueIndex:idx_plugin_data_composite"`
	PluginName string         `json:"plugin_name" gorm:"not null;size:255;index:idx_plugin_data_plugin_name"`
	DataKey    string         `json:"data_key" gorm:"not null;size:255;uniqueIndex:idx_plugin_data_composite"`
	DataValue  []byte         `json:"data_value" gorm:"type:bytea"`                               // Binary data support for any serialization format
	ExpireAt   *time.Time     `json:"expire_at,omitempty" gorm:"index:idx_plugin_data_expire_at"` // Optional expiration timestamp
	CreatedAt  time.Time      `json:"created_at"`
	UpdatedAt  time.Time      `json:"updated_at"`
	DeletedAt  gorm.DeletedAt `json:"deleted_at,omitempty" gorm:"index"`

	// Relationship - CASCADE delete ensures cleanup when plugin is deleted
	Plugin Plugin `json:"-" gorm:"foreignKey:PluginID;constraint:OnDelete:CASCADE"`
}

PluginData represents key-value data storage for AI Studio plugins Each plugin gets its own sandboxed namespace for storing configuration and state data that persists beyond the plugin's config field

func NewPluginData

func NewPluginData() *PluginData

NewPluginData creates a new PluginData instance

func (*PluginData) Create

func (pd *PluginData) Create(db *gorm.DB) error

Create creates a new plugin data entry

func (*PluginData) Delete

func (pd *PluginData) Delete(db *gorm.DB) error

Delete soft deletes a plugin data entry

func (*PluginData) Get

func (pd *PluginData) Get(db *gorm.DB, id uint) error

Get retrieves a plugin data entry by ID

func (*PluginData) GetByKey

func (pd *PluginData) GetByKey(db *gorm.DB, pluginID uint, key string) error

GetByKey retrieves a plugin data entry by plugin ID and key

func (*PluginData) IsExpired

func (pd *PluginData) IsExpired() bool

IsExpired checks if the plugin data entry has expired

func (PluginData) TableName

func (PluginData) TableName() string

TableName returns the table name for the PluginData model

func (*PluginData) Update

func (pd *PluginData) Update(db *gorm.DB) error

Update updates an existing plugin data entry

func (*PluginData) Upsert

func (pd *PluginData) Upsert(db *gorm.DB) (bool, error)

Upsert creates or updates a plugin data entry Returns true if created, false if updated

type PluginDataCollection

type PluginDataCollection []PluginData

PluginDataCollection represents a collection of plugin data entries

func (*PluginDataCollection) DeleteAllByPluginID

func (pdc *PluginDataCollection) DeleteAllByPluginID(db *gorm.DB, pluginID uint) error

DeleteAllByPluginID deletes all plugin data entries for a specific plugin

func (*PluginDataCollection) GetAllByPluginID

func (pdc *PluginDataCollection) GetAllByPluginID(db *gorm.DB, pluginID uint) error

GetAllByPluginID retrieves all plugin data entries for a specific plugin

type PluginManifest

type PluginManifest struct {
	// Basic plugin information
	ID          string `json:"id" binding:"required"`
	Version     string `json:"version" binding:"required"`
	Name        string `json:"name" binding:"required"`
	Description string `json:"description"`

	// Capabilities declares what hooks this plugin implements
	Capabilities *PluginCapabilities `json:"capabilities" binding:"required"`

	// Permissions and security
	Permissions struct {
		KV          []string `json:"kv"`           // KV access permissions: read, write, list
		RPC         []string `json:"rpc"`          // RPC permissions: call
		Routes      []string `json:"routes"`       // Route patterns this plugin can register
		UI          []string `json:"ui"`           // UI permissions: sidebar.register, route.register
		PortalUI    []string `json:"portal_ui"`    // Portal UI permissions: sidebar.register, route.register
		Services    []string `json:"services"`     // AI Studio service access scopes: analytics.read, plugins.config, etc.
		ObjectHooks []string `json:"object_hooks"` // Object hook permissions: llm.before_create, datasource.after_update, etc.
	} `json:"permissions"`

	// Key-value namespace for plugin data
	KVNamespace string `json:"kvNamespace"`

	// RPC configuration
	RPC *struct {
		BasePath   string `json:"basePath"`   // Base path for RPC endpoints
		Proto      string `json:"proto"`      // Path to proto file
		Entrypoint string `json:"entrypoint"` // gRPC service method name
	} `json:"rpc,omitempty"`

	// UI configuration (admin interface)
	UI *struct {
		Slots []UISlot `json:"slots"` // UI slots this plugin registers in admin
	} `json:"ui,omitempty"`

	// Portal UI configuration (end-user portal)
	Portal *struct {
		Slots []PortalUISlot `json:"slots"` // UI slots this plugin registers in portal
	} `json:"portal,omitempty"`

	// Compatibility requirements
	Compat struct {
		App string   `json:"app"` // App version compatibility (semver range)
		API []string `json:"api"` // Required API versions
	} `json:"compat"`

	// Security settings
	Security *struct {
		CSP string `json:"csp"` // Content Security Policy for plugin UI
	} `json:"security,omitempty"`

	// Static assets
	Assets []string `json:"assets"`

	// Scheduled tasks
	Schedules []ScheduleDefinition `json:"schedules,omitempty"`

	// Resource types provided by this plugin (for ResourceProvider capability)
	ResourceTypes []ManifestResourceType `json:"resource_types,omitempty"`

	// Governed metadata contributions (Enterprise): vocabularies and schemas
	// the plugin wants registered when it is loaded.
	Metadata *ManifestMetadata `json:"metadata,omitempty"`

	// RBAC declares permission resources and per-RPC-method requirements
	// for the role editor; see ManifestRBAC.
	RBAC *ManifestRBAC `json:"rbac,omitempty"`
}

PluginManifest represents the manifest structure defined in Hot-load-ui-plugins-plan.md

func (*PluginManifest) GetAllPermissionScopes

func (pm *PluginManifest) GetAllPermissionScopes() []string

GetAllPermissionScopes returns all permission scopes (services + object_hooks) for approval workflow

func (*PluginManifest) GetObjectHooks

func (pm *PluginManifest) GetObjectHooks() []string

GetObjectHooks returns all object hook permissions declared in the manifest

func (*PluginManifest) GetPortalRoutes

func (pm *PluginManifest) GetPortalRoutes() []UISlotItem

GetPortalRoutes extracts all routes defined in the portal manifest section

func (*PluginManifest) GetPortalSidebarItems

func (pm *PluginManifest) GetPortalSidebarItems() []PortalUISlot

GetPortalSidebarItems extracts portal sidebar menu items from the manifest

func (*PluginManifest) GetServiceScopes

func (pm *PluginManifest) GetServiceScopes() []string

GetServiceScopes returns all service scopes declared in the manifest

func (*PluginManifest) GetSidebarItems

func (pm *PluginManifest) GetSidebarItems() []UISlot

GetSidebarItems extracts sidebar menu items from the manifest

func (*PluginManifest) GetUIRoutes

func (pm *PluginManifest) GetUIRoutes() []UISlotItem

GetUIRoutes extracts all routes defined in the manifest

func (*PluginManifest) HasPermission

func (pm *PluginManifest) HasPermission(permType, permission string) bool

HasPermission checks if the manifest declares a specific permission

func (*PluginManifest) HasServiceScope

func (pm *PluginManifest) HasServiceScope(scope string) bool

HasServiceScope checks if the manifest declares a specific service scope

func (*PluginManifest) ValidateManifest

func (pm *PluginManifest) ValidateManifest() error

ValidateManifest validates the plugin manifest structure

type PluginPermissionResource

type PluginPermissionResource struct {
	ID          uint       `json:"id" gorm:"primaryKey"`
	PluginID    uint       `json:"plugin_id" gorm:"not null;uniqueIndex:idx_plugin_permission_resources_key"`
	Key         string     `json:"key" gorm:"size:100;not null;uniqueIndex:idx_plugin_permission_resources_key"`
	Label       string     `json:"label" gorm:"size:255;not null"`
	Description string     `json:"description"`
	Actions     StringList `json:"actions" gorm:"type:text"`
	Sensitive   bool       `json:"sensitive" gorm:"default:false"`
	// Source is "manifest" or "runtime". Manifest rows are replaced on every
	// manifest registration; runtime rows only through the management API.
	Source    string    `json:"source" gorm:"size:16;not null;default:manifest"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

PluginPermissionResource is a permission resource a plugin contributes to the RBAC catalogue beyond its base resource: declared in the manifest ("rbac.resources") or registered at runtime through the management API (asset classes defined by administrators, for example). Rows are what the catalogue is rebuilt from at boot, so the role editor keeps working while the plugin process is down.

func ListPluginPermissionResources

func ListPluginPermissionResources(db *gorm.DB, pluginID uint) ([]PluginPermissionResource, error)

ListByPlugin returns the plugin's rows, manifest ones first.

func (PluginPermissionResource) TableName

func (PluginPermissionResource) TableName() string

type PluginResourceType

type PluginResourceType struct {
	gorm.Model
	ID                  uint   `json:"id" gorm:"primaryKey"`
	PluginID            uint   `json:"plugin_id" gorm:"uniqueIndex:idx_prt_plugin_slug"`
	Slug                string `json:"slug" gorm:"size:100;uniqueIndex:idx_prt_plugin_slug"`
	Name                string `json:"name" gorm:"size:255"`
	Description         string `json:"description"`
	Icon                string `json:"icon" gorm:"size:500"`
	HasPrivacyScore     bool   `json:"has_privacy_score" gorm:"default:false"`
	SupportsSubmissions bool   `json:"supports_submissions" gorm:"default:false"`
	SupportsMetadata    bool   `json:"supports_metadata" gorm:"default:false"` // Instances can carry governed metadata (Enterprise)
	FormComponentTag    string `json:"form_component_tag" gorm:"size:100"`
	FormComponentEntry  string `json:"form_component_entry" gorm:"size:500"`
	SubmissionSchema    string `json:"submission_schema" gorm:"type:text"` // JSON Schema (object) for community submissions; empty = free-form
	IsActive            bool   `json:"is_active" gorm:"default:true"`

	// AccessGrantedViaApp is the resolved answer to "does an App credential
	// grant access to instances of this type?". Only such types are offered
	// in the App forms, show "Build app" in the portal catalog and travel in
	// the gateway config snapshot. Resolved at registration time by
	// ResolveAccessGrantedViaApp from the declared value and the plugin's
	// hook types, so read paths never need the Plugin loaded.
	AccessGrantedViaApp bool `json:"access_granted_via_app" gorm:"default:false"`
	// AccessGrantedViaAppDeclared is what the plugin declared (nil = it left
	// the platform to decide). Kept so a later registration can re-resolve.
	AccessGrantedViaAppDeclared *bool `json:"-" gorm:"column:access_granted_via_app_declared"`
	// PortalDetailPath is a same-origin path template to an instance's portal
	// page; "{id}" is replaced with the escaped instance ID.
	PortalDetailPath string `json:"portal_detail_path" gorm:"size:500"`
	// DefaultAccess is what the plugin declared for Default-team access:
	// "" or DefaultAccessAuto grants every active instance to the Default
	// team; DefaultAccessExplicit leaves access to team grants alone. Read
	// it through services' effective policy, which forces auto in Community
	// Edition.
	DefaultAccess string `json:"default_access" gorm:"size:16"`

	// Relationships
	Plugin *Plugin `json:"plugin,omitempty" gorm:"foreignKey:PluginID"`
}

PluginResourceType represents a resource type registered by a plugin. Plugins declare resource types via the ResourceProvider capability. Each type can appear in the App creation form and participate in privacy validation.

func (*PluginResourceType) Create

func (p *PluginResourceType) Create(db *gorm.DB) error

func (*PluginResourceType) Delete

func (p *PluginResourceType) Delete(db *gorm.DB) error

func (*PluginResourceType) Get

func (p *PluginResourceType) Get(db *gorm.DB, id uint) error

func (*PluginResourceType) GetByPluginAndSlug

func (p *PluginResourceType) GetByPluginAndSlug(db *gorm.DB, pluginID uint, slug string) error

GetByPluginAndSlug finds a resource type by plugin ID and slug

func (PluginResourceType) TableName

func (PluginResourceType) TableName() string

func (*PluginResourceType) Update

func (p *PluginResourceType) Update(db *gorm.DB) error

type PluginResourceTypes

type PluginResourceTypes []PluginResourceType

func (*PluginResourceTypes) GetAllActive

func (pts *PluginResourceTypes) GetAllActive(db *gorm.DB) error

GetAllActive returns all active plugin resource types

func (*PluginResourceTypes) GetAllSubmittable

func (pts *PluginResourceTypes) GetAllSubmittable(db *gorm.DB) error

GetAllSubmittable returns the active resource types that accept community submissions, filtered in the database rather than in memory.

func (*PluginResourceTypes) GetByPlugin

func (pts *PluginResourceTypes) GetByPlugin(db *gorm.DB, pluginID uint) error

GetByPlugin returns all resource types for a specific plugin

type PluginSchedule

type PluginSchedule struct {
	ID       uint   `gorm:"primaryKey" json:"id"`
	PluginID uint   `gorm:"index;not null" json:"plugin_id"`
	Plugin   Plugin `gorm:"foreignKey:PluginID;constraint:OnDelete:CASCADE" json:"plugin,omitempty"`

	ManifestScheduleID string `gorm:"index;not null" json:"schedule_id"` // From manifest (e.g., "sync-repos")
	Name               string `gorm:"not null" json:"name"`              // Human-readable name
	CronExpr           string `gorm:"not null" json:"cron_expr"`         // Cron expression
	Timezone           string `gorm:"default:'UTC'" json:"timezone"`     // Timezone for cron evaluation
	Enabled            bool   `gorm:"default:true" json:"enabled"`       // Whether schedule is enabled
	Config             string `gorm:"type:text" json:"config"`           // JSON config from manifest
	TimeoutSeconds     int    `gorm:"default:60" json:"timeout_seconds"` // Max execution time in seconds

	LastRun *time.Time `json:"last_run,omitempty"`
	NextRun *time.Time `json:"next_run,omitempty"`

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

PluginSchedule represents a cron-based scheduled task for a plugin

func (PluginSchedule) TableName

func (PluginSchedule) TableName() string

TableName returns table name for PluginSchedule

type PluginScheduleExecution

type PluginScheduleExecution struct {
	ID               uint           `gorm:"primaryKey" json:"id"`
	PluginScheduleID uint           `gorm:"index;not null" json:"plugin_schedule_id"` // FK to plugin_schedules.id
	Schedule         PluginSchedule `gorm:"foreignKey:PluginScheduleID;constraint:OnDelete:CASCADE" json:"schedule,omitempty"`
	PluginID         uint           `gorm:"index;not null" json:"plugin_id"` // Track plugin for cleanup

	Status      string     `gorm:"index;not null;default:'pending'" json:"status"` // "pending", "running", "completed", "failed", "timeout"
	StartedAt   time.Time  `gorm:"index;not null" json:"started_at"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
	LockedBy    string     `gorm:"index" json:"locked_by,omitempty"` // Instance ID that owns this execution

	Success  bool   `json:"success"`
	Error    string `gorm:"type:text" json:"error,omitempty"`
	Duration int64  `json:"duration"` // Milliseconds

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

PluginScheduleExecution represents a single execution of a scheduled task

func (PluginScheduleExecution) TableName

func (PluginScheduleExecution) TableName() string

TableName returns table name for PluginScheduleExecution

type Plugins

type Plugins []Plugin

func (*Plugins) GetPluginsByHookType

func (plugins *Plugins) GetPluginsByHookType(db *gorm.DB, hookType string) error

GetPluginsByHookType returns plugins filtered by hook type

func (*Plugins) GetPluginsForLLM

func (plugins *Plugins) GetPluginsForLLM(db *gorm.DB, llmID uint) error

GetPluginsForLLM returns plugins associated with an LLM, ordered by execution order

func (*Plugins) GetPluginsInNamespace

func (plugins *Plugins) GetPluginsInNamespace(db *gorm.DB, namespace string) error

GetPluginsInNamespace returns plugins in a specific namespace (including global)

func (*Plugins) ListAllWithPagination

func (plugins *Plugins) ListAllWithPagination(db *gorm.DB, pageSize, pageNumber int, all bool, hookType string, namespace string) (int64, int, error)

ListAllWithPagination returns paginated list of all plugins (active and inactive) with filtering

func (*Plugins) ListWithPagination

func (plugins *Plugins) ListWithPagination(db *gorm.DB, pageSize, pageNumber int, all bool, hookType string, isActive bool, namespace string) (int64, int, error)

ListWithPagination returns paginated list of plugins with filtering

type PoolVendor

type PoolVendor struct {
	gorm.Model
	ID       uint            `json:"id" gorm:"primaryKey"`
	PoolID   uint            `json:"pool_id" gorm:"not null;index:idx_vendor_pool"`
	LLMID    uint            `json:"llm_id" gorm:"not null;index:idx_vendor_llm"`
	Weight   int             `json:"weight" gorm:"default:1"` // Used for weighted selection
	Active   bool            `json:"active" gorm:"default:true"`
	LLM      *LLM            `json:"llm,omitempty" gorm:"foreignKey:LLMID"`
	Mappings []*ModelMapping `json:"mappings" gorm:"foreignKey:VendorID;constraint:OnDelete:CASCADE"`
}

PoolVendor represents an LLM vendor within a pool Weight is used for weighted selection algorithm

func NewPoolVendor

func NewPoolVendor() *PoolVendor

NewPoolVendor creates a new PoolVendor instance

func (*PoolVendor) Delete

func (v *PoolVendor) Delete(db *gorm.DB) error

Delete removes a PoolVendor and cascades to mappings Note: GORM soft delete does not trigger DB-level CASCADE constraints, so we must manually delete children

func (*PoolVendor) Get

func (v *PoolVendor) Get(db *gorm.DB, id uint) error

Get retrieves a PoolVendor by ID with LLM and Mappings relationships

type PoolVendors

type PoolVendors []PoolVendor

func (*PoolVendors) GetActiveVendorsByPoolID

func (v *PoolVendors) GetActiveVendorsByPoolID(db *gorm.DB, poolID uint) error

GetActiveVendorsByPoolID retrieves all active vendors for a pool

type PortalUISlot

type PortalUISlot struct {
	Slot   string       `json:"slot"`             // Slot identifier (e.g., "portal_sidebar.section")
	Label  string       `json:"label"`            // Display label
	Icon   string       `json:"icon"`             // Icon path/URL
	Groups []string     `json:"groups,omitempty"` // Allowed groups (empty = all portal users)
	Items  []UISlotItem `json:"items"`            // Items to mount in this slot
}

PortalUISlot represents a portal UI extension point with group-based visibility filtering. If Groups is empty, the slot is visible to all portal users. If Groups has values, only users belonging to at least one of those groups can see it.

type PresentToolSpec

type PresentToolSpec struct {
	Description string                 `json:"description"`
	Parameters  map[string]interface{} `json:"parameters"`
}

PresentToolSpec is the model-facing half of the generative UI tool.

func PresentToolSchema

func PresentToolSchema() (PresentToolSpec, error)

PresentToolSchema returns the embedded generative UI tool definition. The parameters map is shared; callers must not mutate it.

type Profile

type Profile struct {
	gorm.Model                `json:"-"`
	ProfileID                 string `gorm:"index" json:"ID"`
	Name                      string
	OrgID                     string
	ActionType                string
	MatchedPolicyID           string
	Type                      string
	ProviderName              string
	CustomEmailField          string
	CustomUserIDField         string
	ProviderConfig            JSONMap `gorm:"type:json"`
	IdentityHandlerConfig     JSONMap `gorm:"type:json"`
	ProviderConstraintsDomain string
	ProviderConstraintsGroup  string
	ReturnURL                 string
	DefaultUserGroupID        string
	CustomUserGroupField      string
	UserGroupMapping          StringMap `gorm:"type:json"`
	UserGroupSeparator        string
	SSOOnlyForRegisteredUsers bool
	// NewUserShowPortal and NewUserShowChat are the provisioning defaults
	// applied to users this profile creates on their first login. They are
	// only consulted at creation time; existing users keep whatever an
	// administrator set. Team membership comes from the claim mapping above.
	NewUserShowPortal    bool
	NewUserShowChat      bool
	SelectedProviderType string `json:"-"`
	UserID               uint   `json:"-"`
	User                 User   `json:"-"`
	UseInLoginPage       bool   `json:"-"`
}

Profile represents an sso profile in the store

func NewProfile

func NewProfile() *Profile

func (*Profile) Create

func (p *Profile) Create(db *gorm.DB) error

func (*Profile) Delete

func (p *Profile) Delete(db *gorm.DB) error

func (*Profile) Get

func (p *Profile) Get(db *gorm.DB, profileID string) error

func (*Profile) GetByName

func (p *Profile) GetByName(db *gorm.DB, name string) error

func (*Profile) GetLoginPageProfile

func (p *Profile) GetLoginPageProfile(db *gorm.DB) error

func (*Profile) MapToTapProfile

func (p *Profile) MapToTapProfile(tapProfile *tap.Profile)

MapToTapProfile fills a tap.Profile with data from the local Profile

func (*Profile) ProvisioningDefaults

func (p *Profile) ProvisioningDefaults() (showPortal, showChat bool)

ProvisioningDefaults returns the surface flags a user created through this profile starts with. A nil profile (login via a profile that no longer exists, or an external broker that does not identify one) falls back to the same defaults as NewUser.

func (*Profile) Update

func (p *Profile) Update(db *gorm.DB) error

func (*Profile) UpdateUseInLoginPage

func (p *Profile) UpdateUseInLoginPage(db *gorm.DB, value bool) error

type Profiles

type Profiles []Profile

func (*Profiles) GetAll

func (p *Profiles) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, sort string) (int64, int, error)

type PromptTemplate

type PromptTemplate struct {
	ID     uint   `json:"id"`
	Name   string `json:"name"`
	Prompt string `json:"prompt"`
}

type ProxyLog

type ProxyLog struct {
	gorm.Model
	ID        uint      `gorm:"primaryKey"`
	AppID     uint      `gorm:"index:idx_proxy_logs_app_time,priority:1;index:idx_proxy_logs_app_code_time,priority:1"`
	UserID    uint      `gorm:"index"`
	TimeStamp time.Time `` /* 160-byte string literal not displayed */
	// LLMID is the specific LLM vendor entry that handled the request.
	// Required to disambiguate when several LLM entries share a Vendor type
	// (e.g. two Anthropic entries with different API keys).
	LLMID        uint `gorm:"index:idx_proxy_logs_llm_time,priority:1"`
	Vendor       string
	ModelName    string
	RequestBody  string
	ResponseBody string
	ResponseCode int `gorm:"index:idx_proxy_logs_code;index:idx_proxy_logs_app_code_time,priority:2"`
	// FailoverFromLLMID is set when this attempt was a rung of that LLM's
	// failover waterfall; nil for a primary attempt. FailoverAttempt is the
	// 1-based rung index (0 = primary). A request that failed over leaves one
	// row per attempt, so request counts should filter failover_attempt = 0.
	FailoverFromLLMID *uint `gorm:"index:idx_proxy_logs_failover_from"`
	FailoverAttempt   int   `gorm:"default:0"`
	// Router fields are set when the request was addressed to a router: its
	// kind ("model_router"), slug, the pool or route that matched, and why
	// (RouteReason, a small fixed set).
	RouterKind  string `gorm:"size:32"`
	RouterSlug  string `gorm:"index:idx_proxy_logs_router"`
	RouterPool  string
	Route       string
	RouteReason string `gorm:"size:64"`
	// The model the caller asked the router for, the model the chosen LLM
	// was asked for (after any mapping), and how the target was selected
	// ("round_robin", "weighted").
	RouteSourceModel string
	RouteTargetModel string
	RouteSelection   string `gorm:"size:32"`
	// Semantic Routers: the similarity that decided an embedding match, and,
	// in shadow mode, the route the classifier picked (the default served).
	RouteScore  float64
	ShadowRoute string
	// OnBehalfOf and ActingAgent are who the call was for and the agent that
	// made it, when an auth plugin said (a delegated token's sub, and its act
	// or azp). UserID stays the App owner. Audit only.
	OnBehalfOf  string `gorm:"size:255"`
	ActingAgent string `gorm:"size:255"`
}

type ProxyLogAttributes

type ProxyLogAttributes struct {
	AppID             uint      `json:"app_id"`
	UserID            uint      `json:"user_id"`
	LLMID             uint      `json:"llm_id"`
	ModelName         string    `json:"model_name"`
	TimeStamp         time.Time `json:"time_stamp"`
	Vendor            string    `json:"vendor"`
	RequestBody       string    `json:"request_body"`
	ResponseBody      string    `json:"response_body"`
	ResponseCode      int       `json:"response_code"`
	FailoverAttempt   int       `json:"failover_attempt"`
	FailoverFromLLMID *uint     `json:"failover_from_llm_id,omitempty"`
	RouterKind        string    `json:"router_kind,omitempty"`
	RouterSlug        string    `json:"router_slug,omitempty"`
	RouterPool        string    `json:"router_pool,omitempty"`
	Route             string    `json:"route,omitempty"`
	RouteReason       string    `json:"route_reason,omitempty"`
	RouteSourceModel  string    `json:"route_source_model,omitempty"`
	RouteTargetModel  string    `json:"route_target_model,omitempty"`
	RouteSelection    string    `json:"route_selection,omitempty"`
	RouteScore        float64   `json:"route_score,omitempty"`
	ShadowRoute       string    `json:"shadow_route,omitempty"`
	OnBehalfOf        string    `json:"on_behalf_of,omitempty"`
	ActingAgent       string    `json:"acting_agent,omitempty"`
}

ProxyLogAttributes is the serialised form of a ProxyLog row. The failover marker is carried so a fallback row can be told from a primary one: FailoverAttempt is the 1-based rung index (0 = primary) and FailoverFromLLMID the primary the request failed over from, absent for a primary attempt.

type ProxyLogExport

type ProxyLogExport struct {
	gorm.Model

	// Export identification - UUID used as download token
	ExportID string `gorm:"uniqueIndex;not null" json:"export_id"`

	// Source information
	SourceType ExportSourceType `gorm:"not null" json:"source_type"` // "app" or "llm"
	SourceID   uint             `gorm:"not null" json:"source_id"`   // AppID or LLMID

	// Filter criteria (stored for reference)
	StartDate    time.Time `gorm:"not null" json:"start_date"`
	EndDate      time.Time `gorm:"not null" json:"end_date"`
	SearchFilter string    `json:"search_filter,omitempty"` // Optional search term

	// Job status
	Status       ExportStatus `gorm:"default:'pending'" json:"status"`
	TotalRecords int64        `json:"total_records"` // Total count after query

	// File information
	FilePath string `json:"file_path,omitempty"` // Path to generated JSON file
	FileSize int64  `json:"file_size"`           // Size in bytes

	// Timing
	RequestedAt time.Time  `gorm:"not null" json:"requested_at"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
	ExpiresAt   time.Time  `gorm:"not null;index" json:"expires_at"` // 24 hours after completion

	// User tracking
	RequestedBy uint `gorm:"not null" json:"requested_by"` // Admin user ID

	// Error handling
	ErrorMessage string `json:"error_message,omitempty"`
}

ProxyLogExport tracks export job status and file references for proxy log exports. This is an Enterprise Edition feature.

func (ProxyLogExport) TableName

func (ProxyLogExport) TableName() string

TableName returns the table name for the ProxyLogExport model

func (*ProxyLogExport) ToResponse

func (p *ProxyLogExport) ToResponse() ProxyLogExportResponse

ToResponse converts a ProxyLogExport to its JSON:API response format

type ProxyLogExportAttributes

type ProxyLogExportAttributes struct {
	ExportID     string           `json:"export_id"`
	SourceType   ExportSourceType `json:"source_type"`
	SourceID     uint             `json:"source_id"`
	StartDate    time.Time        `json:"start_date"`
	EndDate      time.Time        `json:"end_date"`
	SearchFilter string           `json:"search_filter,omitempty"`
	Status       ExportStatus     `json:"status"`
	TotalRecords int64            `json:"total_records"`
	FileSize     int64            `json:"file_size"`
	RequestedAt  time.Time        `json:"requested_at"`
	CompletedAt  *time.Time       `json:"completed_at,omitempty"`
	ExpiresAt    time.Time        `json:"expires_at"`
	RequestedBy  uint             `json:"requested_by"`
	ErrorMessage string           `json:"error_message,omitempty"`
}

ProxyLogExportAttributes contains the attributes for the JSON:API response

type ProxyLogExportResponse

type ProxyLogExportResponse struct {
	Type       string                   `json:"type"`
	ID         string                   `json:"id"`
	Attributes ProxyLogExportAttributes `json:"attributes"`
}

ProxyLogExportResponse is the JSON:API response format for a proxy log export

type ProxyLogResponse

type ProxyLogResponse struct {
	Type       string             `json:"type"`
	ID         string             `json:"id"`
	Attributes ProxyLogAttributes `json:"attributes"`
}

ProxyLogResponse represents a proxy log response in JSON API format

func NewProxyLogResponse

func NewProxyLogResponse(log ProxyLog) ProxyLogResponse

NewProxyLogResponse serialises one ProxyLog row for the proxy-log endpoints.

type PushAttempt

type PushAttempt struct {
	Attempt int       `json:"attempt"`
	Node    string    `json:"node"`
	At      time.Time `json:"at"`
	Outcome string    `json:"outcome"`
}

PushAttempt records one delivery attempt of a command, so a failure can be explained attempt by attempt.

type PushOperation

type PushOperation struct {
	OperationID string     `json:"operation_id" gorm:"primaryKey;size:64"`
	Scope       string     `json:"scope" gorm:"size:16;not null"` // edge | namespace | all
	Namespace   string     `json:"namespace" gorm:"size:255"`
	InitiatedBy string     `json:"initiated_by" gorm:"size:255"`
	Status      string     `json:"status" gorm:"size:32;not null;index"`
	Total       int        `json:"total"`
	CreatedAt   time.Time  `json:"created_at" gorm:"index"`
	DeadlineAt  time.Time  `json:"deadline_at"`
	CompletedAt *time.Time `json:"completed_at" gorm:"index"` // retention
}

PushOperation is one push: to one edge, a namespace, or every namespace.

type RawJSON

type RawJSON string

RawJSON is a string column that already holds JSON. It marshals to the API as the JSON value itself (not a quoted string) so clients get an object. An empty value marshals as null.

func (RawJSON) MarshalJSON

func (r RawJSON) MarshalJSON() ([]byte, error)

MarshalJSON emits the stored JSON verbatim, or null when empty or invalid.

func (*RawJSON) UnmarshalJSON

func (r *RawJSON) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts any JSON value and stores its raw bytes.

type RegisteredPlugin

type RegisteredPlugin struct {
	gorm.Model
	PluginID        uint                   `json:"plugin_id" gorm:"index;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"` // References plugins.id
	ManifestVersion string                 `json:"manifest_version"`
	ParsedManifest  map[string]interface{} `json:"parsed_manifest" gorm:"serializer:json"`
	IsLoaded        bool                   `json:"is_loaded" gorm:"default:false"`
	LoadedAt        *time.Time             `json:"loaded_at"`
	LoadError       string                 `json:"load_error"`
	AssetPaths      []string               `json:"asset_paths" gorm:"serializer:json"`
	CreatedAt       time.Time              `json:"created_at"`
	UpdatedAt       time.Time              `json:"updated_at"`

	// Relationships
	Plugin *Plugin `json:"plugin,omitempty" gorm:"foreignKey:PluginID"`
}

RegisteredPlugin represents a plugin with its parsed manifest and runtime info

func (RegisteredPlugin) TableName

func (RegisteredPlugin) TableName() string

TableName returns table name for RegisteredPlugin

type ResolvedFailoverTriggers

type ResolvedFailoverTriggers struct {
	StatusCodes          map[int]bool
	OnTimeout            bool
	OnConnectionError    bool
	AttemptTimeoutSecond int // 0 = use the proxy's LLM timeout
}

ResolvedFailoverTriggers is LLMFailoverTriggers with every default applied, in the shape the proxy wants to consult per attempt.

type Role

type Role struct {
	ID          uint       `gorm:"primaryKey" json:"id"`
	Slug        string     `gorm:"size:64;uniqueIndex:idx_roles_slug" json:"slug"`
	Name        string     `gorm:"size:128;uniqueIndex:idx_roles_name" json:"name"`
	Description string     `gorm:"size:1024" json:"description"`
	IsSystem    bool       `json:"is_system"`
	Permissions StringList `gorm:"type:text" json:"permissions"`
	CreatedBy   uint       `json:"created_by"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
}

Role is a named bundle of permissions. Permissions are stored as the catalogue strings ("llms:read"); the single wildcard "*" is reserved for the Owner and Administrator system roles.

The table exists in Community Edition but is unused there.

func (*Role) IsWildcard

func (r *Role) IsWildcard() bool

IsWildcard reports whether the role grants full administrator access.

func (Role) TableName

func (Role) TableName() string

TableName pins the table so the slug/name indexes are stable.

type RoleBinding

type RoleBinding struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	SubjectType string `gorm:"size:16;uniqueIndex:idx_role_bindings_unique,priority:1;index:idx_role_bindings_subject,priority:1" json:"subject_type"`
	SubjectID   uint   `gorm:"uniqueIndex:idx_role_bindings_unique,priority:2;index:idx_role_bindings_subject,priority:2" json:"subject_id"`
	RoleID      uint   `gorm:"uniqueIndex:idx_role_bindings_unique,priority:3;index:idx_role_bindings_role" json:"role_id"`
	ScopeType   string `gorm:"size:32;uniqueIndex:idx_role_bindings_unique,priority:4" json:"scope_type"`
	ScopeID     string `gorm:"size:64;uniqueIndex:idx_role_bindings_unique,priority:5" json:"scope_id"`
	CreatedBy   uint   `json:"created_by"`
	// Source is RoleBindingSourceHost for a binding the host application
	// manages, empty otherwise.
	Source    string    `gorm:"size:16;not null;default:''" json:"source"`
	CreatedAt time.Time `json:"created_at"`
	Role      *Role     `gorm:"foreignKey:RoleID" json:"role,omitempty"`
}

RoleBinding assigns a role to a subject (a user or a group). ScopeType and ScopeID are reserved for scoped bindings (namespace, catalogue); an empty string means the binding is global. They are empty strings rather than NULLs so the composite unique index behaves the same on Postgres and SQLite.

func (RoleBinding) TableName

func (RoleBinding) TableName() string

TableName pins the table name.

type ScheduleDefinition

type ScheduleDefinition struct {
	ID             string                 `json:"id" binding:"required"`     // Unique schedule identifier
	Name           string                 `json:"name" binding:"required"`   // Human-readable name
	Cron           string                 `json:"cron" binding:"required"`   // Cron expression
	Timezone       string                 `json:"timezone,omitempty"`        // Timezone (default: UTC)
	Enabled        bool                   `json:"enabled"`                   // Whether enabled (default: true)
	TimeoutSeconds int                    `json:"timeout_seconds,omitempty"` // Max execution time (default: 60)
	Config         map[string]interface{} `json:"config,omitempty"`          // Schedule-specific config
}

ScheduleDefinition represents a cron-based task schedule in the manifest

type SchedulerLease

type SchedulerLease struct {
	ID          uint      `gorm:"primaryKey" json:"id"`
	InstanceID  string    `gorm:"uniqueIndex;not null" json:"instance_id"` // hostname-pid
	LeaderID    string    `gorm:"index;not null" json:"leader_id"`         // Current leader instance
	ExpiresAt   time.Time `gorm:"index;not null" json:"expires_at"`        // Leader lease expiry
	HeartbeatAt time.Time `json:"heartbeat_at"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

SchedulerLease represents the leader election lease for scheduler service

func (SchedulerLease) TableName

func (SchedulerLease) TableName() string

TableName returns table name for SchedulerLease

type SecretReference

type SecretReference struct {
	ID         uint   `gorm:"primaryKey" json:"id"`
	SecretName string `gorm:"size:255;index:idx_secret_references_name" json:"secret_name"`
	ObjectType string `gorm:"size:32;index:idx_secret_references_object,priority:1" json:"object_type"`
	ObjectID   uint   `gorm:"index:idx_secret_references_object,priority:2" json:"object_id"`
	ObjectName string `json:"object_name"`
}

SecretReference records that one object reads a secret. It is the indexed, denormalised answer to "which LLMs, tools and datasources use this secret?", maintained by the AfterSave/AfterDelete hooks on those models so the secrets list and the per-secret dependents endpoint are single indexed queries rather than scans of the object tables.

The rows are derived data: BackfillSecretReferences rebuilds them from the object tables at startup, which also repairs any drift from writes that bypassed the hooks (bulk SQL, external tooling).

type SelectionAlgorithm

type SelectionAlgorithm string

SelectionAlgorithm defines how vendors are selected within a pool

const (
	SelectionRoundRobin SelectionAlgorithm = "round_robin"
	SelectionWeighted   SelectionAlgorithm = "weighted"
)

type SemanticRouter

type SemanticRouter struct {
	gorm.Model
	ID          uint   `json:"id" gorm:"primaryKey"`
	Name        string `json:"name" gorm:"not null"`
	Slug        string `json:"slug" gorm:"uniqueIndex:idx_semantic_router_slug_namespace;not null"`
	Namespace   string `json:"namespace" gorm:"default:'';uniqueIndex:idx_semantic_router_slug_namespace;index:idx_semantic_router_namespace"`
	Description string `json:"description"`
	Active      bool   `json:"active" gorm:"default:false"`
	// APICompat is the API the router is called with. Only the OpenAI-shaped
	// unified ingress routes today.
	APICompat string `json:"api_compat" gorm:"default:'openai'"`

	// Portal presentation.
	ShortDescription string `json:"short_description"`
	LongDescription  string `json:"long_description"`
	LogoURL          string `json:"logo_url"`

	Settings sr.Settings `json:"settings" gorm:"serializer:json"`
	Routes   []sr.Route  `json:"routes" gorm:"serializer:json"`

	// EmbedderID is the embedder of the embedding stage (examples and
	// requests). Settings.Embedding then only carries its timeout; without
	// an embedder, a Settings.Embedding naming an LLM is used as it is
	// (routers saved before Embedders, draft tests).
	EmbedderID *uint     `json:"embedder_id" gorm:"index"`
	Embedder   *Embedder `json:"-" gorm:"foreignKey:EmbedderID"`

	Catalogues []Catalogue `json:"-" gorm:"many2many:catalogue_semantic_routers;"`
}

SemanticRouter is a router that picks one of its named routes from what the prompt says (Enterprise; see pkg/semanticrouting). Like a Model Router it is addressed on the unified ingress ("{slug}/auto"), published in LLM catalogues and granted to Apps; a grant reaches the LLMs its routes send to, only through the router.

func (*SemanticRouter) CompiledConfig

func (r *SemanticRouter) CompiledConfig(db *gorm.DB, encrypt func(string) (string, error)) (sr.Config, error)

CompiledConfig is the router as the engine runs it: the embedder is flattened into Settings.Embedding. A linked embedder becomes the LLM reference older edges understand ({llm_id, model}); a standalone one is carried inline. With encrypt nil (the hub) the inline key is resolved into APIKey; with encrypt set (the edge snapshot) it travels encrypted in APIKeyEncrypted. A router without an embedder keeps its Settings.Embedding.

func (*SemanticRouter) Config

func (r *SemanticRouter) Config() sr.Config

Config is the router as the engine compiles it.

func (*SemanticRouter) ConfigJSON

func (r *SemanticRouter) ConfigJSON() (string, error)

ConfigJSON is Config as stored, without resolving the embedder.

func (*SemanticRouter) Create

func (r *SemanticRouter) Create(db *gorm.DB) error

Create inserts the router and its target rows.

func (*SemanticRouter) Delete

func (r *SemanticRouter) Delete(db *gorm.DB) error

Delete removes the router for good, with its targets, App grants and catalogue memberships. It is a hard delete: a soft-deleted row would keep its slug in the unique index and block a new router of the same name.

func (*SemanticRouter) EdgeConfigJSON

func (r *SemanticRouter) EdgeConfigJSON(db *gorm.DB, encrypt func(string) (string, error)) (string, error)

EdgeConfigJSON is CompiledConfig as the snapshot carries it to the edge. The encoding is deterministic (struct field order) and the key encryption is too, so the snapshot checksum is stable.

func (*SemanticRouter) Get

func (r *SemanticRouter) Get(db *gorm.DB, id uint) error

Get loads a router by id, with its catalogues.

func (*SemanticRouter) Update

func (r *SemanticRouter) Update(db *gorm.DB) error

Update saves the router's fields (not its catalogues) and rebuilds its target rows.

type SemanticRouterTarget

type SemanticRouterTarget struct {
	ID            uint   `gorm:"primaryKey"`
	RouterID      uint   `gorm:"not null;index:idx_semantic_router_target_router"`
	LLMID         *uint  `gorm:"index:idx_semantic_router_target_llm"`
	ModelRouterID *uint  `gorm:"index:idx_semantic_router_target_model_router"`
	Role          string `gorm:"size:16;not null"` // "route" or "classifier"
}

SemanticRouterTarget records what a router may send a request's text to: the LLMs and Model Routers its routes target, and the LLMs that embed and judge. It is rebuilt whenever the router is saved, so the privacy score (the least private of them) and "what uses this LLM" can be answered in SQL.

type SemanticRouters

type SemanticRouters []SemanticRouter

SemanticRouters is a list of routers.

func (*SemanticRouters) GetAll

func (rs *SemanticRouters) GetAll(db *gorm.DB, pageSize, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

GetAll lists routers, paged unless all is set.

type StringList

type StringList []string

StringList is a JSON-encoded []string column. Nil scans to an empty list so callers never see a NULL.

func (*StringList) Scan

func (s *StringList) Scan(value interface{}) error

Scan implements sql.Scanner.

func (StringList) Value

func (s StringList) Value() (driver.Value, error)

Value implements driver.Valuer.

type StringMap

type StringMap map[string]string

StringMap is a custom type for map[string]string to implement sql.Scanner and driver.Valuer

func (*StringMap) Scan

func (s *StringMap) Scan(value interface{}) error

Implement the sql.Scanner interface for StringMap

func (StringMap) Value

func (s StringMap) Value() (driver.Value, error)

Implement the driver.Valuer interface for StringMap

type StudioSchema

type StudioSchema struct {
	ID               uint `gorm:"primaryKey;autoIncrement:false"`
	Version          int  `gorm:"not null"`
	MinReaderVersion int  `gorm:"not null"`
	// WrittenBy is the Studio version that recorded it.
	WrittenBy string
	UpdatedAt time.Time
}

StudioSchema records the schema version the database was last migrated to by a full Studio, and the oldest schema version whose code can still read it.

func CheckSchemaVersion

func CheckSchemaVersion(ctx context.Context, db *gorm.DB) (StudioSchema, error)

CheckSchemaVersion reports whether this build can use the database's schema without migrating it, and returns the record. It only reads: it creates nothing. The errors wrap ErrSchemaMissing, ErrSchemaTooOld or ErrSchemaTooNew.

func (StudioSchema) TableName

func (StudioSchema) TableName() string

TableName keeps the table name singular: it holds one row.

type Submission

type Submission struct {
	gorm.Model
	ID           uint   `json:"id" gorm:"primaryKey"`
	ResourceType string `json:"resource_type" gorm:"index"` // datasource | tool | plugin
	ResourceID   *uint  `json:"resource_id"`                // set after approval creates the resource

	// Plugin resource type reference (only set when ResourceType == "plugin")
	PluginResourceTypeID *uint               `json:"plugin_resource_type_id" gorm:"index"`
	PluginResourceType   *PluginResourceType `json:"plugin_resource_type,omitempty" gorm:"foreignKey:PluginResourceTypeID"`
	// PluginInstanceID is the plugin-assigned instance ID created on approval
	// (plugin instances use string IDs, unlike ResourceID).
	PluginInstanceID string `json:"plugin_instance_id" gorm:"size:255;index"`
	// ExternalResourceID is the id of the object created on an external
	// system in the first phase of a two-phase approval (the Tyk api id of an
	// MCP proxy), so a retry after a partial failure does not create it twice.
	ExternalResourceID string `json:"external_resource_id" gorm:"size:255;index"`
	Status             string `json:"status" gorm:"index"` // draft | submitted | in_review | approved | rejected | changes_requested
	LockVersion        int    `json:"lock_version"`        // optimistic concurrency control

	// Update workflow: when IsUpdate is true, this submission proposes changes to an existing resource
	IsUpdate         bool  `json:"is_update"`
	TargetResourceID *uint `json:"target_resource_id"` // the existing resource being updated

	SubmitterID uint  `json:"submitter_id" gorm:"index"`
	Submitter   *User `json:"submitter,omitempty" gorm:"foreignKey:SubmitterID"`
	ReviewerID  *uint `json:"reviewer_id"`
	Reviewer    *User `json:"reviewer,omitempty" gorm:"foreignKey:ReviewerID"`

	// Resource payload — stored as JSON, used to create the actual resource on approval
	ResourcePayload JSONMap `json:"resource_payload" gorm:"type:json"`

	// Governance metadata
	Attestations         JSONMap `json:"attestations" gorm:"type:json"` // array of {template_id, accepted_at, text}
	SuggestedPrivacy     int     `json:"suggested_privacy"`
	PrivacyJustification string  `json:"privacy_justification"`

	// Support metadata
	PrimaryContact   string     `json:"primary_contact"`
	SecondaryContact string     `json:"secondary_contact"`
	SLAExpectation   string     `json:"sla_expectation"`
	DataCutoffDate   *time.Time `json:"data_cutoff_date"`
	DocumentationURL string     `json:"documentation_url"`
	Notes            string     `json:"notes"`

	// Review metadata
	ReviewNotes        string  `json:"review_notes"`        // admin-facing notes
	SubmitterFeedback  string  `json:"submitter_feedback"`  // submitter-facing feedback
	AssignedCatalogues JSONMap `json:"assigned_catalogues"` // array of catalogue IDs
	FinalPrivacyScore  *int    `json:"final_privacy_score"` // set by admin during review

	// Tracking timestamps
	SubmittedAt       *time.Time `json:"submitted_at"`
	ReviewStartedAt   *time.Time `json:"review_started_at"`
	ReviewCompletedAt *time.Time `json:"review_completed_at"`
}

func NewSubmission

func NewSubmission() *Submission

func (*Submission) AfterFind

func (s *Submission) AfterFind(tx *gorm.DB) error

AfterFind decrypts credential fields in ResourcePayload after reading from DB

func (*Submission) BeforeSave

func (s *Submission) BeforeSave(tx *gorm.DB) error

BeforeSave encrypts credential fields in ResourcePayload before writing to DB

func (*Submission) Create

func (s *Submission) Create(db *gorm.DB) error

func (*Submission) Delete

func (s *Submission) Delete(db *gorm.DB) error

func (*Submission) Get

func (s *Submission) Get(db *gorm.DB, id uint) error

func (*Submission) Update

func (s *Submission) Update(db *gorm.DB) error

func (*Submission) UpdateWithLock

func (s *Submission) UpdateWithLock(db *gorm.DB) error

UpdateWithLock performs an optimistic concurrency update. Returns an error if the lock_version has changed since the submission was read. Uses GORM's Select("*") to automatically include all struct fields — no manual map needed.

type SubmissionActivities

type SubmissionActivities []SubmissionActivity

func (*SubmissionActivities) GetBySubmission

func (a *SubmissionActivities) GetBySubmission(db *gorm.DB, submissionID uint) error

GetBySubmission retrieves all activities for a submission, ordered chronologically

type SubmissionActivity

type SubmissionActivity struct {
	gorm.Model
	ID           uint   `json:"id" gorm:"primaryKey"`
	SubmissionID uint   `json:"submission_id" gorm:"index"`
	ActorID      uint   `json:"actor_id"`
	ActorName    string `json:"actor_name"`
	ActivityType string `json:"activity_type"` // submitted, review_started, approved, rejected, changes_requested, resubmitted
	Feedback     string `json:"feedback"`      // submitter-facing feedback
	InternalNote string `json:"internal_note"` // admin-only note
}

SubmissionActivity records each action taken on a submission for audit trail purposes

func (*SubmissionActivity) Create

func (a *SubmissionActivity) Create(db *gorm.DB) error

type SubmissionVersion

type SubmissionVersion struct {
	gorm.Model
	ID            uint       `json:"id" gorm:"primaryKey"`
	SubmissionID  uint       `json:"submission_id" gorm:"index"` // FK to the update submission that triggered this snapshot
	ResourceID    uint       `json:"resource_id" gorm:"index"`
	ResourceType  string     `json:"resource_type"` // datasource | tool
	VersionNumber int        `json:"version_number"`
	Payload       JSONMap    `json:"payload" gorm:"type:json"` // snapshot of resource state before the update
	ChangedBy     uint       `json:"changed_by"`               // user who proposed the change
	ApprovedBy    uint       `json:"approved_by"`              // admin who approved
	ChangeNotes   string     `json:"change_notes"`
	RolledBackAt  *time.Time `json:"rolled_back_at"` // set if this version was restored via rollback
	RolledBackBy  *uint      `json:"rolled_back_by"` // admin who performed rollback
}

SubmissionVersion stores a snapshot of a resource's state before an update is applied. This enables rollback to any previous version.

func NewSubmissionVersion

func NewSubmissionVersion() *SubmissionVersion

func (*SubmissionVersion) Create

func (v *SubmissionVersion) Create(db *gorm.DB) error

func (*SubmissionVersion) Get

func (v *SubmissionVersion) Get(db *gorm.DB, id uint) error

type SubmissionVersions

type SubmissionVersions []SubmissionVersion

func (*SubmissionVersions) GetByResource

func (v *SubmissionVersions) GetByResource(db *gorm.DB, resourceType string, resourceID uint) error

GetByResource retrieves all versions for a specific resource, ordered by version number descending

func (*SubmissionVersions) GetBySubmission

func (v *SubmissionVersions) GetBySubmission(db *gorm.DB, submissionID uint) error

GetBySubmission retrieves all versions created by a specific update submission

type Submissions

type Submissions []Submission

func (*Submissions) GetAll

func (s *Submissions) GetAll(db *gorm.DB, status, resourceType string, pageSize, pageNumber int) (int64, int, error)

GetAll retrieves all submissions with optional filters (for admin)

func (*Submissions) GetBySubmitter

func (s *Submissions) GetBySubmitter(db *gorm.DB, submitterID uint, status string, pageSize, pageNumber int) (int64, int, error)

GetBySubmitter retrieves all submissions for a specific user

type SyncAuditLog

type SyncAuditLog struct {
	gorm.Model
	EventType     string  `gorm:"size:50;not null;index" json:"event_type"`
	Namespace     string  `gorm:"size:255;not null;index" json:"namespace"`
	EdgeID        *string `gorm:"size:255;index" json:"edge_id,omitempty"`
	Checksum      string  `gorm:"size:64" json:"checksum"`
	ConfigVersion string  `gorm:"size:64" json:"config_version"`
	Details       string  `gorm:"type:text" json:"details"`
}

SyncAuditLog tracks sync events between control plane and edge gateways

func (*SyncAuditLog) CleanupOldLogs

func (s *SyncAuditLog) CleanupOldLogs(db *gorm.DB, daysToKeep int) error

CleanupOldLogs removes audit logs older than the specified number of days

func (*SyncAuditLog) Create

func (s *SyncAuditLog) Create(db *gorm.DB) error

Create creates a new sync audit log entry

func (*SyncAuditLog) GetByEdgeID

func (s *SyncAuditLog) GetByEdgeID(db *gorm.DB, edgeID string, limit int) ([]SyncAuditLog, error)

GetByEdgeID retrieves audit logs for a specific edge

func (*SyncAuditLog) GetByNamespace

func (s *SyncAuditLog) GetByNamespace(db *gorm.DB, namespace string, limit int) ([]SyncAuditLog, error)

GetByNamespace retrieves audit logs for a specific namespace

func (*SyncAuditLog) GetFiltered

func (s *SyncAuditLog) GetFiltered(db *gorm.DB, namespace, edgeID, eventType string, limit int) ([]SyncAuditLog, error)

GetFiltered retrieves audit logs with optional filters

func (*SyncAuditLog) GetRecent

func (s *SyncAuditLog) GetRecent(db *gorm.DB, limit int) ([]SyncAuditLog, error)

GetRecent retrieves the most recent audit logs

func (SyncAuditLog) TableName

func (SyncAuditLog) TableName() string

TableName specifies the table name for the SyncAuditLog model

type Tag

type Tag struct {
	gorm.Model
	ID   uint   `json:"id" gorm:"primaryKey"`
	Name string `json:"name"`
}

func NewTag

func NewTag() *Tag

func (*Tag) Create

func (t *Tag) Create(db *gorm.DB) error

Create a new tag

func (*Tag) Delete

func (t *Tag) Delete(db *gorm.DB) error

Delete a tag

func (*Tag) Get

func (t *Tag) Get(db *gorm.DB, id uint) error

Get a tag by ID

func (*Tag) GetByName

func (t *Tag) GetByName(db *gorm.DB, name string) error

Get tag by exact name

func (*Tag) Update

func (t *Tag) Update(db *gorm.DB) error

Update an existing tag

type Tags

type Tags []Tag

func (*Tags) GetAll

func (t *Tags) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool) (int64, int, error)

Get all tags

func (*Tags) GetByNameStub

func (t *Tags) GetByNameStub(db *gorm.DB, stub string) error

Get tags by name stub

type TeamBudget

type TeamBudget struct {
	ID                   uint       `json:"id" gorm:"primaryKey"`
	GroupID              uint       `json:"group_id" gorm:"not null;uniqueIndex"`
	MonthlyBudget        *float64   `json:"monthly_budget"`
	BudgetStartDate      *time.Time `json:"budget_start_date"`
	DefaultAppAllocation *float64   `json:"default_app_allocation"`
	Enforcement          string     `json:"enforcement" gorm:"size:16;not null;default:'alert_only'"`
	CreatedAt            time.Time  `json:"created_at"`
	UpdatedAt            time.Time  `json:"updated_at"`
}

TeamBudget holds the budget of one team (Group). Enterprise; the table exists in CE and is used there for nothing but reporting.

MonthlyBudget semantics (as for App and LLM budgets, nil is "no limit" and 0 is zero):

  • no row, or a nil budget: the team is unmanaged (no pool, no ceiling);
  • 0: an empty pool and a zero ceiling; new Apps are allocated nothing;
  • > 0: the pool Apps draw from, and the ceiling on the team's total spend.

No gorm.Model: the row is deleted outright with its team, so a soft-delete tombstone can never block the unique group_id of a recreated row.

func GetTeamBudget

func GetTeamBudget(db *gorm.DB, groupID uint) (*TeamBudget, error)

GetTeamBudget returns the budget row of a team, or nil when it has none.

func (*TeamBudget) HardBlocks

func (tb *TeamBudget) HardBlocks() bool

HardBlocks reports whether reaching the budget refuses the team's Apps.

func (*TeamBudget) IsManaged

func (tb *TeamBudget) IsManaged() bool

IsManaged reports whether the team has a budget at all.

type TeamBudgetSettings

type TeamBudgetSettings struct {
	ID      uint `gorm:"primaryKey"`
	Enabled bool `gorm:"not null;default:false"`
	// AttributionBackfilled records that apps and spend recorded before
	// team attribution existed have been stamped with their team.
	AttributionBackfilled bool `gorm:"not null;default:false"`
	// ZeroBudgetsCleared records that App and LLM budgets of 0, which meant
	// "no limit" before 0 came to mean zero, were rewritten to nil.
	ZeroBudgetsCleared bool `gorm:"not null;default:false"`
	UpdatedAt          time.Time
}

TeamBudgetSettings is the single row holding the global team budget switch. While the switch is off, Apps and spend are still attributed to teams (for reporting) but nothing is allocated or enforced.

func GetTeamBudgetSettings

func GetTeamBudgetSettings(db *gorm.DB) (*TeamBudgetSettings, error)

GetTeamBudgetSettings returns the settings row, or the zero value (switch off) when it has never been written.

type TeamCostRow

type TeamCostRow struct {
	TeamID   uint    `json:"team_id"`
	TeamName string  `json:"team_name"`
	Cost     float64 `json:"cost"`
	Tokens   int64   `json:"tokens"`
	Requests int64   `json:"requests"`
	// Deleted marks a team deleted since it spent: its name may since have
	// been reused, and it has no page to link to.
	Deleted bool `json:"deleted,omitempty"`
}

TeamCostRow is one team's spend over a reporting window.

type TokenTotals

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

TokenTotals keeps running sums of llm_chat_records.total_tokens, overall and per interaction type, for usage telemetry.

Telemetry used to run SUM(total_tokens) over the whole table three times at start-up and every hour. At ~100M rows each sum is a full scan of the largest table, which on a busy hub kept the database busy for minutes. The tracker sums the table once, in one grouped pass, and afterwards reads only the rows added since, found by id. This relies on llm_chat_records rows being insert-only (see LLMChatRecord).

Rows are folded into the settled totals only once they have been visible for tokenTotalsSettleAfter, and until then are summed afresh on each read, so a row whose transaction commits after rows with higher ids (several hub replicas writing to one database) is still counted if it commits within that window.

func NewTokenTotals

func NewTokenTotals() *TokenTotals

NewTokenTotals returns an empty tracker.

func (*TokenTotals) Read

func (t *TokenTotals) Read(db *gorm.DB) (all int64, byType map[InteractionType]int64, err error)

Read returns the tokens of every llm_chat_records row, overall and by interaction type.

type Tool

type Tool struct {
	gorm.Model
	ID          uint   `json:"id" gorm:"primary_key"`
	Name        string `json:"name" gorm:"index"`
	Slug        string `json:"slug" gorm:"index"`
	Description string `json:"description"`

	ToolType            string `json:"tool_type"`
	OASSpec             string `json:"oas_spec"`
	AvailableOperations string `json:"available_operations"`
	PrivacyScore        int    `json:"privacy_score"`
	AuthKey             string `json:"auth_key"`
	AuthSchemaName      string `json:"auth_schema_name"`
	Active              bool   `json:"active" gorm:"default:true"`
	Namespace           string `json:"namespace" gorm:"default:'';index:idx_tool_namespace"`

	// Access methods. A tool is first of all a chat capability; reaching it
	// from an App over REST or MCP on the gateway is optional and switched per
	// tool. The columns are stored inverted so the zero value means "enabled":
	// rows that predate the switches, and config pushed by a hub that does not
	// know them, keep today's behaviour. New tools get their default in
	// services.CreateToolWithDB (see DefaultToolRESTAccessEnabled). Read them
	// through RESTAccessEnabled / MCPAccessEnabled, never directly.
	RESTAccessDisabled bool `json:"rest_access_disabled" gorm:"not null;default:false"`
	MCPAccessDisabled  bool `json:"mcp_access_disabled" gorm:"not null;default:false"`

	FileStores   []FileStore `gorm:"many2many:tool_filestores;" json:"file_stores"`
	Filters      []Filter    `gorm:"many2many:tool_filters;" json:"filters"`
	Dependencies []*Tool     `gorm:"many2many:tool_dependencies" json:"dependencies"`
	Apps         []*App      `gorm:"many2many:app_tools;" json:"apps"`

	// Ownership
	UserID uint `json:"user_id" gorm:"index:idx_tool_user_community"`

	// UGC (User-Generated Content) fields
	CommunitySubmitted bool  `json:"community_submitted" gorm:"index:idx_tool_user_community"`
	SubmissionID       *uint `json:"submission_id"`

	// Plugin-stored metadata
	Metadata JSONMap `json:"metadata" gorm:"type:json"`
}

func NewTool

func NewTool() *Tool

func (*Tool) AddDependency

func (t *Tool) AddDependency(db *gorm.DB, dependency *Tool) error

func (*Tool) AddFileStore

func (t *Tool) AddFileStore(db *gorm.DB, fileStore *FileStore) error

AddFileStore adds a FileStore to the Tool

func (*Tool) AddFilter

func (t *Tool) AddFilter(db *gorm.DB, filter *Filter) error

AddFilter adds a Filter to the Tool

func (*Tool) AddOperation

func (t *Tool) AddOperation(operation string)

AddOperation adds a new operation to the AvailableOperations list

func (*Tool) AfterDelete

func (t *Tool) AfterDelete(tx *gorm.DB) error

AfterDelete drops the tool's secret references.

func (*Tool) AfterSave

func (t *Tool) AfterSave(tx *gorm.DB) error

AfterSave keeps the secret_references rows for this tool current.

func (*Tool) AllowsOperation

func (t *Tool) AllowsOperation(operationID string) bool

AllowsOperation reports whether operationID is on the tool's whitelist. An empty whitelist allows nothing, which is what chat and the MCP endpoint already do.

func (*Tool) AppGrantable

func (t *Tool) AppGrantable() bool

AppGrantable reports whether binding the tool to an App gives the App anything: a chat-only tool has no endpoint an App credential could unlock.

func (*Tool) BeforeSave

func (t *Tool) BeforeSave(tx *gorm.DB) error

BeforeSave computes the slug from the tool name before saving

func (*Tool) ClearDependencies

func (t *Tool) ClearDependencies(db *gorm.DB) error

ClearDependencies removes all Tool dependencies

func (*Tool) ClientDefinition

func (t *Tool) ClientDefinition() (*ClientToolDefinition, error)

ClientDefinition parses the tool's client-tool definition. Missing pieces get usable defaults: an empty object schema and an approval UI.

func (*Tool) ClientOperation

func (t *Tool) ClientOperation() string

ClientOperation is the function name the model sees for a client tool: the first configured operation, else the tool's slug.

func (*Tool) Create

func (t *Tool) Create(db *gorm.DB) error

Create a new tool

func (*Tool) Delete

func (t *Tool) Delete(db *gorm.DB) error

Delete a tool

func (*Tool) Get

func (t *Tool) Get(db *gorm.DB, id uint) error

Get a tool by ID

func (*Tool) GetByName

func (t *Tool) GetByName(db *gorm.DB, name string) error

GetByName gets a tool by its name

func (*Tool) GetDependencies

func (t *Tool) GetDependencies(db *gorm.DB) ([]*Tool, error)

GetDependencies gets all Tool dependencies

func (*Tool) GetFileStores

func (t *Tool) GetFileStores(db *gorm.DB) ([]FileStore, error)

GetFileStores gets all FileStores associated with the Tool

func (*Tool) GetFilters

func (t *Tool) GetFilters(db *gorm.DB) ([]Filter, error)

GetFilters gets all Filters associated with the Tool

func (*Tool) GetOperations

func (t *Tool) GetOperations() []string

GetOperations returns the AvailableOperations as a []string

func (*Tool) HasDependency

func (t *Tool) HasDependency(db *gorm.DB, dependencyID uint) (bool, error)

HasDependency checks if a specific Tool is a dependency

func (*Tool) MCPAccessEnabled

func (t *Tool) MCPAccessEnabled() bool

MCPAccessEnabled reports whether Apps may reach the tool's MCP endpoint (/tools/{slug}/mcp and its SSE transport).

func (*Tool) RESTAccessEnabled

func (t *Tool) RESTAccessEnabled() bool

RESTAccessEnabled reports whether Apps may call the tool on /tools/{slug}.

func (*Tool) RemoveDependency

func (t *Tool) RemoveDependency(db *gorm.DB, dependency *Tool) error

RemoveDependency removes a Tool dependency

func (*Tool) RemoveFileStore

func (t *Tool) RemoveFileStore(db *gorm.DB, fileStore *FileStore) error

RemoveFileStore removes a FileStore from the Tool

func (*Tool) RemoveFilter

func (t *Tool) RemoveFilter(db *gorm.DB, filter *Filter) error

RemoveFilter removes a Filter from the Tool

func (*Tool) RemoveOperation

func (t *Tool) RemoveOperation(operation string)

RemoveOperation removes an operation from the AvailableOperations list

func (*Tool) SetDependencies

func (t *Tool) SetDependencies(db *gorm.DB, dependencies []*Tool) error

SetDependencies replaces all existing Tool dependencies with new ones

func (*Tool) SetFileStores

func (t *Tool) SetFileStores(db *gorm.DB, fileStores []FileStore) error

SetFileStores replaces all existing FileStore associations with new ones

func (*Tool) SetFilters

func (t *Tool) SetFilters(db *gorm.DB, filters []Filter) error

SetFilters replaces all existing Filter associations with new ones

func (*Tool) Update

func (t *Tool) Update(db *gorm.DB) error

Update an existing tool

func (*Tool) WouldCreateCircularDependency

func (t *Tool) WouldCreateCircularDependency(db *gorm.DB, newDependency *Tool) (bool, error)

Would create a circular dependency checks if adding this dependency would create a circular reference

type ToolCallRecord

type ToolCallRecord struct {
	gorm.Model
	ID        uint `gorm:"primaryKey"`
	ToolID    uint
	Name      string
	ExecTime  int
	TimeStamp time.Time
}

records tool usage

type ToolCatalogue

type ToolCatalogue struct {
	gorm.Model
	ID               uint   `json:"id" gorm:"primaryKey"`
	Name             string `json:"name"`
	ShortDescription string `json:"short_description"`
	LongDescription  string `json:"long_description"`
	Icon             string `json:"icon"`
	Tools            []Tool `json:"tools" gorm:"many2many:tool_catalogue_tools;"`
	// Tyk-managed MCP servers (Enterprise) share the tool catalogues.
	MCPServers []MCPServer `json:"-" gorm:"many2many:tool_catalogue_mcp_servers;"`
	Tags       []Tag       `json:"tags" gorm:"many2many:tool_catalogue_tags;"`
}

func GetOrCreateDefaultToolCatalogue

func GetOrCreateDefaultToolCatalogue(db *gorm.DB) (*ToolCatalogue, error)

GetOrCreateDefaultToolCatalogue finds or creates the Default tool catalogue by name This is safe for databases where auto-increment has been reset or cleared

func NewToolCatalogue

func NewToolCatalogue() *ToolCatalogue

func (*ToolCatalogue) AddTag

func (tc *ToolCatalogue) AddTag(db *gorm.DB, tag *Tag) error

Add a tag to the tool catalogue

func (*ToolCatalogue) AddTool

func (tc *ToolCatalogue) AddTool(db *gorm.DB, tool *Tool) error

Add a tool to the tool catalogue

func (*ToolCatalogue) Create

func (tc *ToolCatalogue) Create(db *gorm.DB) error

Create a new tool catalogue

func (*ToolCatalogue) Delete

func (tc *ToolCatalogue) Delete(db *gorm.DB) error

Delete a tool catalogue

func (*ToolCatalogue) Get

func (tc *ToolCatalogue) Get(db *gorm.DB, id uint) error

Get a tool catalogue by ID

func (*ToolCatalogue) IsDefault

func (tc *ToolCatalogue) IsDefault() bool

IsDefault checks if this tool catalogue is the default tool catalogue

func (*ToolCatalogue) RemoveTag

func (tc *ToolCatalogue) RemoveTag(db *gorm.DB, tag *Tag) error

Remove a tag from the tool catalogue

func (*ToolCatalogue) RemoveTool

func (tc *ToolCatalogue) RemoveTool(db *gorm.DB, tool *Tool) error

Remove a tool from the tool catalogue

func (*ToolCatalogue) Update

func (tc *ToolCatalogue) Update(db *gorm.DB) error

Update an existing tool catalogue

type ToolCatalogues

type ToolCatalogues []ToolCatalogue

func (*ToolCatalogues) GetAll

func (tc *ToolCatalogues) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

Get all tool catalogues

func (*ToolCatalogues) GetByTag

func (tc *ToolCatalogues) GetByTag(db *gorm.DB, tagName string) error

Get tool catalogues by tag

func (*ToolCatalogues) GetByTool

func (tc *ToolCatalogues) GetByTool(db *gorm.DB, toolID uint) error

Get tool catalogues by tool

func (*ToolCatalogues) Search

func (tc *ToolCatalogues) Search(db *gorm.DB, query string) error

Search tool catalogues by name, short description, and long description

type ToolResult

type ToolResult struct {
	ToolCallID string
	Result     string
	IsError    bool
}

ToolResult is a client-side (human-in-the-loop) tool outcome supplied by the browser for a tool call the session parked.

type Tools

type Tools []Tool

func (*Tools) GetAll

func (t *Tools) GetAll(db *gorm.DB, pageSize int, pageNumber int, all bool, scopes ...func(*gorm.DB) *gorm.DB) (int64, int, error)

GetAll retrieves all tools

func (*Tools) GetByPrivacyScoreMax

func (t *Tools) GetByPrivacyScoreMax(db *gorm.DB, maxScore int) error

GetByPrivacyScoreMax retrieves all tools with a privacy score less than or equal to the given maximum

func (*Tools) GetByPrivacyScoreMin

func (t *Tools) GetByPrivacyScoreMin(db *gorm.DB, minScore int) error

GetByPrivacyScoreMin retrieves all tools with a privacy score greater than or equal to the given minimum

func (*Tools) GetByPrivacyScoreRange

func (t *Tools) GetByPrivacyScoreRange(db *gorm.DB, minScore, maxScore int) error

GetByPrivacyScoreRange retrieves all tools with a privacy score within the given range

func (*Tools) GetByType

func (t *Tools) GetByType(db *gorm.DB, toolType string) error

GetByType retrieves all tools of a specific type

func (*Tools) Search

func (t *Tools) Search(db *gorm.DB, query string) error

Search retrieves all tools matching the given query in name or description

type TykCapability

type TykCapability struct {
	State     string     `json:"state"`
	Detail    string     `json:"detail,omitempty"`
	CheckedAt *time.Time `json:"checked_at,omitempty"`
}

TykCapability is one probed capability.

type TykConnection

type TykConnection struct {
	gorm.Model
	Name        string `gorm:"size:200;not null" json:"name"`
	Description string `gorm:"size:1024" json:"description"`

	DashboardURL   string `gorm:"size:2048;not null" json:"dashboard_url"`
	GatewayBaseURL string `gorm:"size:2048" json:"gateway_base_url"`
	// TemplateID names a Dashboard API template asset (kind oas-template)
	// merged into every MCP proxy AI Studio creates on this connection, so
	// the API team's governance defaults (logging, caching, middleware,
	// tags) apply to community and Studio registrations alike.
	TemplateID string `gorm:"size:255" json:"template_id"`
	// DashboardAccessToken is the Dashboard user's API access key. Encrypted.
	DashboardAccessToken string `gorm:"type:text" json:"-"`
	OrgID                string `gorm:"size:64" json:"org_id"`

	DeclaredMode  string `gorm:"size:16;not null;default:catalogue" json:"declared_mode"`
	EffectiveMode string `gorm:"size:16;not null;default:catalogue" json:"effective_mode"`
	// CapabilitiesJSON is a JSON object of capability name -> TykCapability.
	CapabilitiesJSON string `gorm:"column:capabilities;type:text" json:"-"`

	Status         string `gorm:"size:16;index;not null;default:pending" json:"status"`
	Degraded       bool   `json:"degraded"`
	DegradedReason string `gorm:"size:1024" json:"degraded_reason"`

	SyncIntervalSeconds int        `gorm:"not null;default:300" json:"sync_interval_seconds"`
	NextSyncAt          *time.Time `gorm:"index" json:"next_sync_at"`
	SyncLeaseOwner      string     `gorm:"size:255" json:"-"`
	SyncLeaseUntil      *time.Time `json:"-"`

	AutoPublish         bool `json:"auto_publish"`
	DefaultPrivacyScore *int `json:"default_privacy_score"`
	AcceptHandoffs      bool `gorm:"not null;default:true" json:"accept_handoffs"`

	// KeyDefaultsJSON holds TykKeyDefaults.
	KeyDefaultsJSON string `gorm:"column:key_defaults;type:text" json:"-"`

	AllowInternalHost bool `json:"allow_internal_host"`

	// Optional MDCB section for gateway segmentation discovery.
	MDCBURL               string `gorm:"size:2048" json:"mdcb_url"`
	MDCBAccessToken       string `gorm:"type:text" json:"-"`
	MDCBAllowInternalHost bool   `json:"mdcb_allow_internal_host"`
	// KnownGatewayTagsJSON holds []TykGatewayTag maintained by administrators.
	KnownGatewayTagsJSON string `gorm:"column:known_gateway_tags;type:text" json:"-"`
	// GatewayBaseURLsJSON holds map[tag]url.
	GatewayBaseURLsJSON string `gorm:"column:gateway_base_urls;type:text" json:"-"`
	// DataPlanesJSON holds []TykDataPlane, the sanitised MDCB snapshot.
	DataPlanesJSON string `gorm:"column:data_planes;type:text" json:"-"`

	LastSyncAt      *time.Time `json:"last_sync_at"`
	LastSyncStatus  string     `gorm:"size:16" json:"last_sync_status"`
	LastSyncError   string     `gorm:"size:2048" json:"last_sync_error"`
	LastProbeAt     *time.Time `json:"last_probe_at"`
	LastMDCBProbeAt *time.Time `json:"last_mdcb_probe_at"`

	CreatedByUserID   uint       `json:"created_by_user_id"`
	CreatedByEmail    string     `gorm:"size:255" json:"created_by_email"`
	ActivatedByUserID uint       `json:"activated_by_user_id"`
	ActivatedByEmail  string     `gorm:"size:255" json:"activated_by_email"`
	ActivatedAt       *time.Time `json:"activated_at"`

	LockVersion int `gorm:"not null;default:0" json:"lock_version"`

	// HostKey marks the connection the host application AI Studio is
	// embedded in provides (pkg/studio Options.HostTykConnection). Every
	// replica upserts it under this key; its Dashboard URL, organisation,
	// mode and gateway URL are the host's, and its Dashboard key is asked of
	// the host on each use, never stored. Nil for the connections
	// administrators create.
	HostKey *string `gorm:"size:64;uniqueIndex" json:"-"`
}

TykConnection is one Tyk Dashboard (one organisation) that AI Studio imports MCP proxies from, registers MCP proxies into, and brokers access keys against.

Secret-bearing columns carry "token" in their name so the audit trail's built-in redaction masks them in diffs, and they are encrypted at rest by the BeforeSave/AfterFind hooks, which refuse to save without the key.

func (*TykConnection) AfterFind

func (t *TykConnection) AfterFind(tx *gorm.DB) error

AfterFind decrypts the access tokens.

func (*TykConnection) AfterSave

func (t *TykConnection) AfterSave(tx *gorm.DB) error

AfterSave restores plaintext on the in-memory struct.

func (*TykConnection) AllGatewayTags

func (t *TykConnection) AllGatewayTags() []string

AllGatewayTags is the union of MDCB-discovered and administrator-known tags.

func (*TykConnection) BeforeSave

func (t *TykConnection) BeforeSave(tx *gorm.DB) error

BeforeSave encrypts the access tokens. It refuses to save a plaintext token when the encryption key is not configured rather than falling back to plaintext storage.

func (*TykConnection) Capabilities

func (t *TykConnection) Capabilities() map[string]TykCapability

Capabilities decodes the probe results.

func (*TykConnection) DataPlanes

func (t *TykConnection) DataPlanes() []TykDataPlane

DataPlanes decodes the sanitised MDCB snapshot.

func (*TykConnection) GatewayBaseURLs

func (t *TykConnection) GatewayBaseURLs() map[string]string

GatewayBaseURLs decodes the per-tag public base URLs.

func (*TykConnection) HasMDCB

func (t *TykConnection) HasMDCB() bool

HasMDCB reports whether the MDCB section is configured.

func (*TykConnection) HostManaged

func (t *TykConnection) HostManaged() bool

HostManaged reports whether the host application provides the connection.

func (*TykConnection) IsUsable

func (t *TykConnection) IsUsable() bool

IsUsable reports whether Studio may call the Dashboard for this connection.

func (*TykConnection) KeyDefaults

func (t *TykConnection) KeyDefaults() TykKeyDefaults

KeyDefaults decodes the key defaults.

func (*TykConnection) KnownGatewayTags

func (t *TykConnection) KnownGatewayTags() []TykGatewayTag

KnownGatewayTags decodes the administrator-maintained tags.

func (*TykConnection) SetCapabilities

func (t *TykConnection) SetCapabilities(c map[string]TykCapability)

SetCapabilities encodes the probe results.

func (*TykConnection) SetDataPlanes

func (t *TykConnection) SetDataPlanes(d []TykDataPlane)

SetDataPlanes encodes the sanitised MDCB snapshot.

func (*TykConnection) SetGatewayBaseURLs

func (t *TykConnection) SetGatewayBaseURLs(m map[string]string)

SetGatewayBaseURLs encodes the per-tag public base URLs.

func (*TykConnection) SetKeyDefaults

func (t *TykConnection) SetKeyDefaults(d TykKeyDefaults)

SetKeyDefaults encodes the key defaults.

func (*TykConnection) SetKnownGatewayTags

func (t *TykConnection) SetKnownGatewayTags(tags []TykGatewayTag)

SetKnownGatewayTags encodes the administrator-maintained tags.

func (TykConnection) TableName

func (TykConnection) TableName() string

func (*TykConnection) ToResponse

func (t *TykConnection) ToResponse() TykConnectionResponse

ToResponse converts the connection to its API shape, dropping every secret.

type TykConnectionResponse

type TykConnectionResponse struct {
	ID                  uint                     `json:"id"`
	Name                string                   `json:"name"`
	Description         string                   `json:"description"`
	DashboardURL        string                   `json:"dashboard_url"`
	GatewayBaseURL      string                   `json:"gateway_base_url"`
	TemplateID          string                   `json:"template_id"`
	HasToken            bool                     `json:"has_token"`
	TokenHint           string                   `json:"token_hint,omitempty"`
	OrgID               string                   `json:"org_id"`
	DeclaredMode        string                   `json:"declared_mode"`
	EffectiveMode       string                   `json:"effective_mode"`
	Capabilities        map[string]TykCapability `json:"capabilities"`
	Status              string                   `json:"status"`
	Degraded            bool                     `json:"degraded"`
	DegradedReason      string                   `json:"degraded_reason,omitempty"`
	SyncIntervalSeconds int                      `json:"sync_interval_seconds"`
	NextSyncAt          *time.Time               `json:"next_sync_at,omitempty"`
	AutoPublish         bool                     `json:"auto_publish"`
	DefaultPrivacyScore *int                     `json:"default_privacy_score"`
	AcceptHandoffs      bool                     `json:"accept_handoffs"`
	KeyDefaults         TykKeyDefaults           `json:"key_defaults"`
	AllowInternalHost   bool                     `json:"allow_internal_host"`
	MDCBURL             string                   `json:"mdcb_url"`
	HasMDCBToken        bool                     `json:"has_mdcb_token"`
	MDCBAllowInternal   bool                     `json:"mdcb_allow_internal_host"`
	KnownGatewayTags    []TykGatewayTag          `json:"known_gateway_tags"`
	GatewayBaseURLs     map[string]string        `json:"gateway_base_urls"`
	DataPlanes          []TykDataPlane           `json:"data_planes"`
	GatewayTags         []string                 `json:"gateway_tags"`
	LastSyncAt          *time.Time               `json:"last_sync_at,omitempty"`
	LastSyncStatus      string                   `json:"last_sync_status,omitempty"`
	LastSyncError       string                   `json:"last_sync_error,omitempty"`
	LastProbeAt         *time.Time               `json:"last_probe_at,omitempty"`
	LastMDCBProbeAt     *time.Time               `json:"last_mdcb_probe_at,omitempty"`
	CreatedByUserID     uint                     `json:"created_by_user_id"`
	CreatedByEmail      string                   `json:"created_by_email"`
	ActivatedByUserID   uint                     `json:"activated_by_user_id"`
	ActivatedByEmail    string                   `json:"activated_by_email"`
	ActivatedAt         *time.Time               `json:"activated_at,omitempty"`
	LockVersion         int                      `json:"lock_version"`
	HostManaged         bool                     `json:"host_managed"`
	CreatedAt           time.Time                `json:"created_at"`
	UpdatedAt           time.Time                `json:"updated_at"`
}

TykConnectionResponse is the API shape of a connection. Tokens are never included; a presence flag and a last-four hint replace them.

type TykDataPlane

type TykDataPlane struct {
	GroupID      string    `json:"group_id"`
	Tags         []string  `json:"tags"`
	NodeCount    int       `json:"node_count"`
	NodeVersions []string  `json:"node_versions"`
	Healthy      bool      `json:"healthy"`
	LastSeen     time.Time `json:"last_seen"`
}

TykDataPlane is the sanitised view of one MDCB data plane group. The MDCB response also carries each node's gateway api_key; it is never stored.

type TykGatewayTag

type TykGatewayTag struct {
	Tag         string `json:"tag"`
	Label       string `json:"label,omitempty"`
	Description string `json:"description,omitempty"`
}

TykGatewayTag is an administrator-maintained segmentation tag.

type TykKeyDefaults

type TykKeyDefaults struct {
	ExpiresInSeconds  int64  `json:"expires_in_seconds"`
	AliasPrefix       string `json:"alias_prefix"`
	DetailedRecording bool   `json:"detailed_recording"`
}

TykKeyDefaults are applied to every key minted on the connection.

type TykPolicy

type TykPolicy struct {
	gorm.Model
	ConnectionID uint   `gorm:"index;uniqueIndex:idx_tyk_policies_conn_pol" json:"connection_id"`
	TykPolicyID  string `gorm:"size:64;uniqueIndex:idx_tyk_policies_conn_pol" json:"tyk_policy_id"`
	Name         string `gorm:"size:255" json:"name"`
	Active       bool   `json:"active"`
	IsInactive   bool   `json:"is_inactive"`
	// PartitionsJSON holds TykPolicyPartitions.
	PartitionsJSON string `gorm:"column:partitions;type:text" json:"-"`
	TagsJSON       string `gorm:"column:tags;type:text" json:"-"`
	KeyExpiresIn   int64  `json:"key_expires_in"`
	// MCPAPIIDsJSON lists the MCP proxy ids in access_rights.
	MCPAPIIDsJSON string `gorm:"column:mcp_api_ids;type:text" json:"-"`
	// APIIDsJSON lists every api id in access_rights (MCP or not).
	APIIDsJSON     string     `gorm:"column:api_ids;type:text" json:"-"`
	IsPartitioned  bool       `json:"is_partitioned"`
	HasACL         bool       `json:"has_acl"`
	HasRateLimit   bool       `json:"has_rate_limit"`
	HasQuota       bool       `json:"has_quota"`
	HasComplexity  bool       `json:"has_complexity"`
	HasPerAPI      bool       `json:"has_per_api"`
	StudioManaged  bool       `json:"studio_managed"`
	Raw            string     `gorm:"type:text" json:"-"`
	DashboardState string     `gorm:"size:16;not null;default:present" json:"dashboard_state"`
	LastSeenAt     *time.Time `json:"last_seen_at"`
}

TykPolicy is a read-mostly cache of a Tyk security policy, refreshed on every sync. The full JSON is admin-only.

func (*TykPolicy) APIIDs

func (p *TykPolicy) APIIDs() []string

APIIDs decodes every api id the policy grants.

func (*TykPolicy) GrantsAPI

func (p *TykPolicy) GrantsAPI(apiID string) bool

GrantsAPI reports whether the policy's access rights name the api id.

func (*TykPolicy) IsAllInOne

func (p *TykPolicy) IsAllInOne() bool

IsAllInOne reports a non-partitioned policy (ACL and limits together).

func (*TykPolicy) MCPAPIIDs

func (p *TykPolicy) MCPAPIIDs() []string

MCPAPIIDs decodes the MCP proxy ids the policy grants.

func (*TykPolicy) Partitions

func (p *TykPolicy) Partitions() TykPolicyPartitions

Partitions decodes the partition flags.

func (*TykPolicy) SetAPIIDs

func (p *TykPolicy) SetAPIIDs(ids []string)

SetAPIIDs encodes every api id the policy grants.

func (*TykPolicy) SetMCPAPIIDs

func (p *TykPolicy) SetMCPAPIIDs(ids []string)

SetMCPAPIIDs encodes the MCP proxy ids the policy grants.

func (*TykPolicy) SetPartitions

func (p *TykPolicy) SetPartitions(part TykPolicyPartitions)

SetPartitions encodes the partition flags and the denormalised columns.

func (*TykPolicy) SetTags

func (p *TykPolicy) SetTags(tags []string)

SetTags encodes the policy tags.

func (TykPolicy) TableName

func (TykPolicy) TableName() string

func (*TykPolicy) Tags

func (p *TykPolicy) Tags() []string

Tags decodes the policy tags.

func (*TykPolicy) ToResponse

func (p *TykPolicy) ToResponse(detail bool) TykPolicyResponse

ToResponse converts the policy to its API shape; raw is included on detail.

type TykPolicyPartitions

type TykPolicyPartitions struct {
	ACL        bool `json:"acl"`
	RateLimit  bool `json:"rate_limit"`
	Quota      bool `json:"quota"`
	Complexity bool `json:"complexity"`
	PerAPI     bool `json:"per_api"`
}

TykPolicyPartitions mirrors a policy's partitions object.

type TykPolicyResponse

type TykPolicyResponse struct {
	ID             uint                `json:"id"`
	ConnectionID   uint                `json:"connection_id"`
	TykPolicyID    string              `json:"tyk_policy_id"`
	Name           string              `json:"name"`
	Active         bool                `json:"active"`
	IsInactive     bool                `json:"is_inactive"`
	Partitions     TykPolicyPartitions `json:"partitions"`
	IsPartitioned  bool                `json:"is_partitioned"`
	Tags           []string            `json:"tags"`
	KeyExpiresIn   int64               `json:"key_expires_in"`
	MCPAPIIDs      []string            `json:"mcp_api_ids"`
	APIIDs         []string            `json:"api_ids"`
	StudioManaged  bool                `json:"studio_managed"`
	DashboardState string              `json:"dashboard_state"`
	LastSeenAt     *time.Time          `json:"last_seen_at,omitempty"`
	Raw            json.RawMessage     `json:"raw,omitempty"`
}

TykPolicyResponse is the administrator API shape of a cached policy.

type UIMount

type UIMount struct {
	Kind  string                 `json:"kind"`            // "webc", "module-federation", "iframe"
	Tag   string                 `json:"tag,omitempty"`   // Web component tag name
	Entry string                 `json:"entry,omitempty"` // Entry point file
	Props map[string]interface{} `json:"props,omitempty"` // Props to pass to component

	// RequiredPermission is the RBAC permission an administrator needs to
	// see and open this page ("resource:action"). Plugin-relative forms are
	// accepted: "read" means the plugin's own base resource, "assets:write"
	// one of its declared sub-resources. Default: the plugin's base read.
	RequiredPermission string `json:"required_permission,omitempty"`

	// Module Federation specific
	Remote  string `json:"remote,omitempty"`  // Remote entry point for MF
	Exposed string `json:"exposed,omitempty"` // Exposed module name

	// iFrame specific
	App string `json:"app,omitempty"` // App HTML file for iframe
}

UIMount defines how a UI component should be mounted

type UIRegistry

type UIRegistry struct {
	gorm.Model
	PluginID      uint                   `json:"plugin_id" gorm:"index;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	SlotType      string                 `json:"slot_type" gorm:"size:100"` // e.g., "sidebar.section"
	RoutePattern  string                 `json:"route_pattern" gorm:"size:255"`
	ComponentTag  string                 `json:"component_tag" gorm:"size:100"`
	EntryPoint    string                 `json:"entry_point" gorm:"size:500"`
	MountConfig   map[string]interface{} `json:"mount_config" gorm:"serializer:json"`
	IsActive      bool                   `json:"is_active" gorm:"default:true"`
	LoadPriority  int                    `json:"load_priority" gorm:"default:0"`
	Scope         string                 `json:"scope" gorm:"size:20;default:admin"`    // "admin" or "portal"
	AllowedGroups []string               `json:"allowed_groups" gorm:"serializer:json"` // Empty = all users (portal scope only)
	// RequiredPermission is computed when the registry is served (admin
	// scope): mount_config.required_permission resolved against the plugin,
	// or the plugin's base read permission. Not stored.
	RequiredPermission string `json:"required_permission,omitempty" gorm:"-"`
	// PluginPermissionKey is the owning plugin's RBAC resource key, served
	// alongside so plugin pages can check their own permissions. Not stored.
	PluginPermissionKey string    `json:"plugin_permission_key,omitempty" gorm:"-"`
	CreatedAt           time.Time `json:"created_at"`
	UpdatedAt           time.Time `json:"updated_at"`

	// Relationships
	Plugin *Plugin `json:"plugin,omitempty" gorm:"foreignKey:PluginID"`
}

UIRegistry represents the runtime registry of loaded plugin UI components

func (UIRegistry) TableName

func (UIRegistry) TableName() string

TableName returns table name for UIRegistry

type UISlot

type UISlot struct {
	Slot  string       `json:"slot"`  // Slot identifier (e.g., "sidebar.section")
	Label string       `json:"label"` // Display label
	Icon  string       `json:"icon"`  // Icon path/URL
	Items []UISlotItem `json:"items"` // Items to mount in this slot
}

UISlot represents a UI extension point where plugins can mount components

type UISlotItem

type UISlotItem struct {
	Type  string  `json:"type"`  // "route" or "component"
	Path  string  `json:"path"`  // Route path
	Title string  `json:"title"` // Display title
	Mount UIMount `json:"mount"` // Mount configuration
	// Hidden registers the route without a sidebar entry: a detail page
	// reached from links in the plugin's other pages.
	Hidden bool `json:"hidden,omitempty"`
	// Tool is the tool operation name a chat.tool_renderer component draws.
	Tool string `json:"tool,omitempty"`
}

UISlotItem represents an individual UI component or route

func (UISlotItem) RendererKey

func (i UISlotItem) RendererKey() string

RendererKey returns the lookup key of a chat.tool_renderer item: the tool operation it renders (Tool, or Path for manifests that used it).

type User

type User struct {
	gorm.Model
	ID                   uint   `json:"id" gorm:"primaryKey"`
	Email                string `json:"email"`
	Name                 string
	Password             string `json:"password"`
	SessionToken         string
	ResetToken           string
	ResetTokenExpiry     time.Time
	EmailVerified        bool
	VerificationToken    string
	IsAdmin              bool
	ShowPortal           bool
	ShowChat             bool
	AccessToSSOConfig    bool
	SkipQuickStart       bool
	APIKey               string
	NotificationsEnabled bool `json:"notifications_enabled"` // Permission to receive notifications about new users, app requests etc.
	// EmailNotificationsEnabled is the user's own delivery preference: when
	// false, notifications are still recorded for the bell but no email is
	// sent. Defaults on. GORM's default:true turns an explicit false into
	// true on insert, so it is only ever switched off through a column
	// update (SetEmailNotificationsEnabled).
	EmailNotificationsEnabled bool    `json:"email_notifications_enabled" gorm:"default:true"`
	Groups                    []Group `json:"groups" gorm:"many2many:user_groups;"`
	// BudgetTeamID is the team the user's new Apps (and chat spend) are
	// attributed to when they belong to several (Enterprise team budgets).
	BudgetTeamID *uint `json:"budget_team_id"`

	// Provenance and activity. AuthSource is one of the AuthSource*
	// constants; SSOProfileID is the identity provider profile that
	// provisioned the user (or last signed them in, when the origin was
	// not SSO). The NOT NULL defaults matter: AutoMigrate adds these
	// columns to existing rows and a NULL would otherwise fall through
	// every equality filter.
	AuthSource   string `json:"auth_source" gorm:"size:16;not null;default:'';index"`
	SSOProfileID string `json:"sso_profile_id" gorm:"size:64"`
	// ExternalSubject is the host application's identifier for a user
	// provisioned through host authentication (AuthSourceHost). It is
	// unique among live users; soft-deleted rows do not hold it.
	ExternalSubject  string     `` /* 150-byte string literal not displayed */
	LastLoginAt      *time.Time `json:"last_login_at"`
	LastLoginMethod  string     `json:"last_login_method" gorm:"size:16"`
	APIKeyLastUsedAt *time.Time `json:"api_key_last_used_at"`

	// Disabled accounts cannot authenticate by any means (session, API
	// key, password, SSO, OAuth) until an administrator re-enables them.
	Disabled   bool       `json:"disabled" gorm:"not null;default:false;index"`
	DisabledAt *time.Time `json:"disabled_at"`

	// Plugin-stored metadata
	Metadata JSONMap `json:"metadata" gorm:"type:json"`
}

func NewUser

func NewUser() *User

NewUser is the self-registration constructor: it issues an API key and stamps the local origin. Admin and SSO creation build the struct directly and deliberately issue no key.

func (*User) AdminFlag

func (u *User) AdminFlag() bool

AdminFlag exposes IsAdmin to packages that cannot import models (see pkg/authz.AdminFlagged).

func (*User) Create

func (u *User) Create(db *gorm.DB) error

func (*User) Delete

func (u *User) Delete(db *gorm.DB) error

func (*User) DeleteGroupAssociation

func (u *User) DeleteGroupAssociation(db *gorm.DB) error

func (*User) DoesPasswordMatch

func (u *User) DoesPasswordMatch(password string) bool

func (*User) ExternalLoginMethod

func (u *User) ExternalLoginMethod() string

ExternalLoginMethod is the LastLoginMethod that proves an externally managed account still has the external system's backing.

func (*User) ExtractGroupIDs

func (u *User) ExtractGroupIDs() []uint

func (*User) GenerateAPIKey

func (u *User) GenerateAPIKey() error

func (*User) Get

func (u *User) Get(db *gorm.DB, id uint, preloads ...string) error

func (*User) GetAccessibleCatalogues

func (u *User) GetAccessibleCatalogues(db *gorm.DB) ([]Catalogue, error)

func (*User) GetAccessibleDataCatalogues

func (u *User) GetAccessibleDataCatalogues(db *gorm.DB) ([]DataCatalogue, error)

func (*User) GetAccessibleDataSources

func (u *User) GetAccessibleDataSources(db *gorm.DB) ([]Datasource, error)

func (*User) GetAccessibleLLMs

func (u *User) GetAccessibleLLMs(db *gorm.DB) ([]LLM, error)

func (*User) GetAccessibleToolCatalogues

func (u *User) GetAccessibleToolCatalogues(db *gorm.DB) ([]ToolCatalogue, error)

func (*User) GetAccessibleTools

func (u *User) GetAccessibleTools(db *gorm.DB, scopes ...func(*gorm.DB) *gorm.DB) ([]Tool, error)

GetAccessibleTools lists the tools the user's teams grant. Optional scopes narrow it in SQL, e.g. AppGrantableToolScope for the portal's App builder.

func (*User) GetByAPIKey

func (u *User) GetByAPIKey(db *gorm.DB, apiKey string) error

GetByAPIKey looks a user up by API key. An empty key never matches: users created by an administrator or through SSO have no key, and a blank comparison would otherwise select the first of them.

func (*User) GetByEmail

func (u *User) GetByEmail(db *gorm.DB, email string) error

func (*User) GetGroupsToUpdate

func (u *User) GetGroupsToUpdate(groupIDs []uint) []Group

func (*User) GetRole

func (u *User) GetRole() string

func (*User) IsExternallyManaged

func (u *User) IsExternallyManaged() bool

IsExternallyManaged reports whether something other than Studio vouches for the account: an identity provider (SSO) or the host application Studio is embedded in. Such accounts should hold no credential that outlives the external system's say-so.

func (*User) IsSSOOrigin

func (u *User) IsSSOOrigin() bool

IsSSOOrigin reports whether the account was provisioned by an identity provider.

func (*User) ParseGroupAssociations

func (u *User) ParseGroupAssociations(groupIDs []uint)

func (*User) ReplaceGroupAssociation

func (u *User) ReplaceGroupAssociation(db *gorm.DB, groups []Group) error

func (*User) SetPassword

func (u *User) SetPassword(password string) error

func (*User) StampLogin

func (u *User) StampLogin(method string)

StampLogin records a completed interactive login on the struct; the caller persists it (SetUserSession's Save, or the SSO transaction).

func (*User) Update

func (u *User) Update(db *gorm.DB) error

func (*User) UpdateGroupMemberships

func (u *User) UpdateGroupMemberships(db *gorm.DB, groupIDs ...string) error

type UserCounts

type UserCounts struct {
	UserCount      int64
	AdminCount     int64
	DeveloperCount int64
	ChatUserCount  int64
}

func GetUserCounts

func GetUserCounts(db *gorm.DB) (UserCounts, error)

type UserMessage

type UserMessage struct {
	FileRef []string
	Payload string
	// RunID identifies the turn for v2 (event-mode) sessions so a run handler
	// can follow exactly its own output. Empty means "assign one".
	RunID string
	// Regenerate asks the session to re-run the model on the stored history
	// without adding a new user message (the caller has already removed the
	// previous reply). Payload and FileRef are ignored.
	Regenerate bool
	// ToolResults resumes a turn that is waiting on client-side tools. When
	// set, Payload is ignored.
	ToolResults []ToolResult
}

UserMessage is one user turn handed to a chat session.

type UserQueryParams

type UserQueryParams struct {
	Search         string
	ExcludeGroupID uint
	PageSize       int
	PageNumber     int
	All            bool
	Sort           string

	// Optional filters; nil / empty means "any".
	AuthSource string
	HasAPIKey  *bool
	Disabled   *bool
}

type Users

type Users []User

func (*Users) CountActive

func (u *Users) CountActive(db *gorm.DB) (int64, error)

func (*Users) GetByGroupID

func (u *Users) GetByGroupID(db *gorm.DB, groupID uint) error

func (*Users) GetGroupUsersPaginated

func (u *Users) GetGroupUsersPaginated(db *gorm.DB, groupID uint, pageSize, pageNumber int, all bool) (int64, int, error)

func (*Users) QueryUsers

func (u *Users) QueryUsers(db *gorm.DB, params UserQueryParams) (int64, int, error)

func (*Users) SearchByEmailStub

func (u *Users) SearchByEmailStub(db *gorm.DB, emailStub string) error

type Vendor

type Vendor string
const (
	OPENAI      Vendor = "openai"
	ANTHROPIC   Vendor = "anthropic"
	VERTEX      Vendor = "vertex"
	GOOGLEAI    Vendor = "google_ai"
	HUGGINGFACE Vendor = "huggingface"
	OLLAMA      Vendor = "ollama"
	BEDROCK     Vendor = "bedrock"
	MOCK_VENDOR Vendor = "mock"
)

type VendorModelCost

type VendorModelCost struct {
	Vendor    string  `json:"vendor"`
	Model     string  `json:"model"`
	TotalCost float64 `json:"totalCost"`
	Currency  string  `json:"currency"`
}

VendorModelCost represents the total cost for a specific vendor and model

type VocabularyTerm

type VocabularyTerm struct {
	Value       string `json:"value"`
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
	Deprecated  bool   `json:"deprecated,omitempty"`
}

VocabularyTerm is one allowed value in a MetadataVocabulary.

type WebhookDelivery

type WebhookDelivery struct {
	ID       string `gorm:"primaryKey;size:36" json:"id"`
	EventID  string `gorm:"size:128;index:idx_webhook_deliveries_event" json:"event_id"`
	TargetID string `gorm:"size:36;index:idx_webhook_deliveries_target_created,priority:1" json:"target_id"`
	Topic    string `gorm:"size:200;index:idx_webhook_deliveries_topic_created,priority:1" json:"topic"`
	// TargetURLSnapshot is the URL at enqueue time, kept so the log stays
	// meaningful after the target is edited or deleted.
	TargetURLSnapshot string `gorm:"size:2048" json:"target_url"`

	Status         string     `gorm:"size:16;index:idx_webhook_deliveries_status_next,priority:1" json:"status"`
	AttemptCount   int        `json:"attempt_count"`
	MaxAttempts    int        `json:"max_attempts"`
	NextAttemptAt  time.Time  `gorm:"index:idx_webhook_deliveries_status_next,priority:2" json:"next_attempt_at"`
	LeaseOwner     string     `gorm:"size:128" json:"lease_owner,omitempty"`
	LeaseExpiresAt *time.Time `json:"lease_expires_at,omitempty"`

	// RenderedPayload is produced once on the first attempt and reused by
	// every retry so receivers see byte-identical bodies.
	RenderedPayload     string `gorm:"type:text" json:"rendered_payload,omitempty"`
	RenderError         string `gorm:"size:1024" json:"render_error,omitempty"`
	LastStatusCode      int    `json:"last_status_code"`
	LastError           string `gorm:"size:1024" json:"last_error"`
	LastResponseSnippet string `gorm:"size:4096" json:"last_response_snippet,omitempty"`

	ReplayOfID string `gorm:"size:36;index:idx_webhook_deliveries_replay_of" json:"replay_of_id,omitempty"`
	Kind       string `gorm:"size:16;index:idx_webhook_deliveries_kind_created,priority:1" json:"kind"`
	// DedupeKey is "<event_id>:<target_id>" for event deliveries so a bus
	// event that arrives twice fans out once. Test and replay rows use their
	// own ID so they are never deduplicated.
	DedupeKey string `gorm:"size:200;uniqueIndex:uq_webhook_deliveries_dedupe" json:"-"`

	LockVersion int        `gorm:"not null;default:0" json:"-"`
	CreatedAt   time.Time  `` /* 223-byte string literal not displayed */
	CompletedAt *time.Time `json:"completed_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
}

WebhookDelivery is one (event, target) outbox row. Workers claim due rows with a lease and an optimistic lock, so any number of Studio nodes can run workers against a shared database without double delivery.

func (*WebhookDelivery) IsTerminal

func (d *WebhookDelivery) IsTerminal() bool

IsTerminal reports whether the delivery will not be attempted again.

func (WebhookDelivery) TableName

func (WebhookDelivery) TableName() string

type WebhookDeliveryAttempt

type WebhookDeliveryAttempt struct {
	ID              uint64    `gorm:"primaryKey;autoIncrement" json:"id"`
	DeliveryID      string    `gorm:"size:36;index:idx_webhook_attempts_delivery" json:"delivery_id"`
	Attempt         int       `json:"attempt"`
	StartedAt       time.Time `json:"started_at"`
	DurationMs      int64     `json:"duration_ms"`
	StatusCode      int       `json:"status_code"`
	RequestHeaders  RawJSON   `gorm:"type:text" json:"request_headers"`
	ResponseHeaders RawJSON   `gorm:"type:text" json:"response_headers"`
	ResponseSnippet string    `gorm:"size:4096" json:"response_snippet"`
	Error           string    `gorm:"size:1024" json:"error"`
	Outcome         string    `gorm:"size:16" json:"outcome"`
}

WebhookDeliveryAttempt records one HTTP attempt (or one non-HTTP terminal step such as a render error). RequestHeaders holds only the X-Webhook-*, Content-Type and User-Agent headers, never the target's custom headers.

func (WebhookDeliveryAttempt) TableName

func (WebhookDeliveryAttempt) TableName() string

type WebhookEvent

type WebhookEvent struct {
	ID          string    `gorm:"primaryKey;size:128" json:"id"`
	Topic       string    `gorm:"size:200;index:idx_webhook_events_topic_received,priority:1" json:"topic"`
	Origin      string    `gorm:"size:128" json:"origin"`
	Payload     RawJSON   `gorm:"type:text" json:"payload"`
	ObjectType  string    `gorm:"size:64" json:"object_type"`
	Action      string    `gorm:"size:32" json:"action"`
	ObjectID    uint      `json:"object_id"`
	ActorUserID uint      `json:"actor_user_id"`
	ReceivedAt  time.Time `gorm:"index:idx_webhook_events_topic_received,priority:2;index:idx_webhook_events_received" json:"received_at"`
	FanoutCount int       `json:"fanout_count"`
	// Synthetic marks events created by "send test", not received from the bus.
	Synthetic bool `json:"synthetic"`
}

WebhookEvent is a bus event persisted for fan-out and replay. The primary key is the bus event ID, which is what makes ingestion idempotent. Payload is stored after redaction; the unredacted object is never written.

func (WebhookEvent) TableName

func (WebhookEvent) TableName() string

type WebhookTarget

type WebhookTarget struct {
	ID          string `gorm:"primaryKey;size:36" json:"id"`
	Name        string `gorm:"size:200;not null" json:"name"`
	Description string `gorm:"size:1024" json:"description"`
	URL         string `gorm:"size:2048;not null" json:"url"`
	Status      string `gorm:"size:16;index:idx_webhook_targets_status;not null" json:"status"`
	Paused      bool   `json:"paused"`

	// TopicFilters are path.Match globs, e.g. "system.llm.*". Empty matches nothing.
	// Stored as JSON text in TopicFiltersJSON (a plain string column, so the
	// audit trail can snapshot the row into a map) and synced by the hooks.
	TopicFilters     []string `gorm:"-" json:"topic_filters"`
	TopicFiltersJSON string   `gorm:"column:topic_filters;type:text" json:"-"`

	TemplatePreset string `gorm:"size:32" json:"template_preset"`
	TemplateBody   string `gorm:"type:text" json:"template_body"`

	// Headers is a JSON-encoded map[string]string of extra request headers.
	// Encrypted at rest because it commonly carries an Authorization value.
	Headers string `gorm:"type:text" json:"-"`

	// SigningSecret signs every delivery (HMAC-SHA256). PrevSigningSecret is
	// honoured until PrevSecretExpiresAt after a rotation so receivers can roll.
	SigningSecret       string     `gorm:"type:text" json:"-"`
	PrevSigningSecret   string     `gorm:"type:text" json:"-"`
	PrevSecretExpiresAt *time.Time `json:"-"`

	// MaxConcurrency caps in-flight deliveries to this target; 0 = engine default.
	MaxConcurrency int `json:"max_concurrency"`

	CreatedByUserID  uint       `json:"created_by_user_id"`
	CreatedByEmail   string     `gorm:"size:255" json:"created_by_email"`
	ApprovedByUserID uint       `json:"approved_by_user_id"`
	ApprovedByEmail  string     `gorm:"size:255" json:"approved_by_email"`
	ApprovedAt       *time.Time `json:"approved_at"`
	RejectedReason   string     `gorm:"size:1024" json:"rejected_reason"`
	RevokedByUserID  uint       `json:"revoked_by_user_id"`
	RevokedByEmail   string     `gorm:"size:255" json:"revoked_by_email"`
	RevokedAt        *time.Time `json:"revoked_at"`
	RevokedReason    string     `gorm:"size:1024" json:"revoked_reason"`

	LastDeliveryAt      *time.Time `json:"last_delivery_at"`
	LastSuccessAt       *time.Time `json:"last_success_at"`
	LastFailureAt       *time.Time `json:"last_failure_at"`
	ConsecutiveFailures int        `json:"consecutive_failures"`

	// LockVersion is bumped on every save; clients send it back on update so
	// two admins editing the same target cannot silently overwrite each other.
	LockVersion int       `gorm:"not null;default:0" json:"lock_version"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

WebhookTarget is an approved (or not yet approved) outbound HTTP endpoint that receives event-bus events matching its topic filters.

Custom headers and signing secrets are encrypted at rest through the BeforeSave/AfterFind hooks (same scheme as Submission credentials) and are never serialised to the API: see ToResponse.

func (*WebhookTarget) AfterFind

func (t *WebhookTarget) AfterFind(tx *gorm.DB) error

AfterFind decrypts the header map and signing secrets after a read and decodes the topic filters.

func (*WebhookTarget) AfterSave

func (t *WebhookTarget) AfterSave(tx *gorm.DB) error

AfterSave restores plaintext on the in-memory struct so callers that keep using the object after Create/Save do not see ciphertext.

func (*WebhookTarget) BeforeSave

func (t *WebhookTarget) BeforeSave(tx *gorm.DB) error

BeforeSave encrypts the header map and signing secrets before they hit the DB and serialises the topic filters.

func (*WebhookTarget) HeaderMap

func (t *WebhookTarget) HeaderMap() map[string]string

HeaderMap decodes the custom headers. Invalid or empty JSON yields an empty map.

func (*WebhookTarget) HeaderNames

func (t *WebhookTarget) HeaderNames() []string

HeaderNames lists the custom header names, sorted, without values.

func (*WebhookTarget) IsDeliverable

func (t *WebhookTarget) IsDeliverable() bool

IsDeliverable reports whether deliveries to this target may be sent now.

func (*WebhookTarget) SetHeaderMap

func (t *WebhookTarget) SetHeaderMap(h map[string]string)

SetHeaderMap encodes the custom headers. A nil or empty map clears them.

func (WebhookTarget) TableName

func (WebhookTarget) TableName() string

func (*WebhookTarget) ToResponse

func (t *WebhookTarget) ToResponse() WebhookTargetResponse

ToResponse converts the target to its API shape, dropping every secret.

type WebhookTargetResponse

type WebhookTargetResponse struct {
	ID                  string     `json:"id"`
	Name                string     `json:"name"`
	Description         string     `json:"description"`
	URL                 string     `json:"url"`
	Status              string     `json:"status"`
	Paused              bool       `json:"paused"`
	TopicFilters        []string   `json:"topic_filters"`
	TemplatePreset      string     `json:"template_preset"`
	TemplateBody        string     `json:"template_body"`
	HeaderNames         []string   `json:"header_names"`
	HasSigningSecret    bool       `json:"has_signing_secret"`
	MaxConcurrency      int        `json:"max_concurrency"`
	CreatedByUserID     uint       `json:"created_by_user_id"`
	CreatedByEmail      string     `json:"created_by_email"`
	ApprovedByUserID    uint       `json:"approved_by_user_id"`
	ApprovedByEmail     string     `json:"approved_by_email"`
	ApprovedAt          *time.Time `json:"approved_at"`
	RejectedReason      string     `json:"rejected_reason"`
	RevokedByUserID     uint       `json:"revoked_by_user_id"`
	RevokedByEmail      string     `json:"revoked_by_email"`
	RevokedAt           *time.Time `json:"revoked_at"`
	RevokedReason       string     `json:"revoked_reason"`
	LastDeliveryAt      *time.Time `json:"last_delivery_at"`
	LastSuccessAt       *time.Time `json:"last_success_at"`
	LastFailureAt       *time.Time `json:"last_failure_at"`
	ConsecutiveFailures int        `json:"consecutive_failures"`
	LockVersion         int        `json:"lock_version"`
	CreatedAt           time.Time  `json:"created_at"`
	UpdatedAt           time.Time  `json:"updated_at"`
}

WebhookTargetResponse is the API shape of a target. Secret values are never included: custom headers appear as names only and the signing secret as a flag.

Jump to

Keyboard shortcuts

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