Documentation
¶
Index ¶
- Constants
- func ParseAllowedDomains(spec string) []string
- func ParseTenantDefaults(spec string) (models.TenantDefaults, error)
- func ValidateCandidatePool(v int) error
- func ValidateCleanupIntervalHours(v int) error
- func ValidateDuplicateThreshold(v float64) error
- func ValidateHistoryRetentionDays(v int) error
- func ValidateLogLevel(v string) error
- func ValidateMMRLambda(v float64) error
- func ValidateMaxRequestBytes(v int64) error
- func ValidateRateLimit(rps float64, burst int) error
- func ValidateRateLimitBurst(v int) error
- func ValidateRateLimitRPS(v float64) error
- func ValidateSelfServicePolicy(v string) error
- func ValidateSnippetChars(v int) error
- func ValidateStalenessDefault(v string) error
- func ValidateStalenessPenalty(v float64) error
- func ValidateTrustedProxyDepth(v int) error
- type Config
Constants ¶
const DefaultUIClientID = "memory-ui"
DefaultUIClientID is the client_id assigned to the web UI's public PKCE OAuth client when MEMORY_UI_CLIENT_ID is unset on an OAuth-enabled instance. It keeps /ui/config.json from ever advertising an empty client and gives the boot-time seed (internal/authletstore.SeedUIClient) a stable id to register.
Variables ¶
This section is empty.
Functions ¶
func ParseAllowedDomains ¶
ParseAllowedDomains splits a comma-separated SIGNUP_ALLOWED_DOMAINS spec into a normalized allow-list: each entry lowercased and trimmed, empties dropped. An empty/whitespace-only spec yields nil (len 0), which callers treat as "public" — any verified identity may self-provision.
func ParseTenantDefaults ¶
func ParseTenantDefaults(spec string) (models.TenantDefaults, error)
ParseTenantDefaults parses "staleness=off,duplicate_guard=false,cleanup_scan_enabled=false" into a models.TenantDefaults, overlaying set keys on top of the built-in safe bundle (models.BaselineTenantDefaults). Empty = the safe bundle; whitespace-tolerant, case-insensitive; unknown keys or invalid values error.
func ValidateCandidatePool ¶ added in v1.1.1
func ValidateCleanupIntervalHours ¶ added in v1.1.1
func ValidateDuplicateThreshold ¶ added in v1.1.1
func ValidateHistoryRetentionDays ¶ added in v1.1.1
func ValidateLogLevel ¶ added in v1.1.1
ValidateLogLevel accepts the slog level names (debug|info|warn|error). Not called by Load — main parses the level leniently — but the admin API rejects a bad value here.
func ValidateMMRLambda ¶ added in v1.1.1
func ValidateMaxRequestBytes ¶ added in v1.1.1
func ValidateRateLimit ¶ added in v1.1.1
ValidateRateLimit enforces the burst>=1 rule whenever throttling is on (rps>0).
func ValidateRateLimitBurst ¶ added in v1.1.1
func ValidateRateLimitRPS ¶ added in v1.1.1
func ValidateSelfServicePolicy ¶ added in v1.1.1
func ValidateSnippetChars ¶ added in v1.1.1
func ValidateStalenessDefault ¶ added in v1.1.1
func ValidateStalenessPenalty ¶ added in v1.1.1
ValidateStalenessPenalty allows [0, 1]; 0 is valid (off), unlike MMR lambda.
func ValidateTrustedProxyDepth ¶ added in v1.1.1
Types ¶
type Config ¶
type Config struct {
DatabaseURL string `env:"DATABASE_URL" envDefault:"postgres://memory:memory@localhost:5432/memory?sslmode=disable"`
ServerAddr string `env:"SERVER_ADDR" envDefault:":8080"`
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
// Embedding provider: "ollama", "gcp", "openai", "aws", or "fake". Default
// dimension matches the default model (ollama nomic-embed-text=768) so a stock
// deploy works (audit #12). For OpenAI text-embedding-3-*, also the output size.
EmbeddingProvider string `env:"EMBEDDING_PROVIDER" envDefault:"ollama"`
EmbeddingDimensions int `env:"EMBEDDING_DIMENSIONS" envDefault:"768"`
// Ollama
OllamaURL string `env:"OLLAMA_URL" envDefault:"http://localhost:11434"`
OllamaModel string `env:"OLLAMA_MODEL" envDefault:"nomic-embed-text"`
// GCP Vertex AI
GCPProject string `env:"GCP_PROJECT"`
GCPLocation string `env:"GCP_LOCATION" envDefault:"us-central1"`
GCPModel string `env:"GCP_EMBEDDING_MODEL" envDefault:"text-embedding-005"`
// OpenAI-compatible — any /v1/embeddings endpoint (OpenAI, Azure, vLLM, TEI,
// etc). APIKey optional (self-hosted often ignores it); BaseURL is the API root.
OpenAIBaseURL string `env:"OPENAI_BASE_URL" envDefault:"https://api.openai.com/v1"`
OpenAIAPIKey string `env:"OPENAI_API_KEY"`
OpenAIModel string `env:"OPENAI_EMBEDDING_MODEL"`
// AWS Bedrock. Credentials resolve from the standard AWS chain (env vars,
// shared config, IAM role) — never from these fields. Region + model only.
AWSRegion string `env:"AWS_REGION"`
AWSModel string `env:"AWS_EMBEDDING_MODEL"`
// Admin
AdminAllowedEmails string `env:"ADMIN_ALLOWED_EMAILS"`
// Cleanup pipeline — nightly lint scan populates cleanup_queue with
// near-duplicate candidates. These env values seed instance_config at migrate
// time; the runtime reads them live via the accessor (webhook_url is DB-only).
CleanupIntervalHours int `env:"CLEANUP_INTERVAL_HOURS" envDefault:"24"`
CleanupEnabled bool `env:"CLEANUP_ENABLED" envDefault:"true"`
// HistoryRetentionDays bounds mutation_history growth: the sweep prunes rows
// older than this. Only matters when the global history toggle is on. Must be
// >= 1 (0 would prune everything each sweep).
HistoryRetentionDays int `env:"MEMORY_HISTORY_RETENTION_DAYS" envDefault:"90"`
// HTTP hardening. MaxRequestBytes caps request bodies (0 disables). RateLimit*
// is a token-bucket throttle over the auth+write surface (RPS <= 0 disables).
// RateLimitTrustedProxyDepth is how many trusted reverse-proxy/CDN hops sit in
// front: 0 (default) trusts none and keys on RemoteAddr (X-Forwarded-For is
// ignored, unspoofable); N>=1 keys on the Nth-from-last X-Forwarded-For entry.
MaxRequestBytes int64 `env:"MAX_REQUEST_BYTES" envDefault:"1048576"`
RateLimitRPS float64 `env:"RATE_LIMIT_RPS" envDefault:"20"`
RateLimitBurst int `env:"RATE_LIMIT_BURST" envDefault:"40"`
RateLimitTrustedProxyDepth int `env:"RATE_LIMIT_TRUSTED_PROXY_DEPTH" envDefault:"0"`
// Tenant-toggle defaults. Raw spec from env, overridable via --opts;
// ParseTenantDefaults yields the typed models.TenantDefaults applied at
// AutoMigrate and tenant-create time.
TenantDefaultsSpec string `env:"MEMORY_DEFAULT_OPTS"`
TenantDefaults models.TenantDefaults
// SelfServicePolicy is the global default self-service gate: "open" (default)
// lets any member edit tenant toggles and an owner self-create API keys;
// "admin_only" raises both to admin. A nullable per-tenant column overrides
// it. Validated at load — unknown values are rejected.
SelfServicePolicy string `env:"MEMORY_SELF_SERVICE_POLICY" envDefault:"open"`
// authlet — OAuth 2.1 / OIDC AS for /mcp. AuthletMasterKey is a 32-byte hex
// key encrypting AS signing material at rest. GoogleClient* identify memory-mcp
// to Google (upstream IdP). Both Google envs set = opt into authlet: Setup must
// succeed at boot (any error fatal). Unset = /mcp is API-key-only, authlet skipped.
AuthletMasterKey string `env:"AUTHLET_MASTER_KEY"`
GoogleClientID string `env:"MEMORY_MCP_GOOGLE_CLIENT_ID"`
GoogleClientSecret string `env:"MEMORY_MCP_GOOGLE_CLIENT_SECRET"`
// UIClientID is the pre-registered public PKCE OAuth client the web UI uses
// (redirect_uri = PublicBaseURL + "/ui"). Non-secret; served to the page.
UIClientID string `env:"MEMORY_UI_CLIENT_ID"`
// SIGNUP_ALLOWED_DOMAINS gates self-serve tenant provisioning: a
// comma-separated allow-list of email domains (e.g. "example.com,acme.org")
// whose verified identities may auto-provision a personal tenant on first
// login. Entries are lowercased and trimmed at load into SignupAllowedDomains.
// Empty/unset ⇒ empty slice, meaning PUBLIC (any verified identity may
// self-provision) — see design decision 2.
SignupAllowedDomainsSpec string `env:"SIGNUP_ALLOWED_DOMAINS"`
SignupAllowedDomains []string
// PublicBaseURL is the external origin (scheme+host, no path/trailing slash),
// e.g. "https://mem.example.org". Anchors the authlet issuer/audience/PRM/
// callback URLs and the UI OAuth config. REQUIRED (absolute http(s)) when the
// authlet path is enabled; unused by the API-key-only path.
PublicBaseURL string `env:"PUBLIC_BASE_URL"`
// Reset — MemoryReset is a boot-time signal (never a route) that re-arms
// bootstrap by clearing the admin-key set only. The first-run bootstrap token
// is no longer configured via env: cmd/server/main.go generates and logs it on
// an un-bootstrapped instance (design D1; see MemoryService.BootstrapToken).
MemoryReset bool `env:"MEMORY_RESET"`
// Import jobs — bounds on the async document-import path. MaxUploadBytes caps
// the archive accepted by POST /api/admin/import (default 32 MiB).
// WorkerConcurrency bounds the in-process worker draining import_jobs.
ImportMaxUploadBytes int64 `env:"IMPORT_MAX_UPLOAD_BYTES" envDefault:"33554432"`
ImportWorkerConcurrency int `env:"IMPORT_WORKER_CONCURRENCY" envDefault:"1"`
// MMRLambda tunes HybridSearch's MMR diversity re-rank (repository.SearchParams.MMRLambda).
// Default 0.5 = LongMemEval-tuned optimum (peak full-recall); 1.0 disables (pure relevance).
MMRLambda float64 `env:"MEMORY_MMR_LAMBDA" envDefault:"0.5"`
// StalenessPenalty down-weights stale docs in HybridSearch's re-rank
// (repository.SearchParams). 0 = off (identity); 1 = strongest demotion.
StalenessPenalty float64 `env:"MEMORY_STALENESS_PENALTY" envDefault:"0.2"`
// SnippetChars caps the match-centered window search_memory returns when
// snippet=true (approximate on the low end — ts_headline windows by words).
SnippetChars int `env:"MEMORY_SNIPPET_CHARS" envDefault:"400"`
// CandidatePool is the per-list SQL LIMIT each of HybridSearch's semantic and
// lexical candidate lists draws before fusion; its half sets the tier cut.
CandidatePool int `env:"MEMORY_CANDIDATE_POOL" envDefault:"20"`
}
func (*Config) AuthletEnabled ¶
AuthletEnabled reports whether both Google client envs are set (opt-in to the authlet OAuth path). When true, callers must require authletas.Setup to succeed.
func (*Config) EmbeddingCfg ¶
func (c *Config) EmbeddingCfg() service.EmbeddingConfig
EmbeddingCfg converts config fields into a service.EmbeddingConfig.
func (*Config) EmbeddingModel ¶
EmbeddingModel returns the active provider's model id. With EmbeddingProvider it fingerprints the corpus's embedding identity for the migration guard (audit #13/#16).