@schlessera/brain-ui-server 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/README.md +51 -12
  2. package/dist/agent/backend.d.ts +163 -37
  3. package/dist/agent/backend.d.ts.map +1 -1
  4. package/dist/agent/backend.js +281 -286
  5. package/dist/agent/backend.js.map +1 -1
  6. package/dist/app.d.ts +46 -5
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/app.js +94 -35
  9. package/dist/app.js.map +1 -1
  10. package/dist/brain/client.d.ts +41 -30
  11. package/dist/brain/client.d.ts.map +1 -1
  12. package/dist/brain/client.js +138 -132
  13. package/dist/brain/client.js.map +1 -1
  14. package/dist/config/env.d.ts +104 -0
  15. package/dist/config/env.d.ts.map +1 -0
  16. package/dist/config/env.js +296 -0
  17. package/dist/config/env.js.map +1 -0
  18. package/dist/cron/scheduler.d.ts +16 -8
  19. package/dist/cron/scheduler.d.ts.map +1 -1
  20. package/dist/cron/scheduler.js +54 -53
  21. package/dist/cron/scheduler.js.map +1 -1
  22. package/dist/db/brain-db.d.ts +50 -0
  23. package/dist/db/brain-db.d.ts.map +1 -0
  24. package/dist/db/brain-db.js +75 -0
  25. package/dist/db/brain-db.js.map +1 -0
  26. package/dist/db/client.d.ts +8 -6
  27. package/dist/db/client.d.ts.map +1 -1
  28. package/dist/db/client.js +12 -25
  29. package/dist/db/client.js.map +1 -1
  30. package/dist/db/settings.d.ts +5 -4
  31. package/dist/db/settings.d.ts.map +1 -1
  32. package/dist/db/settings.js +9 -12
  33. package/dist/db/settings.js.map +1 -1
  34. package/dist/files/walker.d.ts +6 -7
  35. package/dist/files/walker.d.ts.map +1 -1
  36. package/dist/files/walker.js +6 -9
  37. package/dist/files/walker.js.map +1 -1
  38. package/dist/graph/reader.d.ts +6 -6
  39. package/dist/graph/reader.d.ts.map +1 -1
  40. package/dist/graph/reader.js +22 -12
  41. package/dist/graph/reader.js.map +1 -1
  42. package/dist/index.d.ts +15 -9
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +20 -10
  45. package/dist/index.js.map +1 -1
  46. package/dist/middleware/auth.d.ts +17 -6
  47. package/dist/middleware/auth.d.ts.map +1 -1
  48. package/dist/middleware/auth.js +34 -43
  49. package/dist/middleware/auth.js.map +1 -1
  50. package/dist/middleware/origin.d.ts +1 -2
  51. package/dist/middleware/origin.d.ts.map +1 -1
  52. package/dist/middleware/origin.js +1 -7
  53. package/dist/middleware/origin.js.map +1 -1
  54. package/dist/middleware/passkeys.d.ts +29 -5
  55. package/dist/middleware/passkeys.d.ts.map +1 -1
  56. package/dist/middleware/passkeys.js +47 -76
  57. package/dist/middleware/passkeys.js.map +1 -1
  58. package/dist/middleware/tailscale.d.ts +14 -11
  59. package/dist/middleware/tailscale.d.ts.map +1 -1
  60. package/dist/middleware/tailscale.js +11 -10
  61. package/dist/middleware/tailscale.js.map +1 -1
  62. package/dist/routes/brain.d.ts +9 -154
  63. package/dist/routes/brain.d.ts.map +1 -1
  64. package/dist/routes/brain.js +187 -188
  65. package/dist/routes/brain.js.map +1 -1
  66. package/dist/routes/files.d.ts +4 -88
  67. package/dist/routes/files.d.ts.map +1 -1
  68. package/dist/routes/files.js +74 -71
  69. package/dist/routes/files.js.map +1 -1
  70. package/dist/routes/graph.d.ts +4 -255
  71. package/dist/routes/graph.d.ts.map +1 -1
  72. package/dist/routes/graph.js +67 -64
  73. package/dist/routes/graph.js.map +1 -1
  74. package/dist/routes/health.d.ts +8 -22
  75. package/dist/routes/health.d.ts.map +1 -1
  76. package/dist/routes/health.js +10 -10
  77. package/dist/routes/health.js.map +1 -1
  78. package/dist/routes/models.d.ts +7 -90
  79. package/dist/routes/models.d.ts.map +1 -1
  80. package/dist/routes/models.js +53 -51
  81. package/dist/routes/models.js.map +1 -1
  82. package/dist/routes/providers.d.ts +5 -34
  83. package/dist/routes/providers.d.ts.map +1 -1
  84. package/dist/routes/providers.js +13 -11
  85. package/dist/routes/providers.js.map +1 -1
  86. package/dist/routes/sessions.d.ts +7 -78
  87. package/dist/routes/sessions.d.ts.map +1 -1
  88. package/dist/routes/sessions.js +35 -34
  89. package/dist/routes/sessions.js.map +1 -1
  90. package/dist/routes/share.d.ts +7 -60
  91. package/dist/routes/share.d.ts.map +1 -1
  92. package/dist/routes/share.js +80 -77
  93. package/dist/routes/share.js.map +1 -1
  94. package/dist/routes/voice.d.ts +8 -91
  95. package/dist/routes/voice.d.ts.map +1 -1
  96. package/dist/routes/voice.js +62 -59
  97. package/dist/routes/voice.js.map +1 -1
  98. package/dist/share/staging.d.ts +4 -4
  99. package/dist/share/staging.d.ts.map +1 -1
  100. package/dist/share/staging.js +7 -8
  101. package/dist/share/staging.js.map +1 -1
  102. package/dist/voice/deepgram-token.d.ts +1 -1
  103. package/dist/voice/deepgram-token.d.ts.map +1 -1
  104. package/dist/voice/deepgram-token.js +1 -2
  105. package/dist/voice/deepgram-token.js.map +1 -1
  106. package/dist/voice/keyterm-builder.d.ts +23 -8
  107. package/dist/voice/keyterm-builder.d.ts.map +1 -1
  108. package/dist/voice/keyterm-builder.js +67 -43
  109. package/dist/voice/keyterm-builder.js.map +1 -1
  110. package/dist/voice/speech-providers.d.ts +6 -4
  111. package/dist/voice/speech-providers.d.ts.map +1 -1
  112. package/dist/voice/speech-providers.js +28 -25
  113. package/dist/voice/speech-providers.js.map +1 -1
  114. package/dist/ws/bridge.d.ts.map +1 -1
  115. package/dist/ws/bridge.js +2 -3
  116. package/dist/ws/bridge.js.map +1 -1
  117. package/dist/ws/clients.d.ts +18 -10
  118. package/dist/ws/clients.d.ts.map +1 -1
  119. package/dist/ws/clients.js +35 -37
  120. package/dist/ws/clients.js.map +1 -1
  121. package/dist/ws/connection.d.ts.map +1 -1
  122. package/dist/ws/connection.js +5 -7
  123. package/dist/ws/connection.js.map +1 -1
  124. package/dist/ws/dispatch.d.ts.map +1 -1
  125. package/dist/ws/dispatch.js +1 -2
  126. package/dist/ws/dispatch.js.map +1 -1
  127. package/dist/ws/host.d.ts +16 -12
  128. package/dist/ws/host.d.ts.map +1 -1
  129. package/dist/ws/host.js +14 -23
  130. package/dist/ws/host.js.map +1 -1
  131. package/dist/ws/routing.d.ts +2 -1
  132. package/dist/ws/routing.d.ts.map +1 -1
  133. package/dist/ws/routing.js +5 -6
  134. package/dist/ws/routing.js.map +1 -1
  135. package/dist/ws/run-session.js +1 -1
  136. package/dist/ws/run-session.js.map +1 -1
  137. package/dist/ws/session-catalog.d.ts +2 -2
  138. package/dist/ws/session-catalog.d.ts.map +1 -1
  139. package/dist/ws/session-catalog.js +2 -3
  140. package/dist/ws/session-catalog.js.map +1 -1
  141. package/package.json +8 -5
  142. package/src/agent/backend.ts +509 -340
  143. package/src/app.ts +157 -36
  144. package/src/brain/client.ts +166 -143
  145. package/src/config/env.ts +401 -0
  146. package/src/cron/scheduler.ts +77 -59
  147. package/src/db/brain-db.ts +104 -0
  148. package/src/db/client.ts +12 -31
  149. package/src/db/settings.ts +12 -14
  150. package/src/files/walker.ts +6 -10
  151. package/src/graph/reader.ts +26 -15
  152. package/src/index.ts +56 -17
  153. package/src/middleware/auth.ts +51 -45
  154. package/src/middleware/origin.ts +1 -8
  155. package/src/middleware/passkeys.ts +72 -68
  156. package/src/middleware/tailscale.ts +22 -17
  157. package/src/routes/brain.ts +31 -30
  158. package/src/routes/files.ts +10 -7
  159. package/src/routes/graph.ts +9 -6
  160. package/src/routes/health.ts +17 -10
  161. package/src/routes/models.ts +19 -15
  162. package/src/routes/providers.ts +14 -15
  163. package/src/routes/sessions.ts +18 -11
  164. package/src/routes/share.ts +35 -24
  165. package/src/routes/voice.ts +78 -68
  166. package/src/share/staging.ts +10 -8
  167. package/src/voice/deepgram-token.ts +4 -2
  168. package/src/voice/keyterm-builder.ts +90 -56
  169. package/src/voice/speech-providers.ts +28 -24
  170. package/src/ws/bridge.ts +2 -3
  171. package/src/ws/clients.ts +38 -41
  172. package/src/ws/connection.ts +5 -7
  173. package/src/ws/dispatch.ts +1 -2
  174. package/src/ws/host.ts +24 -27
  175. package/src/ws/routing.ts +6 -10
  176. package/src/ws/run-session.ts +1 -1
  177. package/src/ws/session-catalog.ts +2 -3
  178. package/dist/ws/handler.d.ts +0 -34
  179. package/dist/ws/handler.d.ts.map +0 -1
  180. package/dist/ws/handler.js +0 -33
  181. package/dist/ws/handler.js.map +0 -1
  182. package/src/ws/handler.ts +0 -50
