@camstack/addon-provider-unraid 0.2.130 → 0.2.131

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
@@ -5414,7 +5414,7 @@ var ZodIssueCode = {
5414
5414
  var ZodFirstPartyTypeKind;
5415
5415
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5416
5416
  //#endregion
5417
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5417
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5418
5418
  /**
5419
5419
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5420
5420
  * window to float samples (D455).
@@ -7797,9 +7797,9 @@ function normalizeAddonInitResult(result) {
7797
7797
  return result;
7798
7798
  }
7799
7799
  /**
7800
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7801
- * and validates them (`share-token.service.ts` builds its enum from this
7802
- * list); a data plane names the kinds it ACCEPTS in `share`.
7800
+ * The share-view scope kinds a share-link token can carry. The hub mints
7801
+ * and validates them (`ShareViewGrantSchema` builds its
7802
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7803
7803
  */
7804
7804
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7805
7805
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12503,7 +12503,7 @@ var ConvertResultSchema = object({
12503
12503
  * `super_admin` — collapsed onto the single boolean because every
12504
12504
  * non-admin caller is governed by the same scope-check rules; the
12505
12505
  * distinction was only ever used to route role-specific procedures
12506
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12506
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12507
12507
  * with `isAdmin: false` + an explicit scope list.
12508
12508
  */
12509
12509
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -12692,10 +12692,12 @@ var AddonRoutesScopeSchema = object({
12692
12692
  type: literal("addon-routes"),
12693
12693
  access: array(MethodAccessSchema).min(1)
12694
12694
  });
12695
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
12695
12696
  var CredentialScopeSchema = union([
12696
12697
  literal("*"),
12697
12698
  ShareViewScopeSchema,
12698
12699
  AddonRoutesScopeSchema,
12700
+ PreferencesSelfScopeSchema,
12699
12701
  TokenScopeSchema
12700
12702
  ]);
12701
12703
  object({
@@ -12704,6 +12706,55 @@ object({
12704
12706
  jti: string().min(16),
12705
12707
  scopes: array(CredentialScopeSchema).min(1)
12706
12708
  });
12709
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
12710
+ /** A namespace's value: a JSON object, opaque to the hub. */
12711
+ var PreferenceValueSchema = record(string(), unknown());
12712
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
12713
+ /** A stored row, as the owner reads it. */
12714
+ var PreferenceRowSchema = object({
12715
+ namespace: PreferenceNamespaceSchema,
12716
+ value: PreferenceValueSchema,
12717
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
12718
+ revision: number().int().positive(),
12719
+ updatedAt: number().int(),
12720
+ /** The client id the last writer sent; `null` when it sent none. */
12721
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
12722
+ });
12723
+ object({
12724
+ /** Absent: every namespace the caller holds. */
12725
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
12726
+ object({ rows: array(PreferenceRowSchema) });
12727
+ object({
12728
+ namespace: PreferenceNamespaceSchema,
12729
+ value: PreferenceValueSchema,
12730
+ /**
12731
+ * The revision the edit was based on. Absent: last write wins. `0`: the
12732
+ * namespace must not exist yet. Any other value that is not the current
12733
+ * revision answers `conflict` and writes nothing.
12734
+ */
12735
+ baseRevision: number().int().nonnegative().optional(),
12736
+ deviceId: PreferenceDeviceIdSchema.optional()
12737
+ });
12738
+ discriminatedUnion("status", [object({
12739
+ status: literal("saved"),
12740
+ row: PreferenceRowSchema
12741
+ }), object({
12742
+ status: literal("conflict"),
12743
+ current: PreferenceRowSchema.nullable()
12744
+ })]);
12745
+ object({ namespace: PreferenceNamespaceSchema });
12746
+ object({
12747
+ /** `false` when the namespace did not exist. */
12748
+ deleted: boolean() });
12749
+ object({
12750
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
12751
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
12752
+ object({
12753
+ /** Every row whose revision differs from the client's, and every row it did not list. */
12754
+ rows: array(PreferenceRowSchema),
12755
+ /** Namespaces the client listed that no longer exist. */
12756
+ deleted: array(PreferenceNamespaceSchema)
12757
+ });
12707
12758
  _enum(["new-session", "step-up"]);
12708
12759
  /** The languages the hub's app landing pages are written in (D858). */
12709
12760
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -39993,38 +40044,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39993
40044
  auth: "admin",
39994
40045
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39995
40046
  });
40047
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40048
+ /** What a model (or, by default, every model of a kind) can do. */
40049
+ var LlmModelFeaturesSchema = object({
40050
+ vision: boolean(),
40051
+ tools: boolean(),
40052
+ streaming: boolean()
40053
+ });
40054
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40055
+ var LlmModelInfoSchema = object({
40056
+ id: string(),
40057
+ label: string().optional(),
40058
+ contextLength: number().int().positive().optional(),
40059
+ features: LlmModelFeaturesSchema.partial().optional()
40060
+ });
39996
40061
  /**
39997
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
39998
- * methods concat-fan across providers; single-row methods route to ONE
39999
- * provider by the `addonId` in the call input (the notification-output
40000
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40001
- * (hub-placed); the cap stays open for future providers.
40002
- *
40003
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40004
- * `apiKey` is a password field — providers REDACT it on read and merge on
40005
- * write; a stored key NEVER round-trips to a client.
40062
+ * The provider-specific part of a profile, validated by the provider that owns
40063
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40064
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40065
+ * keychain, never in the row, and reads back as the redaction marker.
40006
40066
  */
40007
- var LlmProfileKindSchema = _enum([
40008
- "openai-compatible",
40009
- "openai",
40010
- "anthropic",
40011
- "google",
40012
- "managed-local",
40013
- "apple-foundation"
40014
- ]);
40067
+ var LlmProviderConfigSchema = record(string(), unknown());
40015
40068
  var LlmProfileSchema = object({
40016
40069
  id: string(),
40017
40070
  name: string(),
40071
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40018
40072
  kind: LlmProfileKindSchema,
40019
40073
  /** Stamped by the provider — keeps the fanned catalog routable. */
40020
40074
  addonId: string(),
40021
40075
  enabled: boolean(),
40022
40076
  /** Vendor model id, or the managed runtime's loaded model. */
40023
40077
  model: string(),
40024
- /** Required for openai-compatible; override for cloud kinds. */
40025
- baseUrl: string().optional(),
40026
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40027
- apiKey: string().optional(),
40028
40078
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40029
40079
  * degraded to text — that shipped once and produced a confident answer to a
40030
40080
  * question about a picture nobody sent. */
@@ -40032,15 +40082,11 @@ var LlmProfileSchema = object({
40032
40082
  temperature: number().min(0).max(2).optional(),
40033
40083
  /** Nucleus sampling. Every wire we speak has it. */
40034
40084
  topP: number().min(0).max(1).optional(),
40035
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40036
- * wire does, and the client drops it there (measured: the request body gets
40037
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40038
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40085
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40086
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40039
40087
  topK: number().int().positive().optional(),
40040
40088
  maxTokens: number().int().positive().optional(),
40041
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40042
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40043
- * the model with, so it is the one field that changes a PROCESS. */
40089
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40044
40090
  contextLength: number().int().positive().optional(),
40045
40091
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40046
40092
  * two system prompts fighting is worse than either alone). */
@@ -40066,16 +40112,37 @@ var LlmProfileSchema = object({
40066
40112
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40067
40113
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40068
40114
  toolsEnabled: boolean().default(false),
40069
- extraHeaders: record(string(), string()).optional(),
40070
- /** kind === 'managed-local' only (spec §4). */
40071
- runtime: ManagedRuntimeConfigSchema.optional(),
40072
- /**
40073
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40074
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40075
- * `supportsVision` on such a row is stamped by the provider from the node's
40076
- * reported `imageInput`, never taken from the operator (D62).
40077
- */
40078
- appleFoundation: object({ nodeId: string() }).optional()
40115
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40116
+ providerConfig: LlmProviderConfigSchema.default({})
40117
+ });
40118
+ /**
40119
+ * The common profile fields a kind's editor offers. The editor owns how each
40120
+ * one is drawn; the provider says which of them mean something on its wire.
40121
+ */
40122
+ var LlmProfileFieldSchema = _enum([
40123
+ "temperature",
40124
+ "topP",
40125
+ "topK",
40126
+ "maxTokens",
40127
+ "contextLength",
40128
+ "systemPrompt",
40129
+ "timeoutMs",
40130
+ "connectTimeoutMs",
40131
+ "firstTokenTimeoutMs",
40132
+ "idleTimeoutMs",
40133
+ "retry",
40134
+ "toolsEnabled"
40135
+ ]);
40136
+ /**
40137
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40138
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40139
+ * picker: that widget owns the model choice.
40140
+ */
40141
+ var LlmProviderWidgetSchema = object({
40142
+ id: string(),
40143
+ placement: _enum(["connection", "model"]),
40144
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40145
+ requires: array(string()).optional()
40079
40146
  });
40080
40147
  /** ConfigUISchema tree passed through untyped on the wire (the
40081
40148
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40084,11 +40151,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40084
40151
  var LlmProfileKindDescriptorSchema = object({
40085
40152
  kind: LlmProfileKindSchema,
40086
40153
  label: string(),
40154
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40087
40155
  icon: string(),
40088
40156
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40089
40157
  addonId: string(),
40090
- configSchema: ConfigSchemaPassthrough$3
40158
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40159
+ connectionSchema: ConfigSchemaPassthrough$3,
40160
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40161
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40162
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40163
+ features: LlmModelFeaturesSchema,
40164
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40165
+ visionEditable: boolean(),
40166
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40167
+ modelCatalog: _enum([
40168
+ "fetch",
40169
+ "static",
40170
+ "none"
40171
+ ]),
40172
+ staticModels: array(LlmModelInfoSchema).optional(),
40173
+ /** The common fields that mean something on this kind's wire. */
40174
+ profileFields: array(LlmProfileFieldSchema),
40175
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40176
+ });
40177
+ /**
40178
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40179
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40180
+ * untouched (absent or the redaction marker) is resolved server-side from the
40181
+ * stored profile — the browser never receives it.
40182
+ */
40183
+ var LlmListModelsInputSchema = object({
40184
+ addonId: string(),
40185
+ kind: LlmProfileKindSchema,
40186
+ profileId: string().optional(),
40187
+ connection: LlmProviderConfigSchema.optional()
40091
40188
  });
40189
+ var LlmListModelsErrorCodeSchema = _enum([
40190
+ "auth",
40191
+ "network",
40192
+ "unsupported",
40193
+ "invalid"
40194
+ ]);
40195
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40196
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40197
+ ok: literal(true),
40198
+ models: array(LlmModelInfoSchema)
40199
+ }), object({
40200
+ ok: literal(false),
40201
+ code: LlmListModelsErrorCodeSchema,
40202
+ message: string()
40203
+ })]);
40092
40204
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40093
40205
  var LlmDefaultSchema = object({
40094
40206
  selector: LlmDefaultSelectorSchema,
@@ -40188,7 +40300,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40188
40300
  kind: "mutation",
40189
40301
  auth: "admin",
40190
40302
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40191
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40303
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40304
+ kind: "mutation",
40305
+ auth: "admin"
40306
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40192
40307
  selector: LlmDefaultSelectorSchema,
40193
40308
  profileId: string().nullable()
40194
40309
  }), _void(), {
@@ -64093,26 +64208,6 @@ var ApiKeySummarySchema = object({
64093
64208
  createdAt: number(),
64094
64209
  lastUsedAt: number().optional()
64095
64210
  });
64096
- var ScopedTokenSummarySchema = object({
64097
- id: string(),
64098
- userId: string(),
64099
- name: string(),
64100
- tokenPrefix: string(),
64101
- scopes: array(TokenScopeSchema),
64102
- expiresAt: number().nullish(),
64103
- lastUsedAt: number().nullish(),
64104
- createdAt: number()
64105
- });
64106
- var CreateScopedTokenInputSchema = object({
64107
- userId: string(),
64108
- name: string(),
64109
- scopes: array(TokenScopeSchema),
64110
- expiresAt: number().optional()
64111
- });
64112
- var CreateScopedTokenResultSchema = object({
64113
- token: string(),
64114
- record: ScopedTokenSummarySchema
64115
- });
64116
64211
  var OauthSessionSummarySchema = object({
64117
64212
  id: string(),
64118
64213
  userId: string(),
@@ -64134,11 +64229,11 @@ var TotpStatusSchema = object({
64134
64229
  confirmedAt: number().nullable()
64135
64230
  });
64136
64231
  /**
64137
- * user-management — singleton capability for user accounts, API keys,
64138
- * and scoped tokens.
64232
+ * user-management — singleton capability for user accounts and the
64233
+ * legacy API-key rows.
64139
64234
  *
64140
64235
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
64141
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
64236
+ * — the subset check on `setUserScopes` is moot
64142
64237
  * because non-admins never reach these. If/when we open non-admin
64143
64238
  * delegation, structural caller-scope subset check goes inside the
64144
64239
  * provider.
@@ -64195,15 +64290,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64195
64290
  kind: "mutation",
64196
64291
  auth: "admin",
64197
64292
  access: "delete"
64198
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
64199
- kind: "mutation",
64200
- auth: "admin",
64201
- access: "create"
64202
- }), method(object({ id: string() }), object({ success: literal(true) }), {
64203
- kind: "mutation",
64204
- auth: "admin",
64205
- access: "delete"
64206
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
64293
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
64207
64294
  kind: "mutation",
64208
64295
  auth: "admin",
64209
64296
  access: "create"
@@ -70293,7 +70380,7 @@ Object.freeze({
70293
70380
  capName: "llm",
70294
70381
  capScope: "system",
70295
70382
  addonId: null,
70296
- access: "view"
70383
+ access: "create"
70297
70384
  },
70298
70385
  "llm.listNodeModels": {
70299
70386
  capName: "llm",
@@ -74957,12 +75044,6 @@ Object.freeze({
74957
75044
  addonId: null,
74958
75045
  access: "create"
74959
75046
  },
74960
- "userManagement.createScopedToken": {
74961
- capName: "user-management",
74962
- capScope: "system",
74963
- addonId: null,
74964
- access: "create"
74965
- },
74966
75047
  "userManagement.createUser": {
74967
75048
  capName: "user-management",
74968
75049
  capScope: "system",
@@ -75011,12 +75092,6 @@ Object.freeze({
75011
75092
  addonId: null,
75012
75093
  access: "view"
75013
75094
  },
75014
- "userManagement.listScopedTokens": {
75015
- capName: "user-management",
75016
- capScope: "system",
75017
- addonId: null,
75018
- access: "view"
75019
- },
75020
75095
  "userManagement.listUsers": {
75021
75096
  capName: "user-management",
75022
75097
  capScope: "system",
@@ -75071,12 +75146,6 @@ Object.freeze({
75071
75146
  addonId: null,
75072
75147
  access: "delete"
75073
75148
  },
75074
- "userManagement.revokeScopedToken": {
75075
- capName: "user-management",
75076
- capScope: "system",
75077
- addonId: null,
75078
- access: "delete"
75079
- },
75080
75149
  "userManagement.setupTotp": {
75081
75150
  capName: "user-management",
75082
75151
  capScope: "system",
@@ -75107,12 +75176,6 @@ Object.freeze({
75107
75176
  addonId: null,
75108
75177
  access: "view"
75109
75178
  },
75110
- "userManagement.validateScopedToken": {
75111
- capName: "user-management",
75112
- capScope: "system",
75113
- addonId: null,
75114
- access: "view"
75115
- },
75116
75179
  "userManagement.verifyTotp": {
75117
75180
  capName: "user-management",
75118
75181
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -5413,7 +5413,7 @@ var ZodIssueCode = {
5413
5413
  var ZodFirstPartyTypeKind;
5414
5414
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5415
5415
  //#endregion
5416
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5416
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5417
5417
  /**
5418
5418
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5419
5419
  * window to float samples (D455).
@@ -7796,9 +7796,9 @@ function normalizeAddonInitResult(result) {
7796
7796
  return result;
7797
7797
  }
7798
7798
  /**
7799
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7800
- * and validates them (`share-token.service.ts` builds its enum from this
7801
- * list); a data plane names the kinds it ACCEPTS in `share`.
7799
+ * The share-view scope kinds a share-link token can carry. The hub mints
7800
+ * and validates them (`ShareViewGrantSchema` builds its
7801
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7802
7802
  */
7803
7803
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7804
7804
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12502,7 +12502,7 @@ var ConvertResultSchema = object({
12502
12502
  * `super_admin` — collapsed onto the single boolean because every
12503
12503
  * non-admin caller is governed by the same scope-check rules; the
12504
12504
  * distinction was only ever used to route role-specific procedures
12505
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12505
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12506
12506
  * with `isAdmin: false` + an explicit scope list.
12507
12507
  */
12508
12508
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -12691,10 +12691,12 @@ var AddonRoutesScopeSchema = object({
12691
12691
  type: literal("addon-routes"),
12692
12692
  access: array(MethodAccessSchema).min(1)
12693
12693
  });
12694
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
12694
12695
  var CredentialScopeSchema = union([
12695
12696
  literal("*"),
12696
12697
  ShareViewScopeSchema,
12697
12698
  AddonRoutesScopeSchema,
12699
+ PreferencesSelfScopeSchema,
12698
12700
  TokenScopeSchema
12699
12701
  ]);
12700
12702
  object({
@@ -12703,6 +12705,55 @@ object({
12703
12705
  jti: string().min(16),
12704
12706
  scopes: array(CredentialScopeSchema).min(1)
12705
12707
  });
12708
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
12709
+ /** A namespace's value: a JSON object, opaque to the hub. */
12710
+ var PreferenceValueSchema = record(string(), unknown());
12711
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
12712
+ /** A stored row, as the owner reads it. */
12713
+ var PreferenceRowSchema = object({
12714
+ namespace: PreferenceNamespaceSchema,
12715
+ value: PreferenceValueSchema,
12716
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
12717
+ revision: number().int().positive(),
12718
+ updatedAt: number().int(),
12719
+ /** The client id the last writer sent; `null` when it sent none. */
12720
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
12721
+ });
12722
+ object({
12723
+ /** Absent: every namespace the caller holds. */
12724
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
12725
+ object({ rows: array(PreferenceRowSchema) });
12726
+ object({
12727
+ namespace: PreferenceNamespaceSchema,
12728
+ value: PreferenceValueSchema,
12729
+ /**
12730
+ * The revision the edit was based on. Absent: last write wins. `0`: the
12731
+ * namespace must not exist yet. Any other value that is not the current
12732
+ * revision answers `conflict` and writes nothing.
12733
+ */
12734
+ baseRevision: number().int().nonnegative().optional(),
12735
+ deviceId: PreferenceDeviceIdSchema.optional()
12736
+ });
12737
+ discriminatedUnion("status", [object({
12738
+ status: literal("saved"),
12739
+ row: PreferenceRowSchema
12740
+ }), object({
12741
+ status: literal("conflict"),
12742
+ current: PreferenceRowSchema.nullable()
12743
+ })]);
12744
+ object({ namespace: PreferenceNamespaceSchema });
12745
+ object({
12746
+ /** `false` when the namespace did not exist. */
12747
+ deleted: boolean() });
12748
+ object({
12749
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
12750
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
12751
+ object({
12752
+ /** Every row whose revision differs from the client's, and every row it did not list. */
12753
+ rows: array(PreferenceRowSchema),
12754
+ /** Namespaces the client listed that no longer exist. */
12755
+ deleted: array(PreferenceNamespaceSchema)
12756
+ });
12706
12757
  _enum(["new-session", "step-up"]);
12707
12758
  /** The languages the hub's app landing pages are written in (D858). */
12708
12759
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -39992,38 +40043,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39992
40043
  auth: "admin",
39993
40044
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39994
40045
  });
40046
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40047
+ /** What a model (or, by default, every model of a kind) can do. */
40048
+ var LlmModelFeaturesSchema = object({
40049
+ vision: boolean(),
40050
+ tools: boolean(),
40051
+ streaming: boolean()
40052
+ });
40053
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40054
+ var LlmModelInfoSchema = object({
40055
+ id: string(),
40056
+ label: string().optional(),
40057
+ contextLength: number().int().positive().optional(),
40058
+ features: LlmModelFeaturesSchema.partial().optional()
40059
+ });
39995
40060
  /**
39996
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
39997
- * methods concat-fan across providers; single-row methods route to ONE
39998
- * provider by the `addonId` in the call input (the notification-output
39999
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40000
- * (hub-placed); the cap stays open for future providers.
40001
- *
40002
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40003
- * `apiKey` is a password field — providers REDACT it on read and merge on
40004
- * write; a stored key NEVER round-trips to a client.
40061
+ * The provider-specific part of a profile, validated by the provider that owns
40062
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40063
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40064
+ * keychain, never in the row, and reads back as the redaction marker.
40005
40065
  */
40006
- var LlmProfileKindSchema = _enum([
40007
- "openai-compatible",
40008
- "openai",
40009
- "anthropic",
40010
- "google",
40011
- "managed-local",
40012
- "apple-foundation"
40013
- ]);
40066
+ var LlmProviderConfigSchema = record(string(), unknown());
40014
40067
  var LlmProfileSchema = object({
40015
40068
  id: string(),
40016
40069
  name: string(),
40070
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40017
40071
  kind: LlmProfileKindSchema,
40018
40072
  /** Stamped by the provider — keeps the fanned catalog routable. */
40019
40073
  addonId: string(),
40020
40074
  enabled: boolean(),
40021
40075
  /** Vendor model id, or the managed runtime's loaded model. */
40022
40076
  model: string(),
40023
- /** Required for openai-compatible; override for cloud kinds. */
40024
- baseUrl: string().optional(),
40025
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40026
- apiKey: string().optional(),
40027
40077
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40028
40078
  * degraded to text — that shipped once and produced a confident answer to a
40029
40079
  * question about a picture nobody sent. */
@@ -40031,15 +40081,11 @@ var LlmProfileSchema = object({
40031
40081
  temperature: number().min(0).max(2).optional(),
40032
40082
  /** Nucleus sampling. Every wire we speak has it. */
40033
40083
  topP: number().min(0).max(1).optional(),
40034
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40035
- * wire does, and the client drops it there (measured: the request body gets
40036
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40037
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40084
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40085
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40038
40086
  topK: number().int().positive().optional(),
40039
40087
  maxTokens: number().int().positive().optional(),
40040
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40041
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40042
- * the model with, so it is the one field that changes a PROCESS. */
40088
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40043
40089
  contextLength: number().int().positive().optional(),
40044
40090
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40045
40091
  * two system prompts fighting is worse than either alone). */
@@ -40065,16 +40111,37 @@ var LlmProfileSchema = object({
40065
40111
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40066
40112
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40067
40113
  toolsEnabled: boolean().default(false),
40068
- extraHeaders: record(string(), string()).optional(),
40069
- /** kind === 'managed-local' only (spec §4). */
40070
- runtime: ManagedRuntimeConfigSchema.optional(),
40071
- /**
40072
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40073
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40074
- * `supportsVision` on such a row is stamped by the provider from the node's
40075
- * reported `imageInput`, never taken from the operator (D62).
40076
- */
40077
- appleFoundation: object({ nodeId: string() }).optional()
40114
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40115
+ providerConfig: LlmProviderConfigSchema.default({})
40116
+ });
40117
+ /**
40118
+ * The common profile fields a kind's editor offers. The editor owns how each
40119
+ * one is drawn; the provider says which of them mean something on its wire.
40120
+ */
40121
+ var LlmProfileFieldSchema = _enum([
40122
+ "temperature",
40123
+ "topP",
40124
+ "topK",
40125
+ "maxTokens",
40126
+ "contextLength",
40127
+ "systemPrompt",
40128
+ "timeoutMs",
40129
+ "connectTimeoutMs",
40130
+ "firstTokenTimeoutMs",
40131
+ "idleTimeoutMs",
40132
+ "retry",
40133
+ "toolsEnabled"
40134
+ ]);
40135
+ /**
40136
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40137
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40138
+ * picker: that widget owns the model choice.
40139
+ */
40140
+ var LlmProviderWidgetSchema = object({
40141
+ id: string(),
40142
+ placement: _enum(["connection", "model"]),
40143
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40144
+ requires: array(string()).optional()
40078
40145
  });
40079
40146
  /** ConfigUISchema tree passed through untyped on the wire (the
40080
40147
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40083,11 +40150,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40083
40150
  var LlmProfileKindDescriptorSchema = object({
40084
40151
  kind: LlmProfileKindSchema,
40085
40152
  label: string(),
40153
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40086
40154
  icon: string(),
40087
40155
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40088
40156
  addonId: string(),
40089
- configSchema: ConfigSchemaPassthrough$3
40157
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40158
+ connectionSchema: ConfigSchemaPassthrough$3,
40159
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40160
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40161
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40162
+ features: LlmModelFeaturesSchema,
40163
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40164
+ visionEditable: boolean(),
40165
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40166
+ modelCatalog: _enum([
40167
+ "fetch",
40168
+ "static",
40169
+ "none"
40170
+ ]),
40171
+ staticModels: array(LlmModelInfoSchema).optional(),
40172
+ /** The common fields that mean something on this kind's wire. */
40173
+ profileFields: array(LlmProfileFieldSchema),
40174
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40175
+ });
40176
+ /**
40177
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40178
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40179
+ * untouched (absent or the redaction marker) is resolved server-side from the
40180
+ * stored profile — the browser never receives it.
40181
+ */
40182
+ var LlmListModelsInputSchema = object({
40183
+ addonId: string(),
40184
+ kind: LlmProfileKindSchema,
40185
+ profileId: string().optional(),
40186
+ connection: LlmProviderConfigSchema.optional()
40090
40187
  });
40188
+ var LlmListModelsErrorCodeSchema = _enum([
40189
+ "auth",
40190
+ "network",
40191
+ "unsupported",
40192
+ "invalid"
40193
+ ]);
40194
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40195
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40196
+ ok: literal(true),
40197
+ models: array(LlmModelInfoSchema)
40198
+ }), object({
40199
+ ok: literal(false),
40200
+ code: LlmListModelsErrorCodeSchema,
40201
+ message: string()
40202
+ })]);
40091
40203
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40092
40204
  var LlmDefaultSchema = object({
40093
40205
  selector: LlmDefaultSelectorSchema,
@@ -40187,7 +40299,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40187
40299
  kind: "mutation",
40188
40300
  auth: "admin",
40189
40301
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40190
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40302
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40303
+ kind: "mutation",
40304
+ auth: "admin"
40305
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40191
40306
  selector: LlmDefaultSelectorSchema,
40192
40307
  profileId: string().nullable()
40193
40308
  }), _void(), {
@@ -64092,26 +64207,6 @@ var ApiKeySummarySchema = object({
64092
64207
  createdAt: number(),
64093
64208
  lastUsedAt: number().optional()
64094
64209
  });
64095
- var ScopedTokenSummarySchema = object({
64096
- id: string(),
64097
- userId: string(),
64098
- name: string(),
64099
- tokenPrefix: string(),
64100
- scopes: array(TokenScopeSchema),
64101
- expiresAt: number().nullish(),
64102
- lastUsedAt: number().nullish(),
64103
- createdAt: number()
64104
- });
64105
- var CreateScopedTokenInputSchema = object({
64106
- userId: string(),
64107
- name: string(),
64108
- scopes: array(TokenScopeSchema),
64109
- expiresAt: number().optional()
64110
- });
64111
- var CreateScopedTokenResultSchema = object({
64112
- token: string(),
64113
- record: ScopedTokenSummarySchema
64114
- });
64115
64210
  var OauthSessionSummarySchema = object({
64116
64211
  id: string(),
64117
64212
  userId: string(),
@@ -64133,11 +64228,11 @@ var TotpStatusSchema = object({
64133
64228
  confirmedAt: number().nullable()
64134
64229
  });
64135
64230
  /**
64136
- * user-management — singleton capability for user accounts, API keys,
64137
- * and scoped tokens.
64231
+ * user-management — singleton capability for user accounts and the
64232
+ * legacy API-key rows.
64138
64233
  *
64139
64234
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
64140
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
64235
+ * — the subset check on `setUserScopes` is moot
64141
64236
  * because non-admins never reach these. If/when we open non-admin
64142
64237
  * delegation, structural caller-scope subset check goes inside the
64143
64238
  * provider.
@@ -64194,15 +64289,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64194
64289
  kind: "mutation",
64195
64290
  auth: "admin",
64196
64291
  access: "delete"
64197
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
64198
- kind: "mutation",
64199
- auth: "admin",
64200
- access: "create"
64201
- }), method(object({ id: string() }), object({ success: literal(true) }), {
64202
- kind: "mutation",
64203
- auth: "admin",
64204
- access: "delete"
64205
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
64292
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
64206
64293
  kind: "mutation",
64207
64294
  auth: "admin",
64208
64295
  access: "create"
@@ -70292,7 +70379,7 @@ Object.freeze({
70292
70379
  capName: "llm",
70293
70380
  capScope: "system",
70294
70381
  addonId: null,
70295
- access: "view"
70382
+ access: "create"
70296
70383
  },
70297
70384
  "llm.listNodeModels": {
70298
70385
  capName: "llm",
@@ -74956,12 +75043,6 @@ Object.freeze({
74956
75043
  addonId: null,
74957
75044
  access: "create"
74958
75045
  },
74959
- "userManagement.createScopedToken": {
74960
- capName: "user-management",
74961
- capScope: "system",
74962
- addonId: null,
74963
- access: "create"
74964
- },
74965
75046
  "userManagement.createUser": {
74966
75047
  capName: "user-management",
74967
75048
  capScope: "system",
@@ -75010,12 +75091,6 @@ Object.freeze({
75010
75091
  addonId: null,
75011
75092
  access: "view"
75012
75093
  },
75013
- "userManagement.listScopedTokens": {
75014
- capName: "user-management",
75015
- capScope: "system",
75016
- addonId: null,
75017
- access: "view"
75018
- },
75019
75094
  "userManagement.listUsers": {
75020
75095
  capName: "user-management",
75021
75096
  capScope: "system",
@@ -75070,12 +75145,6 @@ Object.freeze({
75070
75145
  addonId: null,
75071
75146
  access: "delete"
75072
75147
  },
75073
- "userManagement.revokeScopedToken": {
75074
- capName: "user-management",
75075
- capScope: "system",
75076
- addonId: null,
75077
- access: "delete"
75078
- },
75079
75148
  "userManagement.setupTotp": {
75080
75149
  capName: "user-management",
75081
75150
  capScope: "system",
@@ -75106,12 +75175,6 @@ Object.freeze({
75106
75175
  addonId: null,
75107
75176
  access: "view"
75108
75177
  },
75109
- "userManagement.validateScopedToken": {
75110
- capName: "user-management",
75111
- capScope: "system",
75112
- addonId: null,
75113
- access: "view"
75114
- },
75115
75178
  "userManagement.verifyTotp": {
75116
75179
  capName: "user-management",
75117
75180
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-unraid",
3
- "version": "0.2.130",
3
+ "version": "0.2.131",
4
4
  "description": "Unraid device-provider addon for CamStack — one Container per Unraid instance fanning out array, disk, docker and notification entities",
5
5
  "keywords": [
6
6
  "camstack",