@camstack/addon-notifiers 1.2.604 → 1.2.605

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 (3) hide show
  1. package/dist/addon.js +165 -102
  2. package/dist/addon.mjs +165 -102
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -5577,7 +5577,7 @@ var ZodIssueCode = {
5577
5577
  var ZodFirstPartyTypeKind;
5578
5578
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5579
5579
  //#endregion
5580
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5580
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5581
5581
  /**
5582
5582
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5583
5583
  * window to float samples (D455).
@@ -7960,9 +7960,9 @@ function normalizeAddonInitResult(result) {
7960
7960
  return result;
7961
7961
  }
7962
7962
  /**
7963
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7964
- * and validates them (`share-token.service.ts` builds its enum from this
7965
- * list); a data plane names the kinds it ACCEPTS in `share`.
7963
+ * The share-view scope kinds a share-link token can carry. The hub mints
7964
+ * and validates them (`ShareViewGrantSchema` builds its
7965
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7966
7966
  */
7967
7967
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7968
7968
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12938,7 +12938,7 @@ var ConvertResultSchema = object({
12938
12938
  * `super_admin` — collapsed onto the single boolean because every
12939
12939
  * non-admin caller is governed by the same scope-check rules; the
12940
12940
  * distinction was only ever used to route role-specific procedures
12941
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12941
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12942
12942
  * with `isAdmin: false` + an explicit scope list.
12943
12943
  */
12944
12944
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -13127,10 +13127,12 @@ var AddonRoutesScopeSchema = object({
13127
13127
  type: literal("addon-routes"),
13128
13128
  access: array(MethodAccessSchema).min(1)
13129
13129
  });
13130
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
13130
13131
  var CredentialScopeSchema = union([
13131
13132
  literal("*"),
13132
13133
  ShareViewScopeSchema,
13133
13134
  AddonRoutesScopeSchema,
13135
+ PreferencesSelfScopeSchema,
13134
13136
  TokenScopeSchema
13135
13137
  ]);
13136
13138
  object({
@@ -13139,6 +13141,55 @@ object({
13139
13141
  jti: string().min(16),
13140
13142
  scopes: array(CredentialScopeSchema).min(1)
13141
13143
  });
13144
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
13145
+ /** A namespace's value: a JSON object, opaque to the hub. */
13146
+ var PreferenceValueSchema = record(string(), unknown());
13147
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
13148
+ /** A stored row, as the owner reads it. */
13149
+ var PreferenceRowSchema = object({
13150
+ namespace: PreferenceNamespaceSchema,
13151
+ value: PreferenceValueSchema,
13152
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
13153
+ revision: number().int().positive(),
13154
+ updatedAt: number().int(),
13155
+ /** The client id the last writer sent; `null` when it sent none. */
13156
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
13157
+ });
13158
+ object({
13159
+ /** Absent: every namespace the caller holds. */
13160
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
13161
+ object({ rows: array(PreferenceRowSchema) });
13162
+ object({
13163
+ namespace: PreferenceNamespaceSchema,
13164
+ value: PreferenceValueSchema,
13165
+ /**
13166
+ * The revision the edit was based on. Absent: last write wins. `0`: the
13167
+ * namespace must not exist yet. Any other value that is not the current
13168
+ * revision answers `conflict` and writes nothing.
13169
+ */
13170
+ baseRevision: number().int().nonnegative().optional(),
13171
+ deviceId: PreferenceDeviceIdSchema.optional()
13172
+ });
13173
+ discriminatedUnion("status", [object({
13174
+ status: literal("saved"),
13175
+ row: PreferenceRowSchema
13176
+ }), object({
13177
+ status: literal("conflict"),
13178
+ current: PreferenceRowSchema.nullable()
13179
+ })]);
13180
+ object({ namespace: PreferenceNamespaceSchema });
13181
+ object({
13182
+ /** `false` when the namespace did not exist. */
13183
+ deleted: boolean() });
13184
+ object({
13185
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
13186
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
13187
+ object({
13188
+ /** Every row whose revision differs from the client's, and every row it did not list. */
13189
+ rows: array(PreferenceRowSchema),
13190
+ /** Namespaces the client listed that no longer exist. */
13191
+ deleted: array(PreferenceNamespaceSchema)
13192
+ });
13142
13193
  _enum(["new-session", "step-up"]);
13143
13194
  /** The languages the hub's app landing pages are written in (D858). */
13144
13195
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -40036,38 +40087,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
40036
40087
  auth: "admin",
40037
40088
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40038
40089
  });
40090
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40091
+ /** What a model (or, by default, every model of a kind) can do. */
40092
+ var LlmModelFeaturesSchema = object({
40093
+ vision: boolean(),
40094
+ tools: boolean(),
40095
+ streaming: boolean()
40096
+ });
40097
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40098
+ var LlmModelInfoSchema = object({
40099
+ id: string(),
40100
+ label: string().optional(),
40101
+ contextLength: number().int().positive().optional(),
40102
+ features: LlmModelFeaturesSchema.partial().optional()
40103
+ });
40039
40104
  /**
40040
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
40041
- * methods concat-fan across providers; single-row methods route to ONE
40042
- * provider by the `addonId` in the call input (the notification-output
40043
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40044
- * (hub-placed); the cap stays open for future providers.
40045
- *
40046
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40047
- * `apiKey` is a password field — providers REDACT it on read and merge on
40048
- * write; a stored key NEVER round-trips to a client.
40105
+ * The provider-specific part of a profile, validated by the provider that owns
40106
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40107
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40108
+ * keychain, never in the row, and reads back as the redaction marker.
40049
40109
  */
40050
- var LlmProfileKindSchema = _enum([
40051
- "openai-compatible",
40052
- "openai",
40053
- "anthropic",
40054
- "google",
40055
- "managed-local",
40056
- "apple-foundation"
40057
- ]);
40110
+ var LlmProviderConfigSchema = record(string(), unknown());
40058
40111
  var LlmProfileSchema = object({
40059
40112
  id: string(),
40060
40113
  name: string(),
40114
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40061
40115
  kind: LlmProfileKindSchema,
40062
40116
  /** Stamped by the provider — keeps the fanned catalog routable. */
40063
40117
  addonId: string(),
40064
40118
  enabled: boolean(),
40065
40119
  /** Vendor model id, or the managed runtime's loaded model. */
40066
40120
  model: string(),
40067
- /** Required for openai-compatible; override for cloud kinds. */
40068
- baseUrl: string().optional(),
40069
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40070
- apiKey: string().optional(),
40071
40121
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40072
40122
  * degraded to text — that shipped once and produced a confident answer to a
40073
40123
  * question about a picture nobody sent. */
@@ -40075,15 +40125,11 @@ var LlmProfileSchema = object({
40075
40125
  temperature: number().min(0).max(2).optional(),
40076
40126
  /** Nucleus sampling. Every wire we speak has it. */
40077
40127
  topP: number().min(0).max(1).optional(),
40078
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40079
- * wire does, and the client drops it there (measured: the request body gets
40080
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40081
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40128
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40129
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40082
40130
  topK: number().int().positive().optional(),
40083
40131
  maxTokens: number().int().positive().optional(),
40084
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40085
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40086
- * the model with, so it is the one field that changes a PROCESS. */
40132
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40087
40133
  contextLength: number().int().positive().optional(),
40088
40134
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40089
40135
  * two system prompts fighting is worse than either alone). */
@@ -40109,16 +40155,37 @@ var LlmProfileSchema = object({
40109
40155
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40110
40156
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40111
40157
  toolsEnabled: boolean().default(false),
40112
- extraHeaders: record(string(), string()).optional(),
40113
- /** kind === 'managed-local' only (spec §4). */
40114
- runtime: ManagedRuntimeConfigSchema.optional(),
40115
- /**
40116
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40117
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40118
- * `supportsVision` on such a row is stamped by the provider from the node's
40119
- * reported `imageInput`, never taken from the operator (D62).
40120
- */
40121
- appleFoundation: object({ nodeId: string() }).optional()
40158
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40159
+ providerConfig: LlmProviderConfigSchema.default({})
40160
+ });
40161
+ /**
40162
+ * The common profile fields a kind's editor offers. The editor owns how each
40163
+ * one is drawn; the provider says which of them mean something on its wire.
40164
+ */
40165
+ var LlmProfileFieldSchema = _enum([
40166
+ "temperature",
40167
+ "topP",
40168
+ "topK",
40169
+ "maxTokens",
40170
+ "contextLength",
40171
+ "systemPrompt",
40172
+ "timeoutMs",
40173
+ "connectTimeoutMs",
40174
+ "firstTokenTimeoutMs",
40175
+ "idleTimeoutMs",
40176
+ "retry",
40177
+ "toolsEnabled"
40178
+ ]);
40179
+ /**
40180
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40181
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40182
+ * picker: that widget owns the model choice.
40183
+ */
40184
+ var LlmProviderWidgetSchema = object({
40185
+ id: string(),
40186
+ placement: _enum(["connection", "model"]),
40187
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40188
+ requires: array(string()).optional()
40122
40189
  });
40123
40190
  /** ConfigUISchema tree passed through untyped on the wire (the
40124
40191
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40127,11 +40194,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40127
40194
  var LlmProfileKindDescriptorSchema = object({
40128
40195
  kind: LlmProfileKindSchema,
40129
40196
  label: string(),
40197
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40130
40198
  icon: string(),
40131
40199
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40132
40200
  addonId: string(),
40133
- configSchema: ConfigSchemaPassthrough$3
40201
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40202
+ connectionSchema: ConfigSchemaPassthrough$3,
40203
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40204
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40205
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40206
+ features: LlmModelFeaturesSchema,
40207
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40208
+ visionEditable: boolean(),
40209
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40210
+ modelCatalog: _enum([
40211
+ "fetch",
40212
+ "static",
40213
+ "none"
40214
+ ]),
40215
+ staticModels: array(LlmModelInfoSchema).optional(),
40216
+ /** The common fields that mean something on this kind's wire. */
40217
+ profileFields: array(LlmProfileFieldSchema),
40218
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40134
40219
  });
40220
+ /**
40221
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40222
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40223
+ * untouched (absent or the redaction marker) is resolved server-side from the
40224
+ * stored profile — the browser never receives it.
40225
+ */
40226
+ var LlmListModelsInputSchema = object({
40227
+ addonId: string(),
40228
+ kind: LlmProfileKindSchema,
40229
+ profileId: string().optional(),
40230
+ connection: LlmProviderConfigSchema.optional()
40231
+ });
40232
+ var LlmListModelsErrorCodeSchema = _enum([
40233
+ "auth",
40234
+ "network",
40235
+ "unsupported",
40236
+ "invalid"
40237
+ ]);
40238
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40239
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40240
+ ok: literal(true),
40241
+ models: array(LlmModelInfoSchema)
40242
+ }), object({
40243
+ ok: literal(false),
40244
+ code: LlmListModelsErrorCodeSchema,
40245
+ message: string()
40246
+ })]);
40135
40247
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40136
40248
  var LlmDefaultSchema = object({
40137
40249
  selector: LlmDefaultSelectorSchema,
@@ -40231,7 +40343,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40231
40343
  kind: "mutation",
40232
40344
  auth: "admin",
40233
40345
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40234
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40346
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40347
+ kind: "mutation",
40348
+ auth: "admin"
40349
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40235
40350
  selector: LlmDefaultSelectorSchema,
40236
40351
  profileId: string().nullable()
40237
40352
  }), _void(), {
@@ -61248,26 +61363,6 @@ var ApiKeySummarySchema = object({
61248
61363
  createdAt: number(),
61249
61364
  lastUsedAt: number().optional()
61250
61365
  });
61251
- var ScopedTokenSummarySchema = object({
61252
- id: string(),
61253
- userId: string(),
61254
- name: string(),
61255
- tokenPrefix: string(),
61256
- scopes: array(TokenScopeSchema),
61257
- expiresAt: number().nullish(),
61258
- lastUsedAt: number().nullish(),
61259
- createdAt: number()
61260
- });
61261
- var CreateScopedTokenInputSchema = object({
61262
- userId: string(),
61263
- name: string(),
61264
- scopes: array(TokenScopeSchema),
61265
- expiresAt: number().optional()
61266
- });
61267
- var CreateScopedTokenResultSchema = object({
61268
- token: string(),
61269
- record: ScopedTokenSummarySchema
61270
- });
61271
61366
  var OauthSessionSummarySchema = object({
61272
61367
  id: string(),
61273
61368
  userId: string(),
@@ -61289,11 +61384,11 @@ var TotpStatusSchema = object({
61289
61384
  confirmedAt: number().nullable()
61290
61385
  });
61291
61386
  /**
61292
- * user-management — singleton capability for user accounts, API keys,
61293
- * and scoped tokens.
61387
+ * user-management — singleton capability for user accounts and the
61388
+ * legacy API-key rows.
61294
61389
  *
61295
61390
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
61296
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
61391
+ * — the subset check on `setUserScopes` is moot
61297
61392
  * because non-admins never reach these. If/when we open non-admin
61298
61393
  * delegation, structural caller-scope subset check goes inside the
61299
61394
  * provider.
@@ -61350,15 +61445,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
61350
61445
  kind: "mutation",
61351
61446
  auth: "admin",
61352
61447
  access: "delete"
61353
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
61354
- kind: "mutation",
61355
- auth: "admin",
61356
- access: "create"
61357
- }), method(object({ id: string() }), object({ success: literal(true) }), {
61358
- kind: "mutation",
61359
- auth: "admin",
61360
- access: "delete"
61361
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
61448
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
61362
61449
  kind: "mutation",
61363
61450
  auth: "admin",
61364
61451
  access: "create"
@@ -65514,7 +65601,7 @@ Object.freeze({
65514
65601
  capName: "llm",
65515
65602
  capScope: "system",
65516
65603
  addonId: null,
65517
- access: "view"
65604
+ access: "create"
65518
65605
  },
65519
65606
  "llm.listNodeModels": {
65520
65607
  capName: "llm",
@@ -70178,12 +70265,6 @@ Object.freeze({
70178
70265
  addonId: null,
70179
70266
  access: "create"
70180
70267
  },
70181
- "userManagement.createScopedToken": {
70182
- capName: "user-management",
70183
- capScope: "system",
70184
- addonId: null,
70185
- access: "create"
70186
- },
70187
70268
  "userManagement.createUser": {
70188
70269
  capName: "user-management",
70189
70270
  capScope: "system",
@@ -70232,12 +70313,6 @@ Object.freeze({
70232
70313
  addonId: null,
70233
70314
  access: "view"
70234
70315
  },
70235
- "userManagement.listScopedTokens": {
70236
- capName: "user-management",
70237
- capScope: "system",
70238
- addonId: null,
70239
- access: "view"
70240
- },
70241
70316
  "userManagement.listUsers": {
70242
70317
  capName: "user-management",
70243
70318
  capScope: "system",
@@ -70292,12 +70367,6 @@ Object.freeze({
70292
70367
  addonId: null,
70293
70368
  access: "delete"
70294
70369
  },
70295
- "userManagement.revokeScopedToken": {
70296
- capName: "user-management",
70297
- capScope: "system",
70298
- addonId: null,
70299
- access: "delete"
70300
- },
70301
70370
  "userManagement.setupTotp": {
70302
70371
  capName: "user-management",
70303
70372
  capScope: "system",
@@ -70328,12 +70397,6 @@ Object.freeze({
70328
70397
  addonId: null,
70329
70398
  access: "view"
70330
70399
  },
70331
- "userManagement.validateScopedToken": {
70332
- capName: "user-management",
70333
- capScope: "system",
70334
- addonId: null,
70335
- access: "view"
70336
- },
70337
70400
  "userManagement.verifyTotp": {
70338
70401
  capName: "user-management",
70339
70402
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -5550,7 +5550,7 @@ var ZodIssueCode = {
5550
5550
  var ZodFirstPartyTypeKind;
5551
5551
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5552
5552
  //#endregion
5553
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5553
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5554
5554
  /**
5555
5555
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5556
5556
  * window to float samples (D455).
@@ -7933,9 +7933,9 @@ function normalizeAddonInitResult(result) {
7933
7933
  return result;
7934
7934
  }
7935
7935
  /**
7936
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7937
- * and validates them (`share-token.service.ts` builds its enum from this
7938
- * list); a data plane names the kinds it ACCEPTS in `share`.
7936
+ * The share-view scope kinds a share-link token can carry. The hub mints
7937
+ * and validates them (`ShareViewGrantSchema` builds its
7938
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7939
7939
  */
7940
7940
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7941
7941
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12911,7 +12911,7 @@ var ConvertResultSchema = object({
12911
12911
  * `super_admin` — collapsed onto the single boolean because every
12912
12912
  * non-admin caller is governed by the same scope-check rules; the
12913
12913
  * distinction was only ever used to route role-specific procedures
12914
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12914
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12915
12915
  * with `isAdmin: false` + an explicit scope list.
12916
12916
  */
12917
12917
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -13100,10 +13100,12 @@ var AddonRoutesScopeSchema = object({
13100
13100
  type: literal("addon-routes"),
13101
13101
  access: array(MethodAccessSchema).min(1)
13102
13102
  });
13103
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
13103
13104
  var CredentialScopeSchema = union([
13104
13105
  literal("*"),
13105
13106
  ShareViewScopeSchema,
13106
13107
  AddonRoutesScopeSchema,
13108
+ PreferencesSelfScopeSchema,
13107
13109
  TokenScopeSchema
13108
13110
  ]);
13109
13111
  object({
@@ -13112,6 +13114,55 @@ object({
13112
13114
  jti: string().min(16),
13113
13115
  scopes: array(CredentialScopeSchema).min(1)
13114
13116
  });
13117
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
13118
+ /** A namespace's value: a JSON object, opaque to the hub. */
13119
+ var PreferenceValueSchema = record(string(), unknown());
13120
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
13121
+ /** A stored row, as the owner reads it. */
13122
+ var PreferenceRowSchema = object({
13123
+ namespace: PreferenceNamespaceSchema,
13124
+ value: PreferenceValueSchema,
13125
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
13126
+ revision: number().int().positive(),
13127
+ updatedAt: number().int(),
13128
+ /** The client id the last writer sent; `null` when it sent none. */
13129
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
13130
+ });
13131
+ object({
13132
+ /** Absent: every namespace the caller holds. */
13133
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
13134
+ object({ rows: array(PreferenceRowSchema) });
13135
+ object({
13136
+ namespace: PreferenceNamespaceSchema,
13137
+ value: PreferenceValueSchema,
13138
+ /**
13139
+ * The revision the edit was based on. Absent: last write wins. `0`: the
13140
+ * namespace must not exist yet. Any other value that is not the current
13141
+ * revision answers `conflict` and writes nothing.
13142
+ */
13143
+ baseRevision: number().int().nonnegative().optional(),
13144
+ deviceId: PreferenceDeviceIdSchema.optional()
13145
+ });
13146
+ discriminatedUnion("status", [object({
13147
+ status: literal("saved"),
13148
+ row: PreferenceRowSchema
13149
+ }), object({
13150
+ status: literal("conflict"),
13151
+ current: PreferenceRowSchema.nullable()
13152
+ })]);
13153
+ object({ namespace: PreferenceNamespaceSchema });
13154
+ object({
13155
+ /** `false` when the namespace did not exist. */
13156
+ deleted: boolean() });
13157
+ object({
13158
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
13159
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
13160
+ object({
13161
+ /** Every row whose revision differs from the client's, and every row it did not list. */
13162
+ rows: array(PreferenceRowSchema),
13163
+ /** Namespaces the client listed that no longer exist. */
13164
+ deleted: array(PreferenceNamespaceSchema)
13165
+ });
13115
13166
  _enum(["new-session", "step-up"]);
13116
13167
  /** The languages the hub's app landing pages are written in (D858). */
13117
13168
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -40009,38 +40060,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
40009
40060
  auth: "admin",
40010
40061
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40011
40062
  });
40063
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40064
+ /** What a model (or, by default, every model of a kind) can do. */
40065
+ var LlmModelFeaturesSchema = object({
40066
+ vision: boolean(),
40067
+ tools: boolean(),
40068
+ streaming: boolean()
40069
+ });
40070
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40071
+ var LlmModelInfoSchema = object({
40072
+ id: string(),
40073
+ label: string().optional(),
40074
+ contextLength: number().int().positive().optional(),
40075
+ features: LlmModelFeaturesSchema.partial().optional()
40076
+ });
40012
40077
  /**
40013
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
40014
- * methods concat-fan across providers; single-row methods route to ONE
40015
- * provider by the `addonId` in the call input (the notification-output
40016
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40017
- * (hub-placed); the cap stays open for future providers.
40018
- *
40019
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40020
- * `apiKey` is a password field — providers REDACT it on read and merge on
40021
- * write; a stored key NEVER round-trips to a client.
40078
+ * The provider-specific part of a profile, validated by the provider that owns
40079
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40080
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40081
+ * keychain, never in the row, and reads back as the redaction marker.
40022
40082
  */
40023
- var LlmProfileKindSchema = _enum([
40024
- "openai-compatible",
40025
- "openai",
40026
- "anthropic",
40027
- "google",
40028
- "managed-local",
40029
- "apple-foundation"
40030
- ]);
40083
+ var LlmProviderConfigSchema = record(string(), unknown());
40031
40084
  var LlmProfileSchema = object({
40032
40085
  id: string(),
40033
40086
  name: string(),
40087
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40034
40088
  kind: LlmProfileKindSchema,
40035
40089
  /** Stamped by the provider — keeps the fanned catalog routable. */
40036
40090
  addonId: string(),
40037
40091
  enabled: boolean(),
40038
40092
  /** Vendor model id, or the managed runtime's loaded model. */
40039
40093
  model: string(),
40040
- /** Required for openai-compatible; override for cloud kinds. */
40041
- baseUrl: string().optional(),
40042
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40043
- apiKey: string().optional(),
40044
40094
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40045
40095
  * degraded to text — that shipped once and produced a confident answer to a
40046
40096
  * question about a picture nobody sent. */
@@ -40048,15 +40098,11 @@ var LlmProfileSchema = object({
40048
40098
  temperature: number().min(0).max(2).optional(),
40049
40099
  /** Nucleus sampling. Every wire we speak has it. */
40050
40100
  topP: number().min(0).max(1).optional(),
40051
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40052
- * wire does, and the client drops it there (measured: the request body gets
40053
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40054
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40101
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40102
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40055
40103
  topK: number().int().positive().optional(),
40056
40104
  maxTokens: number().int().positive().optional(),
40057
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40058
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40059
- * the model with, so it is the one field that changes a PROCESS. */
40105
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40060
40106
  contextLength: number().int().positive().optional(),
40061
40107
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40062
40108
  * two system prompts fighting is worse than either alone). */
@@ -40082,16 +40128,37 @@ var LlmProfileSchema = object({
40082
40128
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40083
40129
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40084
40130
  toolsEnabled: boolean().default(false),
40085
- extraHeaders: record(string(), string()).optional(),
40086
- /** kind === 'managed-local' only (spec §4). */
40087
- runtime: ManagedRuntimeConfigSchema.optional(),
40088
- /**
40089
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40090
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40091
- * `supportsVision` on such a row is stamped by the provider from the node's
40092
- * reported `imageInput`, never taken from the operator (D62).
40093
- */
40094
- appleFoundation: object({ nodeId: string() }).optional()
40131
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40132
+ providerConfig: LlmProviderConfigSchema.default({})
40133
+ });
40134
+ /**
40135
+ * The common profile fields a kind's editor offers. The editor owns how each
40136
+ * one is drawn; the provider says which of them mean something on its wire.
40137
+ */
40138
+ var LlmProfileFieldSchema = _enum([
40139
+ "temperature",
40140
+ "topP",
40141
+ "topK",
40142
+ "maxTokens",
40143
+ "contextLength",
40144
+ "systemPrompt",
40145
+ "timeoutMs",
40146
+ "connectTimeoutMs",
40147
+ "firstTokenTimeoutMs",
40148
+ "idleTimeoutMs",
40149
+ "retry",
40150
+ "toolsEnabled"
40151
+ ]);
40152
+ /**
40153
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40154
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40155
+ * picker: that widget owns the model choice.
40156
+ */
40157
+ var LlmProviderWidgetSchema = object({
40158
+ id: string(),
40159
+ placement: _enum(["connection", "model"]),
40160
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40161
+ requires: array(string()).optional()
40095
40162
  });
40096
40163
  /** ConfigUISchema tree passed through untyped on the wire (the
40097
40164
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40100,11 +40167,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40100
40167
  var LlmProfileKindDescriptorSchema = object({
40101
40168
  kind: LlmProfileKindSchema,
40102
40169
  label: string(),
40170
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40103
40171
  icon: string(),
40104
40172
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40105
40173
  addonId: string(),
40106
- configSchema: ConfigSchemaPassthrough$3
40174
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40175
+ connectionSchema: ConfigSchemaPassthrough$3,
40176
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40177
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40178
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40179
+ features: LlmModelFeaturesSchema,
40180
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40181
+ visionEditable: boolean(),
40182
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40183
+ modelCatalog: _enum([
40184
+ "fetch",
40185
+ "static",
40186
+ "none"
40187
+ ]),
40188
+ staticModels: array(LlmModelInfoSchema).optional(),
40189
+ /** The common fields that mean something on this kind's wire. */
40190
+ profileFields: array(LlmProfileFieldSchema),
40191
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40107
40192
  });
40193
+ /**
40194
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40195
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40196
+ * untouched (absent or the redaction marker) is resolved server-side from the
40197
+ * stored profile — the browser never receives it.
40198
+ */
40199
+ var LlmListModelsInputSchema = object({
40200
+ addonId: string(),
40201
+ kind: LlmProfileKindSchema,
40202
+ profileId: string().optional(),
40203
+ connection: LlmProviderConfigSchema.optional()
40204
+ });
40205
+ var LlmListModelsErrorCodeSchema = _enum([
40206
+ "auth",
40207
+ "network",
40208
+ "unsupported",
40209
+ "invalid"
40210
+ ]);
40211
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40212
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40213
+ ok: literal(true),
40214
+ models: array(LlmModelInfoSchema)
40215
+ }), object({
40216
+ ok: literal(false),
40217
+ code: LlmListModelsErrorCodeSchema,
40218
+ message: string()
40219
+ })]);
40108
40220
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40109
40221
  var LlmDefaultSchema = object({
40110
40222
  selector: LlmDefaultSelectorSchema,
@@ -40204,7 +40316,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40204
40316
  kind: "mutation",
40205
40317
  auth: "admin",
40206
40318
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40207
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40319
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40320
+ kind: "mutation",
40321
+ auth: "admin"
40322
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40208
40323
  selector: LlmDefaultSelectorSchema,
40209
40324
  profileId: string().nullable()
40210
40325
  }), _void(), {
@@ -61221,26 +61336,6 @@ var ApiKeySummarySchema = object({
61221
61336
  createdAt: number(),
61222
61337
  lastUsedAt: number().optional()
61223
61338
  });
61224
- var ScopedTokenSummarySchema = object({
61225
- id: string(),
61226
- userId: string(),
61227
- name: string(),
61228
- tokenPrefix: string(),
61229
- scopes: array(TokenScopeSchema),
61230
- expiresAt: number().nullish(),
61231
- lastUsedAt: number().nullish(),
61232
- createdAt: number()
61233
- });
61234
- var CreateScopedTokenInputSchema = object({
61235
- userId: string(),
61236
- name: string(),
61237
- scopes: array(TokenScopeSchema),
61238
- expiresAt: number().optional()
61239
- });
61240
- var CreateScopedTokenResultSchema = object({
61241
- token: string(),
61242
- record: ScopedTokenSummarySchema
61243
- });
61244
61339
  var OauthSessionSummarySchema = object({
61245
61340
  id: string(),
61246
61341
  userId: string(),
@@ -61262,11 +61357,11 @@ var TotpStatusSchema = object({
61262
61357
  confirmedAt: number().nullable()
61263
61358
  });
61264
61359
  /**
61265
- * user-management — singleton capability for user accounts, API keys,
61266
- * and scoped tokens.
61360
+ * user-management — singleton capability for user accounts and the
61361
+ * legacy API-key rows.
61267
61362
  *
61268
61363
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
61269
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
61364
+ * — the subset check on `setUserScopes` is moot
61270
61365
  * because non-admins never reach these. If/when we open non-admin
61271
61366
  * delegation, structural caller-scope subset check goes inside the
61272
61367
  * provider.
@@ -61323,15 +61418,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
61323
61418
  kind: "mutation",
61324
61419
  auth: "admin",
61325
61420
  access: "delete"
61326
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
61327
- kind: "mutation",
61328
- auth: "admin",
61329
- access: "create"
61330
- }), method(object({ id: string() }), object({ success: literal(true) }), {
61331
- kind: "mutation",
61332
- auth: "admin",
61333
- access: "delete"
61334
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
61421
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
61335
61422
  kind: "mutation",
61336
61423
  auth: "admin",
61337
61424
  access: "create"
@@ -65487,7 +65574,7 @@ Object.freeze({
65487
65574
  capName: "llm",
65488
65575
  capScope: "system",
65489
65576
  addonId: null,
65490
- access: "view"
65577
+ access: "create"
65491
65578
  },
65492
65579
  "llm.listNodeModels": {
65493
65580
  capName: "llm",
@@ -70151,12 +70238,6 @@ Object.freeze({
70151
70238
  addonId: null,
70152
70239
  access: "create"
70153
70240
  },
70154
- "userManagement.createScopedToken": {
70155
- capName: "user-management",
70156
- capScope: "system",
70157
- addonId: null,
70158
- access: "create"
70159
- },
70160
70241
  "userManagement.createUser": {
70161
70242
  capName: "user-management",
70162
70243
  capScope: "system",
@@ -70205,12 +70286,6 @@ Object.freeze({
70205
70286
  addonId: null,
70206
70287
  access: "view"
70207
70288
  },
70208
- "userManagement.listScopedTokens": {
70209
- capName: "user-management",
70210
- capScope: "system",
70211
- addonId: null,
70212
- access: "view"
70213
- },
70214
70289
  "userManagement.listUsers": {
70215
70290
  capName: "user-management",
70216
70291
  capScope: "system",
@@ -70265,12 +70340,6 @@ Object.freeze({
70265
70340
  addonId: null,
70266
70341
  access: "delete"
70267
70342
  },
70268
- "userManagement.revokeScopedToken": {
70269
- capName: "user-management",
70270
- capScope: "system",
70271
- addonId: null,
70272
- access: "delete"
70273
- },
70274
70343
  "userManagement.setupTotp": {
70275
70344
  capName: "user-management",
70276
70345
  capScope: "system",
@@ -70301,12 +70370,6 @@ Object.freeze({
70301
70370
  addonId: null,
70302
70371
  access: "view"
70303
70372
  },
70304
- "userManagement.validateScopedToken": {
70305
- capName: "user-management",
70306
- capScope: "system",
70307
- addonId: null,
70308
- access: "view"
70309
- },
70310
70373
  "userManagement.verifyTotp": {
70311
70374
  capName: "user-management",
70312
70375
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.604",
3
+ "version": "1.2.605",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",