package/README.md CHANGED
@@ -11,13 +11,14 @@ pieces through `createApp()`.
11
11
  ## Usage
12
12
 
13
13
  ```ts
14
- import { createApp, cancelActiveTurn, closeDb } from "@schlessera/brain-ui-server";
14
+ import { createApp } from "@schlessera/brain-ui-server";
15
15
 
16
16
  const app = createApp({
17
17
  staticRoot: "./client/dist", // optional: serve a built SPA + fallback
18
18
  renderer, // optional: { renderPng, renderPdf }
19
19
  appName: "Brain UI", // branding in status copy
20
- dbPath: process.env.DB_PATH, // session/passkey SQLite (default ./brain-ui.db)
20
+ // config: resolveServerConfig(env) // optional: explicit configuration;
21
+ // // omitted = resolved from process.env once
21
22
  });
22
23
 
23
24
  export default {
@@ -27,9 +28,12 @@ export default {
27
28
  };
28
29
  ```
29
30
 
30
- One app per process: `createApp()` configures a process-wide host (WebSocket
31
- coordinator, SQLite handle, backend registry) calling it twice with
32
- different options reconfigures the first app rather than creating a second.
31
+ Apps are self-contained: each `createApp()` call builds its own WebSocket
32
+ coordinator, SQLite handle and backend registry from its (resolved or
33
+ injected) configuration, so two differently-configured apps coexist in one
34
+ process. The returned handle carries `config`, `db`, `wsHost`,
35
+ `isTurnActive()`, `cancelActiveTurns()` and `close()` for the deployment
36
+ shell's lifecycle wiring.
33
37
 
