@camstack/addon-provider-ecowitt 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
@@ -5417,7 +5417,7 @@ var ZodIssueCode$1 = {
5417
5417
  var ZodFirstPartyTypeKind$1;
5418
5418
  ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
5419
5419
  //#endregion
5420
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5420
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5421
5421
  /**
5422
5422
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5423
5423
  * window to float samples (D455).
@@ -7800,9 +7800,9 @@ function normalizeAddonInitResult(result) {
7800
7800
  return result;
7801
7801
  }
7802
7802
  /**
7803
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7804
- * and validates them (`share-token.service.ts` builds its enum from this
7805
- * list); a data plane names the kinds it ACCEPTS in `share`.
7803
+ * The share-view scope kinds a share-link token can carry. The hub mints
7804
+ * and validates them (`ShareViewGrantSchema` builds its
7805
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7806
7806
  */
7807
7807
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7808
7808
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12506,7 +12506,7 @@ var ConvertResultSchema = object({
12506
12506
  * `super_admin` — collapsed onto the single boolean because every
12507
12507
  * non-admin caller is governed by the same scope-check rules; the
12508
12508
  * distinction was only ever used to route role-specific procedures
12509
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12509
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12510
12510
  * with `isAdmin: false` + an explicit scope list.
12511
12511
  */
12512
12512
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -12695,10 +12695,12 @@ var AddonRoutesScopeSchema = object({
12695
12695
  type: literal("addon-routes"),
12696
12696
  access: array(MethodAccessSchema).min(1)
12697
12697
  });
12698
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
12698
12699
  var CredentialScopeSchema = union([
12699
12700
  literal("*"),
12700
12701
  ShareViewScopeSchema,
12701
12702
  AddonRoutesScopeSchema,
12703
+ PreferencesSelfScopeSchema,
12702
12704
  TokenScopeSchema
12703
12705
  ]);
12704
12706
  object({
@@ -12707,6 +12709,55 @@ object({
12707
12709
  jti: string().min(16),
12708
12710
  scopes: array(CredentialScopeSchema).min(1)
12709
12711
  });
12712
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
12713
+ /** A namespace's value: a JSON object, opaque to the hub. */
12714
+ var PreferenceValueSchema = record(string(), unknown());
12715
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
12716
+ /** A stored row, as the owner reads it. */
12717
+ var PreferenceRowSchema = object({
12718
+ namespace: PreferenceNamespaceSchema,
12719
+ value: PreferenceValueSchema,
12720
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
12721
+ revision: number().int().positive(),
12722
+ updatedAt: number().int(),
12723
+ /** The client id the last writer sent; `null` when it sent none. */
12724
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
12725
+ });
12726
+ object({
12727
+ /** Absent: every namespace the caller holds. */
12728
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
12729
+ object({ rows: array(PreferenceRowSchema) });
12730
+ object({
12731
+ namespace: PreferenceNamespaceSchema,
12732
+ value: PreferenceValueSchema,
12733
+ /**
12734
+ * The revision the edit was based on. Absent: last write wins. `0`: the
12735
+ * namespace must not exist yet. Any other value that is not the current
12736
+ * revision answers `conflict` and writes nothing.
12737
+ */
12738
+ baseRevision: number().int().nonnegative().optional(),
12739
+ deviceId: PreferenceDeviceIdSchema.optional()
12740
+ });
12741
+ discriminatedUnion("status", [object({
12742
+ status: literal("saved"),
12743
+ row: PreferenceRowSchema
12744
+ }), object({
12745
+ status: literal("conflict"),
12746
+ current: PreferenceRowSchema.nullable()
12747
+ })]);
12748
+ object({ namespace: PreferenceNamespaceSchema });
12749
+ object({
12750
+ /** `false` when the namespace did not exist. */
12751
+ deleted: boolean() });
12752
+ object({
12753
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
12754
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
12755
+ object({
12756
+ /** Every row whose revision differs from the client's, and every row it did not list. */
12757
+ rows: array(PreferenceRowSchema),
12758
+ /** Namespaces the client listed that no longer exist. */
12759
+ deleted: array(PreferenceNamespaceSchema)
12760
+ });
12710
12761
  _enum(["new-session", "step-up"]);
12711
12762
  /** The languages the hub's app landing pages are written in (D858). */
12712
12763
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -39996,38 +40047,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39996
40047
  auth: "admin",
39997
40048
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39998
40049
  });
40050
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40051
+ /** What a model (or, by default, every model of a kind) can do. */
40052
+ var LlmModelFeaturesSchema = object({
40053
+ vision: boolean(),
40054
+ tools: boolean(),
40055
+ streaming: boolean()
40056
+ });
40057
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40058
+ var LlmModelInfoSchema = object({
40059
+ id: string(),
40060
+ label: string().optional(),
40061
+ contextLength: number().int().positive().optional(),
40062
+ features: LlmModelFeaturesSchema.partial().optional()
40063
+ });
39999
40064
  /**
40000
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
40001
- * methods concat-fan across providers; single-row methods route to ONE
40002
- * provider by the `addonId` in the call input (the notification-output
40003
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40004
- * (hub-placed); the cap stays open for future providers.
40005
- *
40006
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40007
- * `apiKey` is a password field — providers REDACT it on read and merge on
40008
- * write; a stored key NEVER round-trips to a client.
40065
+ * The provider-specific part of a profile, validated by the provider that owns
40066
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40067
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40068
+ * keychain, never in the row, and reads back as the redaction marker.
40009
40069
  */
40010
- var LlmProfileKindSchema = _enum([
40011
- "openai-compatible",
40012
- "openai",
40013
- "anthropic",
40014
- "google",
40015
- "managed-local",
40016
- "apple-foundation"
40017
- ]);
40070
+ var LlmProviderConfigSchema = record(string(), unknown());
40018
40071
  var LlmProfileSchema = object({
40019
40072
  id: string(),
40020
40073
  name: string(),
40074
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40021
40075
  kind: LlmProfileKindSchema,
40022
40076
  /** Stamped by the provider — keeps the fanned catalog routable. */
40023
40077
  addonId: string(),
40024
40078
  enabled: boolean(),
40025
40079
  /** Vendor model id, or the managed runtime's loaded model. */
40026
40080
  model: string(),
40027
- /** Required for openai-compatible; override for cloud kinds. */
40028
- baseUrl: string().optional(),
40029
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40030
- apiKey: string().optional(),
40031
40081
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40032
40082
  * degraded to text — that shipped once and produced a confident answer to a
40033
40083
  * question about a picture nobody sent. */
@@ -40035,15 +40085,11 @@ var LlmProfileSchema = object({
40035
40085
  temperature: number().min(0).max(2).optional(),
40036
40086
  /** Nucleus sampling. Every wire we speak has it. */
40037
40087
  topP: number().min(0).max(1).optional(),
40038
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40039
- * wire does, and the client drops it there (measured: the request body gets
40040
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40041
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40088
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40089
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40042
40090
  topK: number().int().positive().optional(),
40043
40091
  maxTokens: number().int().positive().optional(),
40044
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40045
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40046
- * the model with, so it is the one field that changes a PROCESS. */
40092
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40047
40093
  contextLength: number().int().positive().optional(),
40048
40094
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40049
40095
  * two system prompts fighting is worse than either alone). */
@@ -40069,16 +40115,37 @@ var LlmProfileSchema = object({
40069
40115
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40070
40116
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40071
40117
  toolsEnabled: boolean().default(false),
40072
- extraHeaders: record(string(), string()).optional(),
40073
- /** kind === 'managed-local' only (spec §4). */
40074
- runtime: ManagedRuntimeConfigSchema.optional(),
40075
- /**
40076
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40077
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40078
- * `supportsVision` on such a row is stamped by the provider from the node's
40079
- * reported `imageInput`, never taken from the operator (D62).
40080
- */
40081
- appleFoundation: object({ nodeId: string() }).optional()
40118
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40119
+ providerConfig: LlmProviderConfigSchema.default({})
40120
+ });
40121
+ /**
40122
+ * The common profile fields a kind's editor offers. The editor owns how each
40123
+ * one is drawn; the provider says which of them mean something on its wire.
40124
+ */
40125
+ var LlmProfileFieldSchema = _enum([
40126
+ "temperature",
40127
+ "topP",
40128
+ "topK",
40129
+ "maxTokens",
40130
+ "contextLength",
40131
+ "systemPrompt",
40132
+ "timeoutMs",
40133
+ "connectTimeoutMs",
40134
+ "firstTokenTimeoutMs",
40135
+ "idleTimeoutMs",
40136
+ "retry",
40137
+ "toolsEnabled"
40138
+ ]);
40139
+ /**
40140
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40141
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40142
+ * picker: that widget owns the model choice.
40143
+ */
40144
+ var LlmProviderWidgetSchema = object({
40145
+ id: string(),
40146
+ placement: _enum(["connection", "model"]),
40147
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40148
+ requires: array(string()).optional()
40082
40149
  });
40083
40150
  /** ConfigUISchema tree passed through untyped on the wire (the
40084
40151
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40087,11 +40154,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40087
40154
  var LlmProfileKindDescriptorSchema = object({
40088
40155
  kind: LlmProfileKindSchema,
40089
40156
  label: string(),
40157
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40090
40158
  icon: string(),
40091
40159
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40092
40160
  addonId: string(),
40093
- configSchema: ConfigSchemaPassthrough$3
40161
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40162
+ connectionSchema: ConfigSchemaPassthrough$3,
40163
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40164
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40165
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40166
+ features: LlmModelFeaturesSchema,
40167
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40168
+ visionEditable: boolean(),
40169
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40170
+ modelCatalog: _enum([
40171
+ "fetch",
40172
+ "static",
40173
+ "none"
40174
+ ]),
40175
+ staticModels: array(LlmModelInfoSchema).optional(),
40176
+ /** The common fields that mean something on this kind's wire. */
40177
+ profileFields: array(LlmProfileFieldSchema),
40178
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40094
40179
  });
40180
+ /**
40181
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40182
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40183
+ * untouched (absent or the redaction marker) is resolved server-side from the
40184
+ * stored profile — the browser never receives it.
40185
+ */
40186
+ var LlmListModelsInputSchema = object({
40187
+ addonId: string(),
40188
+ kind: LlmProfileKindSchema,
40189
+ profileId: string().optional(),
40190
+ connection: LlmProviderConfigSchema.optional()
40191
+ });
40192
+ var LlmListModelsErrorCodeSchema = _enum([
40193
+ "auth",
40194
+ "network",
40195
+ "unsupported",
40196
+ "invalid"
40197
+ ]);
40198
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40199
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40200
+ ok: literal(true),
40201
+ models: array(LlmModelInfoSchema)
40202
+ }), object({
40203
+ ok: literal(false),
40204
+ code: LlmListModelsErrorCodeSchema,
40205
+ message: string()
40206
+ })]);
40095
40207
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40096
40208
  var LlmDefaultSchema = object({
40097
40209
  selector: LlmDefaultSelectorSchema,
@@ -40191,7 +40303,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40191
40303
  kind: "mutation",
40192
40304
  auth: "admin",
40193
40305
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40194
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40306
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40307
+ kind: "mutation",
40308
+ auth: "admin"
40309
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40195
40310
  selector: LlmDefaultSelectorSchema,
40196
40311
  profileId: string().nullable()
40197
40312
  }), _void(), {
@@ -64079,26 +64194,6 @@ var ApiKeySummarySchema = object({
64079
64194
  createdAt: number(),
64080
64195
  lastUsedAt: number().optional()
64081
64196
  });
64082
- var ScopedTokenSummarySchema = object({
64083
- id: string(),
64084
- userId: string(),
64085
- name: string(),
64086
- tokenPrefix: string(),
64087
- scopes: array(TokenScopeSchema),
64088
- expiresAt: number().nullish(),
64089
- lastUsedAt: number().nullish(),
64090
- createdAt: number()
64091
- });
64092
- var CreateScopedTokenInputSchema = object({
64093
- userId: string(),
64094
- name: string(),
64095
- scopes: array(TokenScopeSchema),
64096
- expiresAt: number().optional()
64097
- });
64098
- var CreateScopedTokenResultSchema = object({
64099
- token: string(),
64100
- record: ScopedTokenSummarySchema
64101
- });
64102
64197
  var OauthSessionSummarySchema = object({
64103
64198
  id: string(),
64104
64199
  userId: string(),
@@ -64120,11 +64215,11 @@ var TotpStatusSchema = object({
64120
64215
  confirmedAt: number().nullable()
64121
64216
  });
64122
64217
  /**
64123
- * user-management — singleton capability for user accounts, API keys,
64124
- * and scoped tokens.
64218
+ * user-management — singleton capability for user accounts and the
64219
+ * legacy API-key rows.
64125
64220
  *
64126
64221
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
64127
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
64222
+ * — the subset check on `setUserScopes` is moot
64128
64223
  * because non-admins never reach these. If/when we open non-admin
64129
64224
  * delegation, structural caller-scope subset check goes inside the
64130
64225
  * provider.
@@ -64181,15 +64276,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64181
64276
  kind: "mutation",
64182
64277
  auth: "admin",
64183
64278
  access: "delete"
64184
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
64185
- kind: "mutation",
64186
- auth: "admin",
64187
- access: "create"
64188
- }), method(object({ id: string() }), object({ success: literal(true) }), {
64189
- kind: "mutation",
64190
- auth: "admin",
64191
- access: "delete"
64192
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
64279
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
64193
64280
  kind: "mutation",
64194
64281
  auth: "admin",
64195
64282
  access: "create"
@@ -70279,7 +70366,7 @@ Object.freeze({
70279
70366
  capName: "llm",
70280
70367
  capScope: "system",
70281
70368
  addonId: null,
70282
- access: "view"
70369
+ access: "create"
70283
70370
  },
70284
70371
  "llm.listNodeModels": {
70285
70372
  capName: "llm",
@@ -74943,12 +75030,6 @@ Object.freeze({
74943
75030
  addonId: null,
74944
75031
  access: "create"
74945
75032
  },
74946
- "userManagement.createScopedToken": {
74947
- capName: "user-management",
74948
- capScope: "system",
74949
- addonId: null,
74950
- access: "create"
74951
- },
74952
75033
  "userManagement.createUser": {
74953
75034
  capName: "user-management",
74954
75035
  capScope: "system",
@@ -74997,12 +75078,6 @@ Object.freeze({
74997
75078
  addonId: null,
74998
75079
  access: "view"
74999
75080
  },
75000
- "userManagement.listScopedTokens": {
75001
- capName: "user-management",
75002
- capScope: "system",
75003
- addonId: null,
75004
- access: "view"
75005
- },
75006
75081
  "userManagement.listUsers": {
75007
75082
  capName: "user-management",
75008
75083
  capScope: "system",
@@ -75057,12 +75132,6 @@ Object.freeze({
75057
75132
  addonId: null,
75058
75133
  access: "delete"
75059
75134
  },
75060
- "userManagement.revokeScopedToken": {
75061
- capName: "user-management",
75062
- capScope: "system",
75063
- addonId: null,
75064
- access: "delete"
75065
- },
75066
75135
  "userManagement.setupTotp": {
75067
75136
  capName: "user-management",
75068
75137
  capScope: "system",
@@ -75093,12 +75162,6 @@ Object.freeze({
75093
75162
  addonId: null,
75094
75163
  access: "view"
75095
75164
  },
75096
- "userManagement.validateScopedToken": {
75097
- capName: "user-management",
75098
- capScope: "system",
75099
- addonId: null,
75100
- access: "view"
75101
- },
75102
75165
  "userManagement.verifyTotp": {
75103
75166
  capName: "user-management",
75104
75167
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -5416,7 +5416,7 @@ var ZodIssueCode$1 = {
5416
5416
  var ZodFirstPartyTypeKind$1;
5417
5417
  ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
5418
5418
  //#endregion
5419
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5419
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5420
5420
  /**
5421
5421
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5422
5422
  * window to float samples (D455).
@@ -7799,9 +7799,9 @@ function normalizeAddonInitResult(result) {
7799
7799
  return result;
7800
7800
  }
7801
7801
  /**
7802
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7803
- * and validates them (`share-token.service.ts` builds its enum from this
7804
- * list); a data plane names the kinds it ACCEPTS in `share`.
7802
+ * The share-view scope kinds a share-link token can carry. The hub mints
7803
+ * and validates them (`ShareViewGrantSchema` builds its
7804
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7805
7805
  */
7806
7806
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7807
7807
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12505,7 +12505,7 @@ var ConvertResultSchema = object({
12505
12505
  * `super_admin` — collapsed onto the single boolean because every
12506
12506
  * non-admin caller is governed by the same scope-check rules; the
12507
12507
  * distinction was only ever used to route role-specific procedures
12508
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12508
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12509
12509
  * with `isAdmin: false` + an explicit scope list.
12510
12510
  */
12511
12511
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -12694,10 +12694,12 @@ var AddonRoutesScopeSchema = object({
12694
12694
  type: literal("addon-routes"),
12695
12695
  access: array(MethodAccessSchema).min(1)
12696
12696
  });
12697
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
12697
12698
  var CredentialScopeSchema = union([
12698
12699
  literal("*"),
12699
12700
  ShareViewScopeSchema,
12700
12701
  AddonRoutesScopeSchema,
12702
+ PreferencesSelfScopeSchema,
12701
12703
  TokenScopeSchema
12702
12704
  ]);
12703
12705
  object({
@@ -12706,6 +12708,55 @@ object({
12706
12708
  jti: string().min(16),
12707
12709
  scopes: array(CredentialScopeSchema).min(1)
12708
12710
  });
12711
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
12712
+ /** A namespace's value: a JSON object, opaque to the hub. */
12713
+ var PreferenceValueSchema = record(string(), unknown());
12714
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
12715
+ /** A stored row, as the owner reads it. */
12716
+ var PreferenceRowSchema = object({
12717
+ namespace: PreferenceNamespaceSchema,
12718
+ value: PreferenceValueSchema,
12719
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
12720
+ revision: number().int().positive(),
12721
+ updatedAt: number().int(),
12722
+ /** The client id the last writer sent; `null` when it sent none. */
12723
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
12724
+ });
12725
+ object({
12726
+ /** Absent: every namespace the caller holds. */
12727
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
12728
+ object({ rows: array(PreferenceRowSchema) });
12729
+ object({
12730
+ namespace: PreferenceNamespaceSchema,
12731
+ value: PreferenceValueSchema,
12732
+ /**
12733
+ * The revision the edit was based on. Absent: last write wins. `0`: the
12734
+ * namespace must not exist yet. Any other value that is not the current
12735
+ * revision answers `conflict` and writes nothing.
12736
+ */
12737
+ baseRevision: number().int().nonnegative().optional(),
12738
+ deviceId: PreferenceDeviceIdSchema.optional()
12739
+ });
12740
+ discriminatedUnion("status", [object({
12741
+ status: literal("saved"),
12742
+ row: PreferenceRowSchema
12743
+ }), object({
12744
+ status: literal("conflict"),
12745
+ current: PreferenceRowSchema.nullable()
12746
+ })]);
12747
+ object({ namespace: PreferenceNamespaceSchema });
12748
+ object({
12749
+ /** `false` when the namespace did not exist. */
12750
+ deleted: boolean() });
12751
+ object({
12752
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
12753
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
12754
+ object({
12755
+ /** Every row whose revision differs from the client's, and every row it did not list. */
12756
+ rows: array(PreferenceRowSchema),
12757
+ /** Namespaces the client listed that no longer exist. */
12758
+ deleted: array(PreferenceNamespaceSchema)
12759
+ });
12709
12760
  _enum(["new-session", "step-up"]);
12710
12761
  /** The languages the hub's app landing pages are written in (D858). */
12711
12762
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -39995,38 +40046,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39995
40046
  auth: "admin",
39996
40047
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39997
40048
  });
40049
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40050
+ /** What a model (or, by default, every model of a kind) can do. */
40051
+ var LlmModelFeaturesSchema = object({
40052
+ vision: boolean(),
40053
+ tools: boolean(),
40054
+ streaming: boolean()
40055
+ });
40056
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40057
+ var LlmModelInfoSchema = object({
40058
+ id: string(),
40059
+ label: string().optional(),
40060
+ contextLength: number().int().positive().optional(),
40061
+ features: LlmModelFeaturesSchema.partial().optional()
40062
+ });
39998
40063
  /**
39999
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
40000
- * methods concat-fan across providers; single-row methods route to ONE
40001
- * provider by the `addonId` in the call input (the notification-output
40002
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40003
- * (hub-placed); the cap stays open for future providers.
40004
- *
40005
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40006
- * `apiKey` is a password field — providers REDACT it on read and merge on
40007
- * write; a stored key NEVER round-trips to a client.
40064
+ * The provider-specific part of a profile, validated by the provider that owns
40065
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40066
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40067
+ * keychain, never in the row, and reads back as the redaction marker.
40008
40068
  */
40009
- var LlmProfileKindSchema = _enum([
40010
- "openai-compatible",
40011
- "openai",
40012
- "anthropic",
40013
- "google",
40014
- "managed-local",
40015
- "apple-foundation"
40016
- ]);
40069
+ var LlmProviderConfigSchema = record(string(), unknown());
40017
40070
  var LlmProfileSchema = object({
40018
40071
  id: string(),
40019
40072
  name: string(),
40073
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40020
40074
  kind: LlmProfileKindSchema,
40021
40075
  /** Stamped by the provider — keeps the fanned catalog routable. */
40022
40076
  addonId: string(),
40023
40077
  enabled: boolean(),
40024
40078
  /** Vendor model id, or the managed runtime's loaded model. */
40025
40079
  model: string(),
40026
- /** Required for openai-compatible; override for cloud kinds. */
40027
- baseUrl: string().optional(),
40028
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40029
- apiKey: string().optional(),
40030
40080
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40031
40081
  * degraded to text — that shipped once and produced a confident answer to a
40032
40082
  * question about a picture nobody sent. */
@@ -40034,15 +40084,11 @@ var LlmProfileSchema = object({
40034
40084
  temperature: number().min(0).max(2).optional(),
40035
40085
  /** Nucleus sampling. Every wire we speak has it. */
40036
40086
  topP: number().min(0).max(1).optional(),
40037
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40038
- * wire does, and the client drops it there (measured: the request body gets
40039
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40040
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40087
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40088
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40041
40089
  topK: number().int().positive().optional(),
40042
40090
  maxTokens: number().int().positive().optional(),
40043
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40044
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40045
- * the model with, so it is the one field that changes a PROCESS. */
40091
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40046
40092
  contextLength: number().int().positive().optional(),
40047
40093
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40048
40094
  * two system prompts fighting is worse than either alone). */
@@ -40068,16 +40114,37 @@ var LlmProfileSchema = object({
40068
40114
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40069
40115
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40070
40116
  toolsEnabled: boolean().default(false),
40071
- extraHeaders: record(string(), string()).optional(),
40072
- /** kind === 'managed-local' only (spec §4). */
40073
- runtime: ManagedRuntimeConfigSchema.optional(),
40074
- /**
40075
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40076
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40077
- * `supportsVision` on such a row is stamped by the provider from the node's
40078
- * reported `imageInput`, never taken from the operator (D62).
40079
- */
40080
- appleFoundation: object({ nodeId: string() }).optional()
40117
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40118
+ providerConfig: LlmProviderConfigSchema.default({})
40119
+ });
40120
+ /**
40121
+ * The common profile fields a kind's editor offers. The editor owns how each
40122
+ * one is drawn; the provider says which of them mean something on its wire.
40123
+ */
40124
+ var LlmProfileFieldSchema = _enum([
40125
+ "temperature",
40126
+ "topP",
40127
+ "topK",
40128
+ "maxTokens",
40129
+ "contextLength",
40130
+ "systemPrompt",
40131
+ "timeoutMs",
40132
+ "connectTimeoutMs",
40133
+ "firstTokenTimeoutMs",
40134
+ "idleTimeoutMs",
40135
+ "retry",
40136
+ "toolsEnabled"
40137
+ ]);
40138
+ /**
40139
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40140
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40141
+ * picker: that widget owns the model choice.
40142
+ */
40143
+ var LlmProviderWidgetSchema = object({
40144
+ id: string(),
40145
+ placement: _enum(["connection", "model"]),
40146
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40147
+ requires: array(string()).optional()
40081
40148
  });
40082
40149
  /** ConfigUISchema tree passed through untyped on the wire (the
40083
40150
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40086,11 +40153,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40086
40153
  var LlmProfileKindDescriptorSchema = object({
40087
40154
  kind: LlmProfileKindSchema,
40088
40155
  label: string(),
40156
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40089
40157
  icon: string(),
40090
40158
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40091
40159
  addonId: string(),
40092
- configSchema: ConfigSchemaPassthrough$3
40160
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40161
+ connectionSchema: ConfigSchemaPassthrough$3,
40162
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40163
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40164
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40165
+ features: LlmModelFeaturesSchema,
40166
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40167
+ visionEditable: boolean(),
40168
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40169
+ modelCatalog: _enum([
40170
+ "fetch",
40171
+ "static",
40172
+ "none"
40173
+ ]),
40174
+ staticModels: array(LlmModelInfoSchema).optional(),
40175
+ /** The common fields that mean something on this kind's wire. */
40176
+ profileFields: array(LlmProfileFieldSchema),
40177
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40093
40178
  });
40179
+ /**
40180
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40181
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40182
+ * untouched (absent or the redaction marker) is resolved server-side from the
40183
+ * stored profile — the browser never receives it.
40184
+ */
40185
+ var LlmListModelsInputSchema = object({
40186
+ addonId: string(),
40187
+ kind: LlmProfileKindSchema,
40188
+ profileId: string().optional(),
40189
+ connection: LlmProviderConfigSchema.optional()
40190
+ });
40191
+ var LlmListModelsErrorCodeSchema = _enum([
40192
+ "auth",
40193
+ "network",
40194
+ "unsupported",
40195
+ "invalid"
40196
+ ]);
40197
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40198
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40199
+ ok: literal(true),
40200
+ models: array(LlmModelInfoSchema)
40201
+ }), object({
40202
+ ok: literal(false),
40203
+ code: LlmListModelsErrorCodeSchema,
40204
+ message: string()
40205
+ })]);
40094
40206
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40095
40207
  var LlmDefaultSchema = object({
40096
40208
  selector: LlmDefaultSelectorSchema,
@@ -40190,7 +40302,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40190
40302
  kind: "mutation",
40191
40303
  auth: "admin",
40192
40304
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40193
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40305
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40306
+ kind: "mutation",
40307
+ auth: "admin"
40308
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40194
40309
  selector: LlmDefaultSelectorSchema,
40195
40310
  profileId: string().nullable()
40196
40311
  }), _void(), {
@@ -64078,26 +64193,6 @@ var ApiKeySummarySchema = object({
64078
64193
  createdAt: number(),
64079
64194
  lastUsedAt: number().optional()
64080
64195
  });
64081
- var ScopedTokenSummarySchema = object({
64082
- id: string(),
64083
- userId: string(),
64084
- name: string(),
64085
- tokenPrefix: string(),
64086
- scopes: array(TokenScopeSchema),
64087
- expiresAt: number().nullish(),
64088
- lastUsedAt: number().nullish(),
64089
- createdAt: number()
64090
- });
64091
- var CreateScopedTokenInputSchema = object({
64092
- userId: string(),
64093
- name: string(),
64094
- scopes: array(TokenScopeSchema),
64095
- expiresAt: number().optional()
64096
- });
64097
- var CreateScopedTokenResultSchema = object({
64098
- token: string(),
64099
- record: ScopedTokenSummarySchema
64100
- });
64101
64196
  var OauthSessionSummarySchema = object({
64102
64197
  id: string(),
64103
64198
  userId: string(),
@@ -64119,11 +64214,11 @@ var TotpStatusSchema = object({
64119
64214
  confirmedAt: number().nullable()
64120
64215
  });
64121
64216
  /**
64122
- * user-management — singleton capability for user accounts, API keys,
64123
- * and scoped tokens.
64217
+ * user-management — singleton capability for user accounts and the
64218
+ * legacy API-key rows.
64124
64219
  *
64125
64220
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
64126
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
64221
+ * — the subset check on `setUserScopes` is moot
64127
64222
  * because non-admins never reach these. If/when we open non-admin
64128
64223
  * delegation, structural caller-scope subset check goes inside the
64129
64224
  * provider.
@@ -64180,15 +64275,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64180
64275
  kind: "mutation",
64181
64276
  auth: "admin",
64182
64277
  access: "delete"
64183
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
64184
- kind: "mutation",
64185
- auth: "admin",
64186
- access: "create"
64187
- }), method(object({ id: string() }), object({ success: literal(true) }), {
64188
- kind: "mutation",
64189
- auth: "admin",
64190
- access: "delete"
64191
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
64278
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
64192
64279
  kind: "mutation",
64193
64280
  auth: "admin",
64194
64281
  access: "create"
@@ -70278,7 +70365,7 @@ Object.freeze({
70278
70365
  capName: "llm",
70279
70366
  capScope: "system",
70280
70367
  addonId: null,
70281
- access: "view"
70368
+ access: "create"
70282
70369
  },
70283
70370
  "llm.listNodeModels": {
70284
70371
  capName: "llm",
@@ -74942,12 +75029,6 @@ Object.freeze({
74942
75029
  addonId: null,
74943
75030
  access: "create"
74944
75031
  },
74945
- "userManagement.createScopedToken": {
74946
- capName: "user-management",
74947
- capScope: "system",
74948
- addonId: null,
74949
- access: "create"
74950
- },
74951
75032
  "userManagement.createUser": {
74952
75033
  capName: "user-management",
74953
75034
  capScope: "system",
@@ -74996,12 +75077,6 @@ Object.freeze({
74996
75077
  addonId: null,
74997
75078
  access: "view"
74998
75079
  },
74999
- "userManagement.listScopedTokens": {
75000
- capName: "user-management",
75001
- capScope: "system",
75002
- addonId: null,
75003
- access: "view"
75004
- },
75005
75080
  "userManagement.listUsers": {
75006
75081
  capName: "user-management",
75007
75082
  capScope: "system",
@@ -75056,12 +75131,6 @@ Object.freeze({
75056
75131
  addonId: null,
75057
75132
  access: "delete"
75058
75133
  },
75059
- "userManagement.revokeScopedToken": {
75060
- capName: "user-management",
75061
- capScope: "system",
75062
- addonId: null,
75063
- access: "delete"
75064
- },
75065
75134
  "userManagement.setupTotp": {
75066
75135
  capName: "user-management",
75067
75136
  capScope: "system",
@@ -75092,12 +75161,6 @@ Object.freeze({
75092
75161
  addonId: null,
75093
75162
  access: "view"
75094
75163
  },
75095
- "userManagement.validateScopedToken": {
75096
- capName: "user-management",
75097
- capScope: "system",
75098
- addonId: null,
75099
- access: "view"
75100
- },
75101
75164
  "userManagement.verifyTotp": {
75102
75165
  capName: "user-management",
75103
75166
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-ecowitt",
3
- "version": "0.2.130",
3
+ "version": "0.2.131",
4
4
  "description": "Ecowitt weather-station device-provider addon for CamStack — wraps the @apocaliss92/nodewitt local-poll / push client",
5
5
  "keywords": [
6
6
  "camstack",