@camstack/addon-provider-homematic 1.2.132 → 1.2.133

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 +246 -131
  2. package/dist/addon.mjs +246 -131
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -5386,7 +5386,7 @@ var ZodIssueCode = {
5386
5386
  var ZodFirstPartyTypeKind;
5387
5387
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5388
5388
  //#endregion
5389
- //#region ../types/dist/sleep-r3RWkGVx.mjs
5389
+ //#region ../types/dist/sleep-CI0n5D44.mjs
5390
5390
  /**
5391
5391
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5392
5392
  * window to float samples (D455).
@@ -9392,6 +9392,16 @@ var CompositionSchema = object({
9392
9392
  seen.add(feature.cap);
9393
9393
  });
9394
9394
  });
9395
+ var NodeColorIdSchema = _enum([
9396
+ "node-a",
9397
+ "node-b",
9398
+ "node-c",
9399
+ "node-d",
9400
+ "node-e",
9401
+ "node-f",
9402
+ "node-g",
9403
+ "node-h"
9404
+ ]);
9395
9405
  new Set([
9396
9406
  "track",
9397
9407
  "face",
@@ -24458,24 +24468,69 @@ var RetrainFrameListSchema = object({
24458
24468
  /** What the page pre-selects — the native key frame when one survives. */
24459
24469
  autoPickMediaId: number().int().optional()
24460
24470
  });
24471
+ /** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
24472
+ var RetrainFrameWorkStateSchema = _enum([
24473
+ "unannotated",
24474
+ "annotated",
24475
+ "complete"
24476
+ ]);
24477
+ /**
24478
+ * Filters for paginated corpus list, KPI, and matching export (design §4.4).
24479
+ * Every narrowing field is ANDed; omitted fields impose no constraint.
24480
+ */
24481
+ var RetrainCorpusFilterSchema = object({
24482
+ workState: RetrainFrameWorkStateSchema.optional(),
24483
+ deviceIds: array(number()).max(500).optional(),
24484
+ /** When set, only frames in this named collection. */
24485
+ collectionId: string().optional(),
24486
+ /** Frames that carry at least one saved annotation in one of these classes. */
24487
+ classes: array(RetrainMacroClassSchema).optional(),
24488
+ page: number().int().positive().default(1),
24489
+ pageSize: number().int().positive().max(100).default(50)
24490
+ });
24491
+ var RetrainCorpusPageSchema = object({
24492
+ frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
24493
+ total: number().int().nonnegative(),
24494
+ page: number().int().positive(),
24495
+ pageSize: number().int().positive()
24496
+ });
24497
+ var RetrainCorpusKpiCameraRowSchema = object({
24498
+ deviceId: number(),
24499
+ unannotated: number().int().nonnegative(),
24500
+ annotated: number().int().nonnegative(),
24501
+ complete: number().int().nonnegative(),
24502
+ /** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
24503
+ * `null` when the corpus is empty (no ratio). */
24504
+ pctOfCorpus: number().min(0).max(1).nullable()
24505
+ });
24506
+ var RetrainCorpusKpiSchema = object({
24507
+ total: number().int().nonnegative(),
24508
+ unannotated: number().int().nonnegative(),
24509
+ annotated: number().int().nonnegative(),
24510
+ complete: number().int().nonnegative(),
24511
+ cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
24512
+ });
24461
24513
  /**
24462
24514
  * Which frames an annotated export carries. Every field narrows; an empty
24463
- * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
24464
- * list owned by whoever trains (the training orchestrator), so `frameIds` is
24465
- * the primitive a version export uses; `batchId` re-selects what an earlier
24466
- * export carried (`exportedInBatch`).
24515
+ * filter is every annotated copy. `frameIds` is the primitive a job or
24516
+ * download uses; `batchId` re-selects what an earlier export carried
24517
+ * (`exportedInBatch`). Frozen dataset versions were removed — live selection
24518
+ * resolves to `frameIds` at plan/start.
24467
24519
  */
24468
24520
  var RetrainExportFilterSchema = object({
24469
24521
  deviceIds: array(number()).optional(),
24470
24522
  frameIds: array(string()).max(2e4).optional(),
24471
24523
  /** Only frames in at least one of these named collections. */
24472
24524
  collectionIds: array(string()).max(200).optional(),
24473
- /** Exactly the frames of this dataset version (and its completeOnly). An
24474
- * unknown id selects nothing. */
24475
- datasetVersionId: string().optional(),
24525
+ /** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
24526
+ collectionId: string().optional(),
24476
24527
  batchId: string().optional(),
24477
24528
  /** Only frames the operator marked complete (all subjects boxed). */
24478
- completeOnly: boolean().optional()
24529
+ completeOnly: boolean().optional(),
24530
+ /** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
24531
+ workState: RetrainFrameWorkStateSchema.optional(),
24532
+ /** Frames with at least one saved annotation in one of these classes. */
24533
+ classes: array(RetrainMacroClassSchema).optional()
24479
24534
  });
24480
24535
  /**
24481
24536
  * `frames`: the full frame copies, boxes in `annotations.json`.
@@ -24675,8 +24730,7 @@ var RetrainDatasetStatsSchema = object({
24675
24730
  completeFrames: number().int()
24676
24731
  })).readonly()
24677
24732
  });
24678
- /** An immutable dataset version, without its frame list. */
24679
- var RetrainDatasetVersionSchema = object({
24733
+ object({
24680
24734
  id: string(),
24681
24735
  name: string(),
24682
24736
  createdAt: number(),
@@ -24684,22 +24738,33 @@ var RetrainDatasetVersionSchema = object({
24684
24738
  layout: RetrainExportLayoutSchema,
24685
24739
  completeOnly: boolean(),
24686
24740
  frameCount: number().int(),
24687
- /** sha256 of what the frames taught when the version was frozen. */
24688
24741
  annotationHash: string(),
24689
- /** The export manifest schema the version was cut under. */
24690
24742
  manifestSchema: string(),
24691
24743
  stats: RetrainDatasetStatsSchema
24692
24744
  });
24693
- var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
24694
- kind: literal("created"),
24695
- version: RetrainDatasetVersionSchema
24745
+ /**
24746
+ * Live training corpus criteria — same shape as `TrainingCorpusSelection` on
24747
+ * the training cap. Resolved here so plan/start and the annotated export share
24748
+ * one definition of "the frames" (`buildRetrainExportPlan`).
24749
+ */
24750
+ var RetrainTrainingCorpusSelectionSchema = object({
24751
+ collectionIds: array(string()).min(1),
24752
+ workState: _enum([
24753
+ "complete",
24754
+ "annotated_or_complete",
24755
+ "any_annotated"
24756
+ ]).default("complete")
24757
+ });
24758
+ var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
24759
+ kind: literal("resolved"),
24760
+ frameIds: array(string()).max(2e4).readonly(),
24761
+ stats: RetrainDatasetStatsSchema,
24762
+ annotationHash: string(),
24763
+ layout: RetrainExportLayoutSchema
24696
24764
  }), object({
24697
24765
  kind: literal("refused"),
24698
- reason: _enum([
24699
- "empty-name",
24700
- "duplicate-name",
24701
- "no-frames"
24702
- ])
24766
+ reason: _enum(["unknown-collection", "no-frames"]),
24767
+ detail: string()
24703
24768
  })]);
24704
24769
  /** The outcome of a lifecycle move owned by the retrain page. */