34
38
  ## What it owns
35
39
 
@@ -58,13 +62,48 @@ different options reconfigures the first app rather than creating a second.
58
62
 
59
63
  ## Environment
60
64
 
61
- The package reads the same env contract the brain-ui deployment documents:
62
- `AUTH_MODE`, `BRAIN_UI_PASSWORD_HASH`, `COOKIE_SECRET`, `TRUST_PROXY`,
63
- `WEBAUTHN_*`, `BRAIN_PATH`, `DB_PATH`, `AGENT_BACKEND`,
64
- `BRAIN_UI_CLAUDE_PROFILES`, `BRAIN_UI_MODEL_DISCOVERY`,
65
- `BRAIN_UI_MODEL_TTL_HOURS`, `MAX_CONCURRENT_SESSIONS`, `DEEPGRAM_API_KEY`,
66
- `VOICE_*`, `NOMINATIM_*`, `ALLOWED_ORIGINS`. `createApp()` options win over
67
- env where both exist.
65
+ Every variable this package reads, and what happens when it is unset.
66
+ `createApp()` configuration wins over the environment where both exist.
67
+
68
+ <!-- env:begin -->
69
+
70
+ | Variable | What it controls | Unset |
71
+ | --- | --- | --- |
72
+ | `AGENT_BACKEND` | Primary agent backend: "claude" (default) or "pi". | claude |
73
+ | `ALLOWED_ORIGINS` | Comma-separated cross-origin allowlist for a split client/API topology; empty means same-origin only. | (empty) |
74
+ | `AUTH_MODE` | Authentication mode: password \| tailscale \| proxy \| none. Unset auto-detects (password when a hash is set, else tailscale). | (auto-detect) |
75
+ | `BRAIN_PATH` | Path to the brain repo the server operates on. | $HOME/brain |
76
+ | `BRAIN_UI_ALLOW_LOOPBACK_ORIGIN` | Set "1" to accept loopback Origins for WebAuthn regardless of Host (dev-only, for the vite proxy). | 0 |
77
+ | `BRAIN_UI_ALLOW_PASSWORD` | Set "1" to keep password login enabled after a passkey exists for the RP (break-glass recovery). | 0 |
78
+ | `BRAIN_UI_CLAUDE_DEFAULT_MODEL` | Model the built-in default Claude profile is pinned to. | claude-sonnet-4-6 |
79
+ | `BRAIN_UI_CLAUDE_PROFILES` | JSON array of extra Anthropic-compatible inference profiles ({id,label,model?,baseUrl?,authTokenEnv?,apiKeyEnv?,modelAliases?}). | (none) |
80
+ | `BRAIN_UI_DANGEROUSLY_DISABLE_AUTH` | Set "1" to allow AUTH_MODE=none on a non-loopback host. Every network peer gets full agent access. | 0 |
81
+ | `BRAIN_UI_MODEL_DISCOVERY` | Model discovery against the Anthropic Models API; "0"/"off"/"false" disables. Defaults ON, except under a test runner (NODE_ENV=test) where it defaults OFF. | on (off under NODE_ENV=test) |
82
+ | `BRAIN_UI_MODEL_TTL_HOURS` | How long a model-discovery result stays fresh, in hours. | 24 |
83
+ | `BRAIN_UI_PASSWORD_HASH` | Bun.password argon2id hash of the shared password. | **required** — AUTH_MODE=password |
84
+ | `CLAUDE_CODE_PATH` | Path to the Claude Code native binary handed to the Agent SDK. | /usr/local/bin/claude |
85
+ | `COOKIE_SECRET` | Secret signing the session cookie. | **required** — AUTH_MODE=password |
86
+ | `DB_PATH` | SQLite file for the UI's own database (sessions, passkeys, settings). | ./brain-ui.db |
87
+ | `DEEPGRAM_API_KEY` | Deepgram API key for streaming ASR (short-lived tokens are minted from it). | **required** — VOICE_PROVIDER=deepgram (or any voice use without VOICE_PROVIDER=webspeech) |
88
+ | `HOME` | Fallback anchor for the BRAIN_PATH default only. | /root |
89
+ | `HOST` | Bind host; consulted by the auth validation to decide whether AUTH_MODE=none is loopback-safe. | (empty) |
90
+ | `MAX_CONCURRENT_SESSIONS` | Cap on concurrently RUNNING agent sessions. | 3 |
91
+ | `NODE_ENV` | Only consulted for test-runner detection: flips the model-discovery default to off under bun test. Never gates any security behavior. | (unset) |
92
+ | `PROXY_AUTH_HEADER` | Header a fronting auth proxy sets for AUTH_MODE=proxy. | x-forwarded-user |
93
+ | `SOURCE_COMMIT` | Git SHA reported by /api/status (baked at image build time). | dev |
94
+ | `TRUST_PROXY` | Set "1" to trust x-forwarded-for/x-real-ip and the proxy auth header; only safe behind a trusted reverse proxy. | **required** — AUTH_MODE=proxy |
95
+ | `TRUST_PROXY_HOPS` | How many trusted proxies front the app (x-forwarded-for parse depth). | 1 |
96
+ | `VOICE_CACHE_DIR` | Directory holding the keyterm cache JSON. | $BRAIN_PATH/.brain-ui |
97
+ | `VOICE_KEYTERM_LIMIT` | Maximum custom-vocabulary terms built from the brain database. | 500 |
98
+ | `VOICE_PROVIDER` | Speech provider: "deepgram" or "webspeech" (opt-in only — Chromium streams audio to Google). Unset auto-detects deepgram when its key is present. | (auto-detect) |
99
+ | `WEBAUTHN_ORIGINS` | Comma-separated extra origins allowed for WebAuthn ceremonies. | (empty) |
100
+ | `WEBAUTHN_RP_ID` | Relying-party id override for proxies that rewrite Host. | (derived from the request origin) |
101
+ | `WEBAUTHN_RP_NAME` | Relying-party display name shown by authenticators. | Brain UI |
102
+ | `WEBAUTHN_USER_ID` | Stable WebAuthn user handle (wire contract — burned into every resident credential; max 64 bytes; never change it after the first passkey). | brain-ui-owner |
103
+ | `WEBAUTHN_USER_NAME` | WebAuthn user name shown by authenticators. | owner |
104
+
105
+ Generated from `packages/ui-server/src/config/env.ts` by `bun run env-docs`. Edit the descriptor, not this table.
106
+ <!-- env:end -->
68
107
 
