package gateway import ( "io/fs" "log/slog" "net/http" "git.yeij.top/AskaEth/Cyrene_v2/internal/bus" pluginmgr "git.yeij.top/AskaEth/Cyrene_v2/internal/capability/plugin" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model" ) // Deps carries the gateway's injected dependencies. Every field is nil-tolerant // except Auth, which is required (authentication backs login and every RBAC // decision). Registry/Loop are satisfied by the concrete *capability.Registry and // *loop.Loop; Sessions/Personas/Memories are satisfied by the concrete session // manager, persona registry and memory store, and the handlers return [] only // when a dependency is left nil. type Deps struct { // Log is the base logger. Nil uses a discard logger. Log *slog.Logger // Auth is the JWT/RBAC service. Required. Auth Authenticator // Bus is the in-process event bus the WS hub subscribes to. Optional. Bus bus.Bus // Registry enumerates capabilities/plugins/channels. Optional. Registry CapabilityStore // Loop runs chat turns. Optional (chat returns an error when unset). Loop Chatter // Session lists channel sessions. Optional. Session SessionStore // Personas lists personas. Optional. Personas PersonaStore // Memories lists memory entries. Optional. Memories MemoryStore // History is the persistent chat-history store (design/16). Optional; when nil the // session/message endpoints degrade (list falls back to channel sessions, others 501). History HistoryStore // IoT lists IoT devices. Optional. IoT IoTStore // Scheduler audits sub-agent context for the subagent_ask WS route. // Optional (subagent_ask returns a clear error when unset). Scheduler SubagentAuditor // Tasks queries task output for the task_output_query WS route. // Optional (task_output_query returns a clear error when unset). Tasks TaskOutputStore // Automations lists automations and reminders. Optional. Automations AutomationStore // Users lists accounts and API keys. Optional (falls back to the configured // single admin account). Users UserStore // Refresh is the opaque refresh-token store. Optional: when nil login omits // refreshToken and /auth/refresh + /auth/logout answer not-configured. Refresh RefreshGrantStore // Backthink lists background-think records. Optional. Backthink BackthinkStore // RAG backs the admin knowledge-base RAG module. Optional; list/search // return empty when unset, and write endpoints report a clear 501. RAG RagStore // LLM is the hot-swappable provider stack (models.json, design/04 §3.1). // Optional: when nil the admin /llm endpoints fall back to the env config so // pre-existing gateway tests keep working. LLM *model.RuntimeLLM // Channels is the runtime-editable channel-adapter config (channels.json). // Optional: when nil the admin /channels/config endpoints return a clear // not-configured error, matching how the LLM stack behaves when unset. Channels ChannelConfigStore // Plugins is the runtime-installable external tool provider manager // (plugins.json + live MCP servers). Optional: when nil install answers a // clear not-implemented error and uninstall falls back to a plain capability // removal, so pre-existing gateway tests keep working. Plugins *pluginmgr.Manager // OwnerRegistrar stamps a scan-login's bound owner id into the owner // whitelist (configs/users/owner.yaml) and hot-updates the live profile. // Optional: when nil the weixin confirm flow still persists channels.json but // skips the whitelist registration (best-effort by design). OwnerRegistrar OwnerRegistrar // AuditStore persists the admin audit trail (observability → audit). When nil // the gateway degrades to an in-memory store so the endpoint still returns // data; the composition root injects NewSQLiteAuditStore over a.db for real // persistence. Optional. AuditStore AuditStore // DatabasePath is the resolved path of the SQLite database file the // composition root actually opened (the value derived by resolveSQLitePath, // which may differ from cfg.DB.SQLitePath when the data dir default applies). // It backs the admin backup/restore endpoints. Optional; when empty those // endpoints answer honestly with a clear not-configured error. DatabasePath string // DataDir is the resolved data directory (the value resolveDataDir returns, // which may differ from cfg.DataDir when the OS default applies). It backs // the image-upload store (/uploads) and its static route. Optional; // when empty the upload handlers fall back to cfg.DataDir. DataDir string // Streaming marks the injected Loop as streaming-capable (its OnStream is // wired to publish ws.stream_chunk). When set the hub skips its own single // final stream_chunk emission, since deltas already stream through OnStream. Streaming bool // Frontend is the SPA filesystem served for all non-API, non-WS routes. // When nil the gateway serves no static assets (API and WS only). The // embedded dist (internal/webui) or an external dist directory is used. Frontend fs.FS // Webhooks are externally-mounted inbound HTTP handlers (endpoint path → // handler), typically from channel adapters that receive webhook callbacks // (e.g. webhook). Each is mounted on the ServeMux without gateway auth; the // handler itself enforces its own signature/authorization (webhook HMAC). // Optional. Webhooks map[string]http.Handler }