24705
24770
  var RetrainTransitionResultSchema = object({
@@ -25406,6 +25471,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25406
25471
  }), array(RetrainTrackSchema).readonly(), {
25407
25472
  kind: "query",
25408
25473
  auth: "admin"
25474
+ }), method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
25475
+ kind: "query",
25476
+ auth: "admin"
25477
+ }), method(object({}), RetrainCorpusKpiSchema, {
25478
+ kind: "query",
25479
+ auth: "admin"
25409
25480
  }), method(object({ trackId: string() }), RetrainFrameListSchema, {
25410
25481
  kind: "query",
25411
25482
  auth: "admin"
@@ -25501,36 +25572,6 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25501
25572
  kind: "mutation",
25502
25573
  auth: "admin",
25503
25574
  timeoutMs: 12e4
25504
- }), method(object({
25505
- selection: RetrainDatasetSelectionSchema,
25506
- completeOnly: boolean().optional()
25507
- }), RetrainDatasetStatsSchema, {
25508
- kind: "query",
25509
- auth: "admin"
25510
- }), method(object({
25511
- name: string().max(120),
25512
- selection: RetrainDatasetSelectionSchema,
25513
- layout: RetrainExportLayoutSchema,
25514
- completeOnly: boolean()
25515
- }), CreateRetrainDatasetVersionResultSchema, {
25516
- kind: "mutation",
25517
- auth: "admin",
25518
- timeoutMs: 12e4
25519
- }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
25520
- kind: "query",
25521
- auth: "admin"
25522
- }), method(object({ id: string() }), object({ deleted: boolean() }), {
25523
- kind: "mutation",
25524
- auth: "admin"
25525
- }), method(object({ id: string() }), object({
25526
- found: boolean(),
25527
- annotationHash: string(),
25528
- matches: boolean(),
25529
- missingFrames: number().int()
25530
- }), {
25531
- kind: "query",
25532
- auth: "admin",
25533
- timeoutMs: 12e4
25534
25575
  }), method(object({}), array(RetrainAssistProfileSchema).readonly(), {
25535
25576
  kind: "query",
25536
25577
  auth: "admin"
@@ -25557,6 +25598,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25557
25598
  }), method(object({}), array(RetrainCollectionSchema).readonly(), {
25558
25599
  kind: "query",
25559
25600
  auth: "admin"
25601
+ }), method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
25602
+ kind: "query",
25603
+ auth: "admin",
25604
+ timeoutMs: 6e4
25560
25605
  }), method(object({
25561
25606
  id: string(),
25562
25607
  name: string().max(120)
@@ -28110,6 +28155,8 @@ var AgentPipelineSettingsSchema = object({
28110
28155
  * address is wrong (multi-homed host, NAT, custom interface).
28111
28156
  */
28112
28157
  reachableHost: string().optional(),
28158
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
28159
+ color: NodeColorIdSchema.optional(),
28113
28160
  /**
28114
28161
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
28115
28162
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -28659,8 +28706,9 @@ method(object({
28659
28706
  auth: "admin"
28660
28707
  }), method(object({
28661
28708
  agentNodeId: string(),
28662
- reachableHost: string().nullable()
28663
- }), object({ success: literal(true) }), {
28709
+ reachableHost: string().nullable().optional(),
28710
+ color: NodeColorIdSchema.nullable().optional()
28711
+ }).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
28664
28712
  kind: "mutation",
28665
28713
  auth: "admin"
28666
28714
  }), method(object({
@@ -42525,9 +42573,11 @@ var zoneRulesCapability = {
42525
42573
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
42526
42574
  * manifest entry and nothing else.
42527
42575
  *
42528
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
42529
- * `notification-output` posture); `describe` concat-fans across providers.
42530
- * Every method is `admin`: these spend money.
42576
+ * Collection of provider **types** (addons). Each addon owns zero or more
42577
+ * **entries** (credentials + defaults). Concat-fans: `describe`,
42578
+ * `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
42579
+ * `entryId`; callers also pass the owning `addonId` as the collection
42580
+ * selector (broker posture). Every method is `admin`: these spend money.
42531
42581
  *
42532
42582
  * Every cloud object a provider creates is tagged with the orchestrator's
42533
42583
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -42551,8 +42601,8 @@ var TrainingRegionOptionSchema = object({
42551
42601
  priceMultiplier: number().positive()
42552
42602
  });
42553
42603
  /**
42554
- * The provider's per-account settings, as the orchestrator reads them. They
42555
- * live in the PROVIDER addon's settings (operator decision 2026-10-08: they
42604
+ * The provider's per-entry settings, as the orchestrator reads them. They
42605
+ * live on the PROVIDER addon's entry (operator decision 2026-10-08: they
42556
42606
  * depend on the user's account), never hard-coded in the orchestrator.
42557
42607
  */
42558
42608
  var TrainingProviderDefaultsSchema = object({
@@ -42563,9 +42613,32 @@ var TrainingProviderDefaultsSchema = object({
42563
42613
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
42564
42614
  failedDatasetGraceHours: number().nonnegative()
42565
42615
  });
42616
+ /** One creatable provider type, for the Add-entry dialog. */
42617
+ var TrainingProviderTypeSchema = object({
42618
+ typeId: string(),
42619
+ label: string(),
42620
+ /** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
42621
+ iconAsset: string(),
42622
+ /** Owning `training-provider` addon — collection selector for createEntry. */
42623
+ addonId: string()
42624
+ });
42625
+ /** One configured account / workspace under a provider type. */
42626
+ var TrainingProviderEntrySchema = object({
42627
+ entryId: string(),
42628
+ typeId: string(),
42629
+ name: string(),
42630
+ addonId: string(),
42631
+ /** Credentials are present — never the values. */
42632
+ configured: boolean()
42633
+ });
42566
42634
  var TrainingProviderDescriptorSchema = object({
42567
42635
  addonId: string(),
42568
- /** `modal`, `runpod`, `fake`, … */
42636
+ entryId: string(),
42637
+ typeId: string(),
42638
+ /** Operator-chosen entry name. */
42639
+ name: string(),
42640
+ iconAsset: string(),
42641
+ /** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
42569
42642
  kind: string(),
42570
42643
  label: string(),
42571
42644
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -42629,20 +42702,30 @@ var TrainerSourceRefSchema = object({
42629
42702
  /** A commit sha (never a branch) — the job must be reproducible. */
42630
42703
  revision: string().regex(/^[0-9a-f]{7,64}$/)
42631
42704
  });
42705
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
42632
42706
  var JobRef = {
42633
- addonId: string(),
42707
+ entryId: string().min(1),
42634
42708
  jobKey: string().uuid()
42635
42709
  };
42636
42710
  var TrainingLogLineSchema = object({
42637
42711
  ts: number(),
42638
42712
  text: string()
42639
42713
  });
42640
- method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }), method(object({ addonId: string() }), TrainingCredentialCheckSchema, {
42714
+ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }), method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }), method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }), method(object({
42715
+ typeId: string().min(1),
42716
+ name: string().min(1)
42717
+ }), object({ entryId: string() }), {
42718
+ kind: "mutation",
42719
+ auth: "admin"
42720
+ }), method(object({ entryId: string().min(1) }), object({ ok: literal(true) }), {
42721
+ kind: "mutation",
42722
+ auth: "admin"
42723
+ }), method(object({ entryId: string().min(1) }), TrainingCredentialCheckSchema, {
42641
42724
  kind: "mutation",
42642
42725
  auth: "admin",
42643
42726
  timeoutMs: 3e4
42644
42727
  }), method(object({
42645
- addonId: string(),
42728
+ entryId: string().min(1),
42646
42729
  gpuType: string(),
42647
42730
  region: string(),
42648
42731
  datasetBytes: number().int().nonnegative(),
@@ -42708,7 +42791,7 @@ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "
42708
42791
  kind: "mutation",
42709
42792
  auth: "admin",
42710
42793
  timeoutMs: 5 * 6e4
42711
- }), method(object({ addonId: string() }), array(ProviderJobStatusSchema).readonly(), {
42794
+ }), method(object({ entryId: string().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
42712
42795
  auth: "admin",
42713
42796
  timeoutMs: 2 * 6e4
42714
42797
  });
@@ -42718,20 +42801,31 @@ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "
42718
42801
  *
42719
42802
  * It owns what every provider must agree on, written once:
42720
42803
  *
42721
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
42722
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
42723
- * the export plan) and reaches this store through the five row methods
42724
- * below, so the Retrain page and the export did not change.
42725
42804
  * - **Jobs.** A persisted state machine, a reconcile loop against the
42726
42805
  * provider, a cost guard, a daily orphan sweep and the retention rules.
42727
42806
  * - **The return flow.** Verified artefacts → Model Studio
42728
42807
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
42729
42808
  * rollback. Nothing is ever registered automatically.
42730
42809
  *
42810
+ * Plan/start takes a live {@link TrainingCorpusSelection} (collections +
42811
+ * work-state rule); frame ids are resolved via pipeline-analytics at that
42812
+ * moment and snapshotted on the job. No frozen dataset version.
42813
+ *
42731
42814
  * Every method is `admin`.
42732
42815
  */
42733
- /** A version WITH its frame list — what the export and a job read. */
42734
- var TrainingDatasetVersionRowSchema = RetrainDatasetVersionSchema.omit({ frameCount: true }).extend({ frameIds: array(string()).max(2e4).readonly() });
42816
+ /**
42817
+ * Live corpus criteria for plan/start (design §5.2). Default is complete-only.
42818
+ * Frame ids are resolved at plan/start — never a frozen version id.
42819
+ */
42820
+ var TrainingCorpusSelectionSchema = object({
42821
+ collectionIds: array(string()).min(1),
42822
+ /** Default complete-only for v1 */
42823
+ workState: _enum([
42824
+ "complete",
42825
+ "annotated_or_complete",
42826
+ "any_annotated"
42827
+ ]).default("complete")
42828
+ });
42735
42829
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
42736
42830
  var TrainingBaseModelSchema = object({
42737
42831
  modelId: string(),
@@ -42749,9 +42843,13 @@ var TrainingPresetSchema = _enum([
42749
42843
  "thorough"
42750
42844
  ]);
42751
42845
  var TrainingJobRequestSchema = object({
42752
- datasetVersionId: string().min(1),
42753
- /** The `training-provider` addon that runs it. */
42754
- addonId: string().min(1),
42846
+ /** Live collection + work-state criteria; resolved at plan/start. */
42847
+ selection: TrainingCorpusSelectionSchema,
42848
+ /**
42849
+ * The provider **entry** that runs it (credentials + defaults).
42850
+ * Resolve to an owning addon via `training-provider.describe` / `listEntries`.
42851
+ */
42852
+ entryId: string().min(1),
42755
42853
  gpuType: string().min(1),
42756
42854
  region: string(),
42757
42855
  baseModelId: string().min(1),
@@ -42810,6 +42908,7 @@ var TrainingJobPlanSchema = object({
42810
42908
  * result lives after the operator acted on it.
42811
42909
  */
42812
42910
  var TrainingJobStateSchema = _enum([
42911
+ "queued",
42813
42912
  "uploading",
42814
42913
  "submitted",
42815
42914
  "starting",
@@ -42863,6 +42962,11 @@ var TrainingJobSchema = object({
42863
42962
  createdAt: number(),
42864
42963
  updatedAt: number(),
42865
42964
  state: TrainingJobStateSchema,
42965
+ /**
42966
+ * Shared by every job enqueued together via `startJobBatch`.
42967
+ * `null` for a lone `startJob`. The engine advances queued siblings by this id.
42968
+ */
42969
+ batchId: string().nullable().default(null),
42866
42970
  stage: TrainingStageSchema.nullable(),
42867
42971
  failure: object({
42868
42972
  reason: TrainingFailureReasonSchema,
@@ -42874,6 +42978,12 @@ var TrainingJobSchema = object({
42874
42978
  maxRuntimeSec: number().int().positive(),
42875
42979
  trainer: TrainerSourceRefSchema,
42876
42980
  datasetLayout: RetrainExportLayoutSchema,
42981
+ /** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
42982
+ frameCount: number().int().nonnegative(),
42983
+ /** Resolved frame ids at start — the archive ships exactly these. */
42984
+ frameIds: array(string()).max(2e4).readonly(),
42985
+ /** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
42986
+ annotationHash: string(),
42877
42987
  dataset: object({
42878
42988
  bytes: number().int(),
42879
42989
  sha256: string(),
@@ -42915,13 +43025,7 @@ var TrainingJobSchema = object({
42915
43025
  canary: TrainingCanarySchema.nullable()
42916
43026
  });
42917
43027
  var IdInput = object({ id: string().min(1) });
42918
- method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
42919
- kind: "mutation",
42920
- auth: "admin"
42921
- }), method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }), method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }), method(IdInput, object({ removed: boolean() }), {
42922
- kind: "mutation",
42923
- auth: "admin"
42924
- }), method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }), method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
43028
+ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }), method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
42925
43029
  auth: "admin",
42926
43030
  timeoutMs: 6e4
42927
43031
  }), method(TrainingJobRequestSchema.extend({
@@ -42940,6 +43044,24 @@ method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
42940
43044
  kind: "mutation",
42941
43045
  auth: "admin",
42942
43046
  timeoutMs: 12e4
43047
+ }), method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
43048
+ baseModelIds: array(string().min(1)).min(1),
43049
+ name: string().min(1).max(120),
43050
+ maxCostUsd: number().positive(),
43051
+ maxRuntimeSec: number().int().positive(),
43052
+ idempotencyKey: string().min(8).max(80)
43053
+ }), discriminatedUnion("kind", [object({
43054
+ kind: literal("started"),
43055
+ batchId: string(),
43056
+ jobs: array(TrainingJobSchema).min(1).readonly()
43057
+ }), object({
43058
+ kind: literal("refused"),
43059
+ reason: TrainingRefusalReasonSchema,
43060
+ detail: string()
43061
+ })]), {
43062
+ kind: "mutation",
43063
+ auth: "admin",
43064
+ timeoutMs: 12e4
42943
43065
  }), method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }), method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }), method(IdInput, TrainingJobSchema, {
42944
43066
  kind: "mutation",
42945
43067
  auth: "admin",
@@ -48708,12 +48830,6 @@ Object.freeze({
48708
48830
  addonId: null,
48709
48831
  access: "create"
48710
48832
  },
48711
- "pipelineAnalytics.createRetrainDatasetVersion": {
48712
- capName: "pipeline-analytics",
48713
- capScope: "device",
48714
- addonId: null,
48715
- access: "create"
48716
- },
48717
48833
  "pipelineAnalytics.deleteDeviceEvents": {
48718
48834
  capName: "pipeline-analytics",
48719
48835
  capScope: "device",
@@ -48726,12 +48842,6 @@ Object.freeze({
48726
48842
  addonId: null,
48727
48843
  access: "delete"
48728
48844
  },
48729
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
48730
- capName: "pipeline-analytics",
48731
- capScope: "device",
48732
- addonId: null,
48733
- access: "delete"
48734
- },
48735
48845
  "pipelineAnalytics.deleteTracks": {
48736
48846
  capName: "pipeline-analytics",
48737
48847
  capScope: "device",
@@ -48834,6 +48944,12 @@ Object.freeze({
48834
48944
  addonId: null,
48835
48945
  access: "view"
48836
48946
  },
48947
+ "pipelineAnalytics.getRetrainCorpusKpi": {
48948
+ capName: "pipeline-analytics",
48949
+ capScope: "device",
48950
+ addonId: null,
48951
+ access: "view"
48952
+ },
48837
48953
  "pipelineAnalytics.getRetrainExportUrl": {
48838
48954
  capName: "pipeline-analytics",
48839
48955
  capScope: "device",
@@ -48954,7 +49070,7 @@ Object.freeze({
48954
49070
  addonId: null,
48955
49071
  access: "view"
48956
49072
  },
48957
- "pipelineAnalytics.listRetrainDatasetVersions": {
49073
+ "pipelineAnalytics.listRetrainCorpusPage": {
48958
49074
  capName: "pipeline-analytics",
48959
49075
  capScope: "device",
48960
49076
  addonId: null,
@@ -49008,12 +49124,6 @@ Object.freeze({
49008
49124
  addonId: null,
49009
49125
  access: "create"
49010
49126
  },
49011
- "pipelineAnalytics.previewRetrainDataset": {
49012
- capName: "pipeline-analytics",
49013
- capScope: "device",
49014
- addonId: null,
49015
- access: "view"
49016
- },
49017
49127
  "pipelineAnalytics.proposeRetrainAnnotations": {
49018
49128
  capName: "pipeline-analytics",
49019
49129
  capScope: "device",
@@ -49092,6 +49202,12 @@ Object.freeze({
49092
49202
  addonId: null,
49093
49203
  access: "create"
49094
49204
  },
49205
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
49206
+ capName: "pipeline-analytics",
49207
+ capScope: "device",
49208
+ addonId: null,
49209
+ access: "view"
49210
+ },
49095
49211
  "pipelineAnalytics.restageRetrainTrack": {
49096
49212
  capName: "pipeline-analytics",
49097
49213
  capScope: "device",
@@ -49152,12 +49268,6 @@ Object.freeze({
49152
49268
  addonId: null,
49153
49269
  access: "create"
49154
49270
  },
49155
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
49156
- capName: "pipeline-analytics",
49157
- capScope: "device",
49158
- addonId: null,
49159
- access: "view"
49160
- },
49161
49271
  "pipelineAnalytics.wipeAllAnalytics": {
49162
49272
  capName: "pipeline-analytics",
49163
49273
  capScope: "device",
@@ -51552,18 +51662,6 @@ Object.freeze({
51552
51662
  addonId: null,
51553
51663
  access: "create"
51554
51664
  },
51555
- "training.findDatasetVersionIdByName": {
51556
- capName: "training",
51557
- capScope: "system",
51558
- addonId: null,
51559
- access: "view"
51560
- },
51561
- "training.getDatasetVersion": {
51562
- capName: "training",
51563
- capScope: "system",
51564
- addonId: null,
51565
- access: "view"
51566
- },
51567
51665
  "training.getJob": {
51568
51666
  capName: "training",
51569
51667
  capScope: "system",
@@ -51582,12 +51680,6 @@ Object.freeze({
51582
51680
  addonId: null,
51583
51681
  access: "view"
51584
51682
  },
51585
- "training.listDatasetVersions": {
51586
- capName: "training",
51587
- capScope: "system",
51588
- addonId: null,
51589
- access: "view"
51590
- },
51591
51683
  "training.listJobs": {
51592
51684
  capName: "training",
51593
51685
  capScope: "system",
@@ -51600,54 +51692,66 @@ Object.freeze({
51600
51692
  addonId: null,
51601
51693
  access: "view"
51602
51694
  },
51603
- "training.putDatasetVersion": {
51695
+ "training.registerResult": {
51604
51696
  capName: "training",
51605
51697
  capScope: "system",
51606
51698
  addonId: null,
51607
51699
  access: "create"
51608
51700
  },
51609
- "training.registerResult": {
51701
+ "training.rollbackCanary": {
51610
51702
  capName: "training",
51611
51703
  capScope: "system",
51612
51704
  addonId: null,
51613
51705
  access: "create"
51614
51706
  },
51615
- "training.removeDatasetVersion": {
51707
+ "training.startJob": {
51616
51708
  capName: "training",
51617
51709
  capScope: "system",
51618
51710
  addonId: null,
51619
- access: "delete"
51711
+ access: "create"
51620
51712
  },
51621
- "training.rollbackCanary": {
51713
+ "training.startJobBatch": {
51622
51714
  capName: "training",
51623
51715
  capScope: "system",
51624
51716
  addonId: null,
51625
51717
  access: "create"
51626
51718
  },
51627
- "training.startJob": {
51628
- capName: "training",
51719
+ "trainingProvider.cancelJob": {
51720
+ capName: "training-provider",
51629
51721
  capScope: "system",
51630
51722
  addonId: null,
51631
51723
  access: "create"
51632
51724
  },
51633
- "trainingProvider.cancelJob": {
51725
+ "trainingProvider.cleanupJob": {
51634
51726
  capName: "training-provider",
51635
51727
  capScope: "system",
51636
51728
  addonId: null,
51637
51729
  access: "create"
51638
51730
  },
51639
- "trainingProvider.cleanupJob": {
51731
+ "trainingProvider.createEntry": {
51640
51732
  capName: "training-provider",
51641
51733
  capScope: "system",
51642
51734
  addonId: null,
51643
51735
  access: "create"
51644
51736
  },
51737
+ "trainingProvider.deleteEntry": {
51738
+ capName: "training-provider",
51739
+ capScope: "system",
51740
+ addonId: null,
51741
+ access: "delete"
51742
+ },
51645
51743
  "trainingProvider.describe": {
51646
51744
  capName: "training-provider",
51647
51745
  capScope: "system",
51648
51746
  addonId: null,
51649
51747
  access: "view"
51650
51748
  },
51749
+ "trainingProvider.describeTypes": {
51750
+ capName: "training-provider",
51751
+ capScope: "system",
51752
+ addonId: null,
51753
+ access: "view"
51754
+ },
51651
51755
  "trainingProvider.estimateJob": {
51652
51756
  capName: "training-provider",
51653
51757
  capScope: "system",
@@ -51660,6 +51764,12 @@ Object.freeze({
51660
51764
  addonId: null,
51661
51765
  access: "view"
51662
51766
  },
51767
+ "trainingProvider.listEntries": {
51768
+ capName: "training-provider",
51769
+ capScope: "system",
51770
+ addonId: null,
51771
+ access: "view"
51772
+ },
51663
51773
  "trainingProvider.listJobEvents": {
51664
51774
  capName: "training-provider",
51665
51775
  capScope: "system",
@@ -55116,6 +55226,11 @@ Object.freeze({
55116
55226
  form: "array",
55117
55227
  optional: false
55118
55228
  }],
55229
+ "pipelineAnalytics.listRetrainCorpusPage": [{
55230
+ name: "deviceIds",
55231
+ form: "array",
55232
+ optional: true
55233
+ }],
55119
55234
  "pipelineAnalytics.listRetrainStaging": [{
55120
55235
  name: "deviceIds",
55121
55236
  form: "array",
package/dist/addon.mjs CHANGED
@@ -5387,7 +5387,7 @@ var ZodIssueCode = {
5387
5387
  var ZodFirstPartyTypeKind;
5388
5388
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5389
5389
  //#endregion
5390
- //#region ../types/dist/sleep-r3RWkGVx.mjs
5390
+ //#region ../types/dist/sleep-CI0n5D44.mjs
5391
5391
  /**
5392
5392
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5393
5393
  * window to float samples (D455).
@@ -9393,6 +9393,16 @@ var CompositionSchema = object({
9393
9393
  seen.add(feature.cap);
9394
9394
  });
9395
9395
  });
9396
+ var NodeColorIdSchema = _enum([
9397
+ "node-a",
9398
+ "node-b",
9399
+ "node-c",
9400
+ "node-d",
9401
+ "node-e",
9402
+ "node-f",
9403
+ "node-g",
9404
+ "node-h"
9405
+ ]);
9396
9406
  new Set([
9397
9407
  "track",
9398
9408
  "face",
@@ -24459,24 +24469,69 @@ var RetrainFrameListSchema = object({
24459
24469
  /** What the page pre-selects — the native key frame when one survives. */
24460
24470
  autoPickMediaId: number().int().optional()
24461
24471
  });
24472
+ /** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
24473
+ var RetrainFrameWorkStateSchema = _enum([
24474
+ "unannotated",
24475
+ "annotated",
24476
+ "complete"
24477
+ ]);
24478
+ /**
24479
+ * Filters for paginated corpus list, KPI, and matching export (design §4.4).
24480
+ * Every narrowing field is ANDed; omitted fields impose no constraint.
24481
+ */
24482
+ var RetrainCorpusFilterSchema = object({
24483
+ workState: RetrainFrameWorkStateSchema.optional(),
24484
+ deviceIds: array(number()).max(500).optional(),
24485
+ /** When set, only frames in this named collection. */
24486
+ collectionId: string().optional(),
24487
+ /** Frames that carry at least one saved annotation in one of these classes. */
24488
+ classes: array(RetrainMacroClassSchema).optional(),
24489
+ page: number().int().positive().default(1),
24490
+ pageSize: number().int().positive().max(100).default(50)
24491
+ });
24492
+ var RetrainCorpusPageSchema = object({
24493
+ frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
24494
+ total: number().int().nonnegative(),
24495
+ page: number().int().positive(),
24496
+ pageSize: number().int().positive()
24497
+ });
24498
+ var RetrainCorpusKpiCameraRowSchema = object({
24499
+ deviceId: number(),
24500
+ unannotated: number().int().nonnegative(),
24501
+ annotated: number().int().nonnegative(),
24502
+ complete: number().int().nonnegative(),
24503
+ /** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
24504
+ * `null` when the corpus is empty (no ratio). */
24505
+ pctOfCorpus: number().min(0).max(1).nullable()
24506
+ });
24507
+ var RetrainCorpusKpiSchema = object({
24508
+ total: number().int().nonnegative(),
24509
+ unannotated: number().int().nonnegative(),
24510
+ annotated: number().int().nonnegative(),
24511
+ complete: number().int().nonnegative(),
24512
+ cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
24513
+ });
24462
24514
  /**
24463
24515
  * Which frames an annotated export carries. Every field narrows; an empty
24464
- * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
24465
- * list owned by whoever trains (the training orchestrator), so `frameIds` is
24466
- * the primitive a version export uses; `batchId` re-selects what an earlier
24467
- * export carried (`exportedInBatch`).
24516
+ * filter is every annotated copy. `frameIds` is the primitive a job or
24517
+ * download uses; `batchId` re-selects what an earlier export carried
24518
+ * (`exportedInBatch`). Frozen dataset versions were removed — live selection
24519
+ * resolves to `frameIds` at plan/start.
24468
24520
  */
24469
24521
  var RetrainExportFilterSchema = object({
24470
24522
  deviceIds: array(number()).optional(),
24471
24523
  frameIds: array(string()).max(2e4).optional(),
24472
24524
  /** Only frames in at least one of these named collections. */
24473
24525
  collectionIds: array(string()).max(200).optional(),
24474
- /** Exactly the frames of this dataset version (and its completeOnly). An
24475
- * unknown id selects nothing. */
24476
- datasetVersionId: string().optional(),
24526
+ /** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
24527
+ collectionId: string().optional(),
24477
24528
  batchId: string().optional(),
24478
24529
  /** Only frames the operator marked complete (all subjects boxed). */
24479
- completeOnly: boolean().optional()
24530
+ completeOnly: boolean().optional(),
24531
+ /** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
24532
+ workState: RetrainFrameWorkStateSchema.optional(),
24533
+ /** Frames with at least one saved annotation in one of these classes. */
24534
+ classes: array(RetrainMacroClassSchema).optional()
24480
24535
  });
24481
24536
  /**
24482
24537
  * `frames`: the full frame copies, boxes in `annotations.json`.
@@ -24676,8 +24731,7 @@ var RetrainDatasetStatsSchema = object({
24676
24731
  completeFrames: number().int()
24677
24732
  })).readonly()
24678
24733
  });
24679
- /** An immutable dataset version, without its frame list. */
24680
- var RetrainDatasetVersionSchema = object({
24734
+ object({
24681
24735
  id: string(),
24682
24736
  name: string(),
24683
24737
  createdAt: number(),
@@ -24685,22 +24739,33 @@ var RetrainDatasetVersionSchema = object({
24685
24739
  layout: RetrainExportLayoutSchema,
24686
24740
  completeOnly: boolean(),
24687
24741
  frameCount: number().int(),
24688
- /** sha256 of what the frames taught when the version was frozen. */
24689
24742
  annotationHash: string(),
24690
- /** The export manifest schema the version was cut under. */
24691
24743
  manifestSchema: string(),
24692
24744
  stats: RetrainDatasetStatsSchema
24693
24745
  });
24694
- var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
24695
- kind: literal("created"),
24696
- version: RetrainDatasetVersionSchema
24746
+ /**
24747
+ * Live training corpus criteria — same shape as `TrainingCorpusSelection` on
24748
+ * the training cap. Resolved here so plan/start and the annotated export share
24749
+ * one definition of "the frames" (`buildRetrainExportPlan`).
24750
+ */
24751
+ var RetrainTrainingCorpusSelectionSchema = object({
24752
+ collectionIds: array(string()).min(1),
24753
+ workState: _enum([
24754
+ "complete",
24755
+ "annotated_or_complete",
24756
+ "any_annotated"
24757
+ ]).default("complete")
24758
+ });
24759
+ var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
24760
+ kind: literal("resolved"),
24761
+ frameIds: array(string()).max(2e4).readonly(),
24762
+ stats: RetrainDatasetStatsSchema,
24763
+ annotationHash: string(),
24764
+ layout: RetrainExportLayoutSchema
24697
24765
  }), object({
24698
24766
  kind: literal("refused"),
24699
- reason: _enum([
24700
- "empty-name",
24701
- "duplicate-name",
24702
- "no-frames"
24703
- ])
24767
+ reason: _enum(["unknown-collection", "no-frames"]),
24768
+ detail: string()
24704
24769
  })]);
24705
24770
  /** The outcome of a lifecycle move owned by the retrain page. */
24706
24771
  var RetrainTransitionResultSchema = object({
@@ -25407,6 +25472,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25407
25472
  }), array(RetrainTrackSchema).readonly(), {
25408
25473
  kind: "query",
25409
25474
  auth: "admin"
25475
+ }), method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
25476
+ kind: "query",
25477
+ auth: "admin"
25478
+ }), method(object({}), RetrainCorpusKpiSchema, {
25479
+ kind: "query",
25480
+ auth: "admin"
25410
25481
  }), method(object({ trackId: string() }), RetrainFrameListSchema, {
25411
25482
  kind: "query",
25412
25483
  auth: "admin"
@@ -25502,36 +25573,6 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25502
25573
  kind: "mutation",
25503
25574
  auth: "admin",
25504
25575
  timeoutMs: 12e4
25505
- }), method(object({
25506
- selection: RetrainDatasetSelectionSchema,
25507
- completeOnly: boolean().optional()
25508
- }), RetrainDatasetStatsSchema, {
25509
- kind: "query",
25510
- auth: "admin"
25511
- }), method(object({
25512
- name: string().max(120),
25513
- selection: RetrainDatasetSelectionSchema,
25514
- layout: RetrainExportLayoutSchema,
25515
- completeOnly: boolean()
25516
- }), CreateRetrainDatasetVersionResultSchema, {
25517
- kind: "mutation",
25518
- auth: "admin",
25519
- timeoutMs: 12e4
25520
- }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
25521
- kind: "query",
25522
- auth: "admin"
25523
- }), method(object({ id: string() }), object({ deleted: boolean() }), {
25524
- kind: "mutation",
25525
- auth: "admin"
25526
- }), method(object({ id: string() }), object({
25527
- found: boolean(),
25528
- annotationHash: string(),
25529
- matches: boolean(),
25530
- missingFrames: number().int()
25531
- }), {
25532
- kind: "query",
25533
- auth: "admin",
25534
- timeoutMs: 12e4
25535
25576
  }), method(object({}), array(RetrainAssistProfileSchema).readonly(), {
25536
25577
  kind: "query",
25537
25578
  auth: "admin"
@@ -25558,6 +25599,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25558
25599
  }), method(object({}), array(RetrainCollectionSchema).readonly(), {
25559
25600
  kind: "query",
25560
25601
  auth: "admin"
25602
+ }), method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
25603
+ kind: "query",
25604
+ auth: "admin",
25605
+ timeoutMs: 6e4
25561
25606
  }), method(object({
25562
25607
  id: string(),
25563
25608
  name: string().max(120)
@@ -28111,6 +28156,8 @@ var AgentPipelineSettingsSchema = object({
28111
28156
  * address is wrong (multi-homed host, NAT, custom interface).
28112
28157
  */
28113
28158
  reachableHost: string().optional(),
28159
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
28160
+ color: NodeColorIdSchema.optional(),
28114
28161
  /**
28115
28162
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
28116
28163
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -28660,8 +28707,9 @@ method(object({
28660
28707
  auth: "admin"
28661
28708
  }), method(object({
28662
28709
  agentNodeId: string(),
28663
- reachableHost: string().nullable()
28664
- }), object({ success: literal(true) }), {
28710
+ reachableHost: string().nullable().optional(),
28711
+ color: NodeColorIdSchema.nullable().optional()
28712
+ }).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
28665
28713
  kind: "mutation",
28666
28714
  auth: "admin"
28667
28715
  }), method(object({
@@ -42526,9 +42574,11 @@ var zoneRulesCapability = {
42526
42574
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
42527
42575
  * manifest entry and nothing else.
42528
42576
  *
42529
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
42530
- * `notification-output` posture); `describe` concat-fans across providers.
42531
- * Every method is `admin`: these spend money.
42577
+ * Collection of provider **types** (addons). Each addon owns zero or more
42578
+ * **entries** (credentials + defaults). Concat-fans: `describe`,
42579
+ * `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
42580
+ * `entryId`; callers also pass the owning `addonId` as the collection
42581
+ * selector (broker posture). Every method is `admin`: these spend money.
42532
42582
  *
42533
42583
  * Every cloud object a provider creates is tagged with the orchestrator's
42534
42584
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -42552,8 +42602,8 @@ var TrainingRegionOptionSchema = object({
42552
42602
  priceMultiplier: number().positive()
42553
42603
  });
42554
42604
  /**
42555
- * The provider's per-account settings, as the orchestrator reads them. They
42556
- * live in the PROVIDER addon's settings (operator decision 2026-10-08: they
42605
+ * The provider's per-entry settings, as the orchestrator reads them. They
42606
+ * live on the PROVIDER addon's entry (operator decision 2026-10-08: they
42557
42607
  * depend on the user's account), never hard-coded in the orchestrator.
42558
42608
  */
42559
42609
  var TrainingProviderDefaultsSchema = object({
@@ -42564,9 +42614,32 @@ var TrainingProviderDefaultsSchema = object({
42564
42614
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
42565
42615
  failedDatasetGraceHours: number().nonnegative()
42566
42616
  });
42617
+ /** One creatable provider type, for the Add-entry dialog. */
42618
+ var TrainingProviderTypeSchema = object({
42619
+ typeId: string(),
42620
+ label: string(),
42621
+ /** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
42622
+ iconAsset: string(),
42623
+ /** Owning `training-provider` addon — collection selector for createEntry. */
42624
+ addonId: string()
42625
+ });
42626
+ /** One configured account / workspace under a provider type. */
42627
+ var TrainingProviderEntrySchema = object({
42628
+ entryId: string(),
42629
+ typeId: string(),
42630
+ name: string(),
42631
+ addonId: string(),
42632
+ /** Credentials are present — never the values. */
42633
+ configured: boolean()
42634
+ });
42567
42635
  var TrainingProviderDescriptorSchema = object({
42568
42636
  addonId: string(),
42569
- /** `modal`, `runpod`, `fake`, … */
42637
+ entryId: string(),
42638
+ typeId: string(),
42639
+ /** Operator-chosen entry name. */
42640
+ name: string(),
42641
+ iconAsset: string(),
42642
+ /** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
42570
42643
  kind: string(),
42571
42644
  label: string(),
42572
42645
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -42630,20 +42703,30 @@ var TrainerSourceRefSchema = object({
42630
42703
  /** A commit sha (never a branch) — the job must be reproducible. */
42631
42704
  revision: string().regex(/^[0-9a-f]{7,64}$/)
42632
42705
  });
42706
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
42633
42707
  var JobRef = {
42634
- addonId: string(),
42708
+ entryId: string().min(1),
42635
42709
  jobKey: string().uuid()
42636
42710
  };
42637
42711
  var TrainingLogLineSchema = object({
42638
42712
  ts: number(),
42639
42713
  text: string()
42640
42714
  });
42641
- method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }), method(object({ addonId: string() }), TrainingCredentialCheckSchema, {
42715
+ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }), method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }), method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }), method(object({
42716
+ typeId: string().min(1),
42717
+ name: string().min(1)
42718
+ }), object({ entryId: string() }), {
42719
+ kind: "mutation",
42720
+ auth: "admin"
42721
+ }), method(object({ entryId: string().min(1) }), object({ ok: literal(true) }), {
42722
+ kind: "mutation",
42723
+ auth: "admin"
42724
+ }), method(object({ entryId: string().min(1) }), TrainingCredentialCheckSchema, {
42642
42725
  kind: "mutation",
42643
42726
  auth: "admin",
42644
42727
  timeoutMs: 3e4
42645
42728
  }), method(object({
42646
- addonId: string(),
42729
+ entryId: string().min(1),
42647
42730
  gpuType: string(),
42648
42731
  region: string(),
42649
42732
  datasetBytes: number().int().nonnegative(),
@@ -42709,7 +42792,7 @@ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "
42709
42792
  kind: "mutation",
42710
42793
  auth: "admin",
42711
42794
  timeoutMs: 5 * 6e4
42712
- }), method(object({ addonId: string() }), array(ProviderJobStatusSchema).readonly(), {
42795
+ }), method(object({ entryId: string().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
42713
42796
  auth: "admin",
42714
42797
  timeoutMs: 2 * 6e4
42715
42798
  });
@@ -42719,20 +42802,31 @@ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "
42719
42802
  *
42720
42803
  * It owns what every provider must agree on, written once:
42721
42804
  *
42722
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
42723
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
42724
- * the export plan) and reaches this store through the five row methods
42725
- * below, so the Retrain page and the export did not change.
42726
42805
  * - **Jobs.** A persisted state machine, a reconcile loop against the
42727
42806
  * provider, a cost guard, a daily orphan sweep and the retention rules.
42728
42807
  * - **The return flow.** Verified artefacts → Model Studio
42729
42808
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
42730
42809
  * rollback. Nothing is ever registered automatically.
42731
42810
  *
42811
+ * Plan/start takes a live {@link TrainingCorpusSelection} (collections +
42812
+ * work-state rule); frame ids are resolved via pipeline-analytics at that
42813
+ * moment and snapshotted on the job. No frozen dataset version.
42814
+ *
42732
42815
  * Every method is `admin`.
42733
42816
  */
42734
- /** A version WITH its frame list — what the export and a job read. */
42735
- var TrainingDatasetVersionRowSchema = RetrainDatasetVersionSchema.omit({ frameCount: true }).extend({ frameIds: array(string()).max(2e4).readonly() });
42817
+ /**
42818
+ * Live corpus criteria for plan/start (design §5.2). Default is complete-only.
42819
+ * Frame ids are resolved at plan/start — never a frozen version id.
42820
+ */
42821
+ var TrainingCorpusSelectionSchema = object({
42822
+ collectionIds: array(string()).min(1),
42823
+ /** Default complete-only for v1 */
42824
+ workState: _enum([
42825
+ "complete",
42826
+ "annotated_or_complete",
42827
+ "any_annotated"
42828
+ ]).default("complete")
42829
+ });
42736
42830
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
42737
42831
  var TrainingBaseModelSchema = object({
42738
42832
  modelId: string(),
@@ -42750,9 +42844,13 @@ var TrainingPresetSchema = _enum([
42750
42844
  "thorough"
42751
42845
  ]);
42752
42846
  var TrainingJobRequestSchema = object({
42753
- datasetVersionId: string().min(1),
42754
- /** The `training-provider` addon that runs it. */
42755
- addonId: string().min(1),
42847
+ /** Live collection + work-state criteria; resolved at plan/start. */
42848
+ selection: TrainingCorpusSelectionSchema,
42849
+ /**
42850
+ * The provider **entry** that runs it (credentials + defaults).
42851
+ * Resolve to an owning addon via `training-provider.describe` / `listEntries`.
42852
+ */
42853
+ entryId: string().min(1),
42756
42854
  gpuType: string().min(1),
42757
42855
  region: string(),
42758
42856
  baseModelId: string().min(1),
@@ -42811,6 +42909,7 @@ var TrainingJobPlanSchema = object({
42811
42909
  * result lives after the operator acted on it.
42812
42910
  */
42813
42911
  var TrainingJobStateSchema = _enum([
42912
+ "queued",
42814
42913
  "uploading",
42815
42914
  "submitted",
42816
42915
  "starting",
@@ -42864,6 +42963,11 @@ var TrainingJobSchema = object({
42864
42963
  createdAt: number(),
42865
42964
  updatedAt: number(),
42866
42965
  state: TrainingJobStateSchema,
42966
+ /**
42967
+ * Shared by every job enqueued together via `startJobBatch`.
42968
+ * `null` for a lone `startJob`. The engine advances queued siblings by this id.
42969
+ */
42970
+ batchId: string().nullable().default(null),
42867
42971
  stage: TrainingStageSchema.nullable(),
42868
42972
  failure: object({
42869
42973
  reason: TrainingFailureReasonSchema,
@@ -42875,6 +42979,12 @@ var TrainingJobSchema = object({
42875
42979
  maxRuntimeSec: number().int().positive(),
42876
42980
  trainer: TrainerSourceRefSchema,
42877
42981
  datasetLayout: RetrainExportLayoutSchema,
42982
+ /** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
42983
+ frameCount: number().int().nonnegative(),
42984
+ /** Resolved frame ids at start — the archive ships exactly these. */
42985
+ frameIds: array(string()).max(2e4).readonly(),
42986
+ /** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
42987
+ annotationHash: string(),
42878
42988
  dataset: object({
42879
42989
  bytes: number().int(),
42880
42990
  sha256: string(),
@@ -42916,13 +43026,7 @@ var TrainingJobSchema = object({
42916
43026
  canary: TrainingCanarySchema.nullable()
42917
43027
  });
42918
43028
  var IdInput = object({ id: string().min(1) });
42919
- method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
42920
- kind: "mutation",
42921
- auth: "admin"
42922
- }), method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }), method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }), method(IdInput, object({ removed: boolean() }), {
42923
- kind: "mutation",
42924
- auth: "admin"
42925
- }), method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }), method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
43029
+ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }), method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
42926
43030
  auth: "admin",
42927
43031
  timeoutMs: 6e4
42928
43032
  }), method(TrainingJobRequestSchema.extend({
@@ -42941,6 +43045,24 @@ method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
42941
43045
  kind: "mutation",
42942
43046
  auth: "admin",
42943
43047
  timeoutMs: 12e4
43048
+ }), method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
43049
+ baseModelIds: array(string().min(1)).min(1),
43050
+ name: string().min(1).max(120),
43051
+ maxCostUsd: number().positive(),
43052
+ maxRuntimeSec: number().int().positive(),
43053
+ idempotencyKey: string().min(8).max(80)
43054
+ }), discriminatedUnion("kind", [object({
43055
+ kind: literal("started"),
43056
+ batchId: string(),
43057
+ jobs: array(TrainingJobSchema).min(1).readonly()
43058
+ }), object({
43059
+ kind: literal("refused"),
43060
+ reason: TrainingRefusalReasonSchema,
43061
+ detail: string()
43062
+ })]), {
43063
+ kind: "mutation",
43064
+ auth: "admin",
43065
+ timeoutMs: 12e4
42944
43066
  }), method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }), method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }), method(IdInput, TrainingJobSchema, {
42945
43067
  kind: "mutation",
42946
43068
  auth: "admin",
@@ -48709,12 +48831,6 @@ Object.freeze({
48709
48831
  addonId: null,
48710
48832
  access: "create"
48711
48833
  },
48712
- "pipelineAnalytics.createRetrainDatasetVersion": {
48713
- capName: "pipeline-analytics",
48714
- capScope: "device",
48715
- addonId: null,
48716
- access: "create"
48717
- },
48718
48834
  "pipelineAnalytics.deleteDeviceEvents": {
48719
48835
  capName: "pipeline-analytics",
48720
48836
  capScope: "device",
@@ -48727,12 +48843,6 @@ Object.freeze({
48727
48843
  addonId: null,
48728
48844
  access: "delete"
48729
48845
  },
48730
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
48731
- capName: "pipeline-analytics",
48732
- capScope: "device",
48733
- addonId: null,
48734
- access: "delete"
48735
- },
48736
48846
  "pipelineAnalytics.deleteTracks": {
48737
48847
  capName: "pipeline-analytics",
48738
48848
  capScope: "device",
@@ -48835,6 +48945,12 @@ Object.freeze({
48835
48945
  addonId: null,
48836
48946
  access: "view"
48837
48947
  },
48948
+ "pipelineAnalytics.getRetrainCorpusKpi": {
48949
+ capName: "pipeline-analytics",
48950
+ capScope: "device",
48951
+ addonId: null,
48952
+ access: "view"
48953
+ },
48838
48954
  "pipelineAnalytics.getRetrainExportUrl": {
48839
48955
  capName: "pipeline-analytics",
48840
48956
  capScope: "device",
@@ -48955,7 +49071,7 @@ Object.freeze({
48955
49071
  addonId: null,
48956
49072
  access: "view"
48957
49073
  },
48958
- "pipelineAnalytics.listRetrainDatasetVersions": {
49074
+ "pipelineAnalytics.listRetrainCorpusPage": {
48959
49075
  capName: "pipeline-analytics",
48960
49076
  capScope: "device",
48961
49077
  addonId: null,
@@ -49009,12 +49125,6 @@ Object.freeze({
49009
49125
  addonId: null,
49010
49126
  access: "create"
49011
49127
  },
49012
- "pipelineAnalytics.previewRetrainDataset": {
49013
- capName: "pipeline-analytics",
49014
- capScope: "device",
49015
- addonId: null,
49016
- access: "view"
49017
- },
49018
49128
  "pipelineAnalytics.proposeRetrainAnnotations": {
49019
49129
  capName: "pipeline-analytics",
49020
49130
  capScope: "device",
@@ -49093,6 +49203,12 @@ Object.freeze({
49093
49203
  addonId: null,
49094
49204
  access: "create"
49095
49205
  },
49206
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
49207
+ capName: "pipeline-analytics",
49208
+ capScope: "device",
49209
+ addonId: null,
49210
+ access: "view"
49211
+ },
49096
49212
  "pipelineAnalytics.restageRetrainTrack": {
49097
49213
  capName: "pipeline-analytics",
49098
49214
  capScope: "device",
@@ -49153,12 +49269,6 @@ Object.freeze({
49153
49269
  addonId: null,
49154
49270
  access: "create"
49155
49271
  },
49156
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
49157
- capName: "pipeline-analytics",
49158
- capScope: "device",
49159
- addonId: null,
49160
- access: "view"
49161
- },
49162
49272
  "pipelineAnalytics.wipeAllAnalytics": {
49163
49273
  capName: "pipeline-analytics",
49164
49274
  capScope: "device",
@@ -51553,18 +51663,6 @@ Object.freeze({
51553
51663
  addonId: null,
51554
51664
  access: "create"
51555
51665
  },
51556
- "training.findDatasetVersionIdByName": {
51557
- capName: "training",
51558
- capScope: "system",
51559
- addonId: null,
51560
- access: "view"
51561
- },
51562
- "training.getDatasetVersion": {
51563
- capName: "training",
51564
- capScope: "system",
51565
- addonId: null,
51566
- access: "view"
51567
- },
51568
51666
  "training.getJob": {
51569
51667
  capName: "training",
51570
51668
  capScope: "system",
@@ -51583,12 +51681,6 @@ Object.freeze({
51583
51681
  addonId: null,
51584
51682
  access: "view"
51585
51683
  },
51586
- "training.listDatasetVersions": {
51587
- capName: "training",
51588
- capScope: "system",
51589
- addonId: null,
51590
- access: "view"
51591
- },
51592
51684
  "training.listJobs": {
51593
51685
  capName: "training",
51594
51686
  capScope: "system",
@@ -51601,54 +51693,66 @@ Object.freeze({
51601
51693
  addonId: null,
51602
51694
  access: "view"
51603
51695
  },
51604
- "training.putDatasetVersion": {
51696
+ "training.registerResult": {
51605
51697
  capName: "training",
51606
51698
  capScope: "system",
51607
51699
  addonId: null,
51608
51700
  access: "create"
51609
51701
  },
51610
- "training.registerResult": {
51702
+ "training.rollbackCanary": {
51611
51703
  capName: "training",
51612
51704
  capScope: "system",
51613
51705
  addonId: null,
51614
51706
  access: "create"
51615
51707
  },
51616
- "training.removeDatasetVersion": {
51708
+ "training.startJob": {
51617
51709
  capName: "training",
51618
51710
  capScope: "system",
51619
51711
  addonId: null,
51620
- access: "delete"
51712
+ access: "create"
51621
51713
  },
51622
- "training.rollbackCanary": {
51714
+ "training.startJobBatch": {
51623
51715
  capName: "training",
51624
51716
  capScope: "system",
51625
51717
  addonId: null,
51626
51718
  access: "create"
51627
51719
  },
51628
- "training.startJob": {
51629
- capName: "training",
51720
+ "trainingProvider.cancelJob": {
51721
+ capName: "training-provider",
51630
51722
  capScope: "system",
51631
51723
  addonId: null,
51632
51724
  access: "create"
51633
51725
  },
51634
- "trainingProvider.cancelJob": {
51726
+ "trainingProvider.cleanupJob": {
51635
51727
  capName: "training-provider",
51636
51728
  capScope: "system",
51637
51729
  addonId: null,
51638
51730
  access: "create"
51639
51731
  },
51640
- "trainingProvider.cleanupJob": {
51732
+ "trainingProvider.createEntry": {
51641
51733
  capName: "training-provider",
51642
51734
  capScope: "system",
51643
51735
  addonId: null,
51644
51736
  access: "create"
51645
51737
  },
51738
+ "trainingProvider.deleteEntry": {
51739
+ capName: "training-provider",
51740
+ capScope: "system",
51741
+ addonId: null,
51742
+ access: "delete"
51743
+ },
51646
51744
  "trainingProvider.describe": {
51647
51745
  capName: "training-provider",
51648
51746
  capScope: "system",
51649
51747
  addonId: null,
51650
51748
  access: "view"
51651
51749
  },
51750
+ "trainingProvider.describeTypes": {
51751
+ capName: "training-provider",
51752
+ capScope: "system",
51753
+ addonId: null,
51754
+ access: "view"
51755
+ },
51652
51756
  "trainingProvider.estimateJob": {
51653
51757
  capName: "training-provider",
51654
51758
  capScope: "system",
@@ -51661,6 +51765,12 @@ Object.freeze({
51661
51765
  addonId: null,
51662
51766
  access: "view"
51663
51767
  },
51768
+ "trainingProvider.listEntries": {
51769
+ capName: "training-provider",
51770
+ capScope: "system",
51771
+ addonId: null,
51772
+ access: "view"
51773
+ },
51664
51774
  "trainingProvider.listJobEvents": {
51665
51775
  capName: "training-provider",
51666
51776
  capScope: "system",
@@ -55117,6 +55227,11 @@ Object.freeze({
55117
55227
  form: "array",
55118
55228
  optional: false
55119
55229
  }],
55230
+ "pipelineAnalytics.listRetrainCorpusPage": [{
55231
+ name: "deviceIds",
55232
+ form: "array",
55233
+ optional: true
55234
+ }],
55120
55235
  "pipelineAnalytics.listRetrainStaging": [{
55121
55236
  name: "deviceIds",
55122
55237
  form: "array",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.132",
3
+ "version": "1.2.133",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",