69
108
  Model discovery is on by default and needs no configuration beyond the Claude
70
109
  credential the agent already uses (`CLAUDE_CODE_OAUTH_TOKEN` or
@@ -1,45 +1,171 @@
1
- import { type ModelSource } from "@schlessera/brain-backend-claude";
1
+ import type { AgentConfig } from "../config/env.js";
2
2
  import type { ProviderInfo } from "@schlessera/brain-ui-sdk";
3
3
  import type { AgentBackend, BackendCapabilities } from "@schlessera/brain-ui-sdk/server";
4
- /** Drop the memo so the next read reflects a refresh or a settings change. */
5
- export declare function invalidateProfiles(): void;
6
4
  /**
7
- * The Claude backend's discovery source, once the registry is built. Null when
8
- * discovery is disabled or the deployment runs a different backend.
5
+ * Backend registry for one app instance. Built by `createApp()` from the
6
+ * resolved configuration no ambient environment and no module-level state,
7
+ * so two apps with different backend configuration coexist in one process and
8
+ * tests install fakes by constructing a registry, not by mutating a module.
9
+ *
10
+ * BOTH backend packages are optional peers loaded lazily (the same
11
+ * `createRequire` path): a deployment installs the one its AGENT_BACKEND
12
+ * names, and the other never has to be present — at runtime AND at
13
+ * type-check time (see the structural mirrors below).
14
+ *
15
+ * The old five hardcoded personal inference profiles are gone: the Claude
16
+ * backend ships the single "claude" default, and additional Anthropic-compatible
17
+ * endpoints are declared via the BRAIN_UI_CLAUDE_PROFILES env var (documented in
18
+ * .env.example) rather than in code.
9
19
  */
10
- export declare function getModelSource(): Promise<ModelSource | null>;
11
- /** All configured backends, with the default backend first. */
12
- export declare function getBackends(): Promise<AgentBackend[]>;
13
- /** Find a configured backend by its stable id. */
14
- export declare function getBackendById(id: string): Promise<AgentBackend | undefined>;
15
- /** The default backend used for new and legacy sessions. */
16
- export declare function getDefaultBackend(): Promise<AgentBackend>;
17
- /** The stable id of the default backend. */
18
- export declare function getDefaultBackendId(): Promise<string>;
19
- /** Resolve the backend that owns a globally unique profile id. */
20
- export declare function getBackendForProfile(profileId: string): Promise<AgentBackend | undefined>;
21
- /** Resolve a persisted backend id, falling back for legacy/unknown sessions. */
22
- export declare function getBackendForSession(backendId: string | null | undefined): Promise<AgentBackend>;
20
+ /** Mirror of the Claude package's `InferenceProfileInput` (declarative shape). */
21
+ export interface ClaudeProfileInput {
22
+ id: string;
23
+ label: string;
24
+ vendor?: string;
25
+ /** Model id. Undefined = the SDK/CLI default model. */
26
+ model?: string;
27
+ /** Anthropic-compatible endpoint. */
28
+ baseUrl?: string;
29
+ /** Name of the env var holding a bearer token. */
30
+ authTokenEnv?: string;
31
+ /** Name of the env var holding an x-api-key. */
32
+ apiKeyEnv?: string;
33
+ /** Remap the CLI's model-alias envs to `model`. Requires `model`. */
34
+ modelAliases?: boolean;
35
+ allowedTools?: string[];
36
+ /** Context window in tokens, when known. Presentation only. */
37
+ contextWindow?: number;
38
+ /** Where this profile came from. Presentation only. */
39
+ source?: "builtin" | "declared" | "discovered";
40
+ }
41
+ /** Mirror of the Claude package's resolved `InferenceProfile`. */
42
+ export interface ClaudeProfile {
43
+ id: string;
44
+ label: string;
45
+ vendor?: string;
46
+ model?: string;
47
+ allowedTools?: string[];
48
+ contextWindow?: number;
49
+ source?: "builtin" | "declared" | "discovered";
50
+ /** Env vars that must be present (non-empty) for this profile to be usable. */
51
+ requiredEnvKeys: string[];
52
+ /** Environment overrides merged over the host environment. */
53
+ buildEnv: () => Record<string, string>;
54
+ }
23
55
  /**
24
- * Every available profile, tagged with its owning backend id.
56
+ * The slice of the lazily-required Claude module this registry drives. The
57
+ * real module carries more (and looser-optional) options; assignability is
58
+ * asserted in tests/declaration-surface.test.ts.
59
+ */
60
+ export interface ClaudeBackendModule {
61
+ createClaudeBackend: (options: {
62
+ brainPath: string;
63
+ claudeCodePath?: string;
64
+ profiles?: ClaudeProfile[] | (() => ClaudeProfile[]);
65
+ }) => AgentBackend;
66
+ createModelSource: (options: {
67
+ brainPath: string;
68
+ ttlMs?: number;
69
+ enabled?: boolean;
70
+ }) => ClaudeModelSource;
71
+ defineProfiles: (inputs: ClaudeProfileInput[]) => ClaudeProfile[];
72
+ }
73
+ /** Discovery source as the registry internals see it: the public slice + list(). */
74
+ export interface ClaudeModelSource extends ModelDiscoverySource {
75
+ list: () => ClaudeProfileInput[];
76
+ }
77
+ /**
78
+ * Discovery freshness, as exposed on the public registry surface.
25
79
  *
26
- * Hidden profiles are omitted by default (this feeds the picker); the settings
27
- * screen passes `includeHidden` to render the full catalog.
80
+ * `list()` is omitted on purpose it returns Claude profile inputs, only the
81
+ * registry internals consume it (see {@link ClaudeModelSource}), and exposing
82
+ * it would put those types on every consumer's plate for no reader.
28
83
  */
29
- export declare function listAllProviders(options?: {
30
- includeHidden?: boolean;
31
- }): Promise<ProviderInfo[]>;
32
- /** Per-backend capability metadata exposed by the providers route. */
33
- export declare function getBackendsInfo(): Promise<Record<string, {
34
- id: string;
35
- capabilities: BackendCapabilities;
36
- }>>;
37
- /** @deprecated Use getDefaultBackend() or a routing-specific accessor. */
38
- export declare function getBackend(): Promise<AgentBackend>;
39
- /** Test seam: drop the cached registry so later access rebuilds from env. */
40
- export declare function resetBackendForTests(): void;
41
- /** Test seam: install one fake backend as the complete registry. */
42
- export declare function setBackendForTests(backend: AgentBackend): void;
43
- /** Test seam: install a complete fake registry with an explicit default. */
44
- export declare function setBackendsForTests(backends: AgentBackend[], defaultBackendId?: string): void;
84
+ export interface ModelDiscoveryState {
85
+ enabled: boolean;
86
+ /** When discovery last succeeded; null when it never has. */
87
+ refreshedAt: number | null;
88
+ /** The cached result is older than the TTL (or absent). */
89
+ stale: boolean;
90
+ /** Last discovery failure, if the current list is served despite one. */
91
+ error?: string;
92
+ }
93
+ /** The slice of the Claude backend's discovery source the routes consume. */
94
+ export interface ModelDiscoverySource {
95
+ state(): ModelDiscoveryState;
96
+ /** Refresh if stale. Awaits only when there is nothing cached to serve. */
97
+ ensureFresh(): Promise<void>;
98
+ /** Force a refresh regardless of TTL. Rejects on failure. */
99
+ refresh(): Promise<void>;
100
+ }
101
+ export interface BackendRegistryOptions {
102
+ /** Where the brain repo lives (handed to every backend). */
103
+ brainPath: string;
104
+ /** Resolved agent configuration (AGENT_BACKEND, profiles, discovery...). */
105
+ agent: AgentConfig;
106
+ /**
107
+ * Profile ids the user keeps out of the model picker (from the app's
108
+ * settings table). Presentation only — a hidden profile still resolves for
109
+ * sessions pinned to it. Defaults to "nothing hidden".
110
+ */
111
+ getHiddenModelIds?: () => string[];
112
+ }
113
+ export interface BackendRegistry {
114
+ /** All configured backends, with the default backend first. */
115
+ getBackends(): Promise<AgentBackend[]>;
116
+ /** Find a configured backend by its stable id. */
117
+ getBackendById(id: string): Promise<AgentBackend | undefined>;
118
+ /** The default backend used for new and legacy sessions. */
119
+ getDefaultBackend(): Promise<AgentBackend>;
120
+ /** The stable id of the default backend. */
121
+ getDefaultBackendId(): Promise<string>;
122
+ /** Resolve the backend that owns a globally unique profile id. */
123
+ getBackendForProfile(profileId: string): Promise<AgentBackend | undefined>;
124
+ /** Resolve a persisted backend id, falling back for legacy/unknown sessions. */
125
+ getBackendForSession(backendId: string | null | undefined): Promise<AgentBackend>;
126
+ /**
127
+ * Every available profile, tagged with its owning backend id. Hidden
128
+ * profiles are omitted by default (this feeds the picker); the settings
129
+ * screen passes `includeHidden` to render the full catalog.
130
+ */
131
+ listAllProviders(options?: {
132
+ includeHidden?: boolean;
133
+ }): Promise<ProviderInfo[]>;
134
+ /** Per-backend capability metadata exposed by the providers route. */
135
+ getBackendsInfo(): Promise<Record<string, {
136
+ id: string;
137
+ capabilities: BackendCapabilities;
138
+ }>>;
139
+ /**
140
+ * The Claude backend's discovery source, once the registry is built. Null
141
+ * when discovery is disabled or the deployment runs a different backend.
142
+ */
143
+ getModelSource(): Promise<ModelDiscoverySource | null>;
144
+ /** Drop the profile memo so the next read reflects a refresh or settings change. */
145
+ invalidateProfiles(): void;
146
+ }
147
+ /**
148
+ * Boot-time guard: the SELECTED backend's package must at least RESOLVE, so a
149
+ * broken install refuses to start instead of reporting healthy and failing
150
+ * every agent turn (the guarantee the old static import gave, restored without
151
+ * giving up the lazy load — `require.resolve` never executes the module, so
152
+ * the Agent SDK still loads on first use only). Called by `createApp()` next
153
+ * to the auth assertions; skipped when an explicit registry is injected.
154
+ *
155
+ * An unrecognized AGENT_BACKEND fails here too, for the same reason.
156
+ *
157
+ * The `resolve` parameter exists for tests (simulating an absent package);
158
+ * production callers pass nothing.
159
+ */
160
+ export declare function assertBackendResolvable(agent: AgentConfig, resolve?: (specifier: string) => void): void;
161
+ export declare function createBackendRegistry(options: BackendRegistryOptions): BackendRegistry;
162
+ /**
163
+ * A registry over an explicit backend list — the seam tests (and embedders
164
+ * with their own backend wiring) use instead of mutating module state. Takes
165
+ * the same optional hidden-ids reader so visibility behavior matches
166
+ * production.
167
+ */
168
+ export declare function createStaticBackendRegistry(backends: AgentBackend[], defaultBackendId?: string, options?: {
169
+ getHiddenModelIds?: () => string[];
170
+ }): BackendRegistry;
45
171
  //# sourceMappingURL=backend.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/agent/backend.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACpB,MAAM,iCAAiC,CAAC;AA6FzC,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAGlE;AAwHD,+DAA+D;AAC/D,wBAAsB,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAE3D;AAED,kDAAkD;AAClD,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAEnC;AAED,4DAA4D;AAC5D,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,YAAY,CAAC,CAG/D;AAED,4CAA4C;AAC5C,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAE3D;AAED,kEAAkE;AAClE,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAOnC;AAED,gFAAgF;AAChF,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,OAAO,CAAC,YAAY,CAAC,CAMvB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACxC,OAAO,CAAC,YAAY,EAAE,CAAC,CAUzB;AAED,sEAAsE;AACtE,wBAAsB,eAAe,IAAI,OAAO,CAC9C,MAAM,CAAC,MAAM,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAClE,CAQA;AAED,0EAA0E;AAC1E,wBAAsB,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC,CAExD;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAG9D;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EAAE,EACxB,gBAAgB,SAAwB,GACvC,IAAI,CAGN"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/agent/backend.ts"],"names":[],"mappings":"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"}