@camstack/addon-osd-manager 0.1.198 → 0.1.200

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 (20) hide show
  1. package/dist/MotionZonesSettings-DAz0zsa2.mjs +310 -0
  2. package/dist/{PrivacyMaskSettings-xC6YrNM-.mjs → PrivacyMaskSettings-DBRcmqYu.mjs} +25 -25
  3. package/dist/{SceneMonitorEditor-DKN2cL7k.mjs → SceneMonitorEditor-p1bF1btk.mjs} +299 -299
  4. package/dist/_stub.js +3872 -3832
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-BPCqUX6E.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-Dgy-eWCs.mjs} +3 -3
  6. package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DVaKG6N9.mjs +26 -0
  7. package/dist/addon-osd-manager.css +1 -1
  8. package/dist/{hostInit-DGG5vSkv.mjs → hostInit-Pkln2STJ.mjs} +2 -2
  9. package/dist/index.js +302 -158
  10. package/dist/index.mjs +302 -158
  11. package/dist/{player-overlays-TxRsHixk.mjs → player-overlays-2hRBqn9k.mjs} +5 -5
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-t3UayeQT.mjs → responsive-BCF-RTGy.mjs} +3 -3
  14. package/dist/{scene-monitor-copy-gMmaT-FC.mjs → scene-monitor-copy-M5yqaBpP.mjs} +1 -1
  15. package/dist/{square-B_CvlH_T.mjs → square-CLL05HzW.mjs} +1 -1
  16. package/dist/{trash-2-BfeGf6tH.mjs → trash-2-BECtJsvm.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BXV7lhl_.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BFUWkh_2.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/dist/MotionZonesSettings-DUltQQw1.mjs +0 -310
  20. package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CGoq0DWk.mjs +0 -26
package/dist/index.mjs CHANGED
@@ -5376,7 +5376,7 @@ var ZodIssueCode = {
5376
5376
  var ZodFirstPartyTypeKind;
5377
5377
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5378
5378
  //#endregion
5379
- //#region ../types/dist/sleep-r3RWkGVx.mjs
5379
+ //#region ../types/dist/sleep-CI0n5D44.mjs
5380
5380
  /**
5381
5381
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5382
5382
  * window to float samples (D455).
@@ -9417,6 +9417,16 @@ var CompositionSchema = object({
9417
9417
  seen.add(feature.cap);
9418
9418
  });
9419
9419
  });
9420
+ var NodeColorIdSchema = _enum([
9421
+ "node-a",
9422
+ "node-b",
9423
+ "node-c",
9424
+ "node-d",
9425
+ "node-e",
9426
+ "node-f",
9427
+ "node-g",
9428
+ "node-h"
9429
+ ]);
9420
9430
  new Set([
9421
9431
  "track",
9422
9432
  "face",
@@ -27509,24 +27519,69 @@ var RetrainFrameListSchema = object({
27509
27519
  /** What the page pre-selects — the native key frame when one survives. */
27510
27520
  autoPickMediaId: number().int().optional()
27511
27521
  });
27522
+ /** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
27523
+ var RetrainFrameWorkStateSchema = _enum([
27524
+ "unannotated",
27525
+ "annotated",
27526
+ "complete"
27527
+ ]);
27528
+ /**
27529
+ * Filters for paginated corpus list, KPI, and matching export (design §4.4).
27530
+ * Every narrowing field is ANDed; omitted fields impose no constraint.
27531
+ */
27532
+ var RetrainCorpusFilterSchema = object({
27533
+ workState: RetrainFrameWorkStateSchema.optional(),
27534
+ deviceIds: array(number()).max(500).optional(),
27535
+ /** When set, only frames in this named collection. */
27536
+ collectionId: string().optional(),
27537
+ /** Frames that carry at least one saved annotation in one of these classes. */
27538
+ classes: array(RetrainMacroClassSchema).optional(),
27539
+ page: number().int().positive().default(1),
27540
+ pageSize: number().int().positive().max(100).default(50)
27541
+ });
27542
+ var RetrainCorpusPageSchema = object({
27543
+ frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
27544
+ total: number().int().nonnegative(),
27545
+ page: number().int().positive(),
27546
+ pageSize: number().int().positive()
27547
+ });
27548
+ var RetrainCorpusKpiCameraRowSchema = object({
27549
+ deviceId: number(),
27550
+ unannotated: number().int().nonnegative(),
27551
+ annotated: number().int().nonnegative(),
27552
+ complete: number().int().nonnegative(),
27553
+ /** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
27554
+ * `null` when the corpus is empty (no ratio). */
27555
+ pctOfCorpus: number().min(0).max(1).nullable()
27556
+ });
27557
+ var RetrainCorpusKpiSchema = object({
27558
+ total: number().int().nonnegative(),
27559
+ unannotated: number().int().nonnegative(),
27560
+ annotated: number().int().nonnegative(),
27561
+ complete: number().int().nonnegative(),
27562
+ cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
27563
+ });
27512
27564
  /**
27513
27565
  * Which frames an annotated export carries. Every field narrows; an empty
27514
- * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
27515
- * list owned by whoever trains (the training orchestrator), so `frameIds` is
27516
- * the primitive a version export uses; `batchId` re-selects what an earlier
27517
- * export carried (`exportedInBatch`).
27566
+ * filter is every annotated copy. `frameIds` is the primitive a job or
27567
+ * download uses; `batchId` re-selects what an earlier export carried
27568
+ * (`exportedInBatch`). Frozen dataset versions were removed — live selection
27569
+ * resolves to `frameIds` at plan/start.
27518
27570
  */
27519
27571
  var RetrainExportFilterSchema = object({
27520
27572
  deviceIds: array(number()).optional(),
27521
27573
  frameIds: array(string()).max(2e4).optional(),
27522
27574
  /** Only frames in at least one of these named collections. */
27523
27575
  collectionIds: array(string()).max(200).optional(),
27524
- /** Exactly the frames of this dataset version (and its completeOnly). An
27525
- * unknown id selects nothing. */
27526
- datasetVersionId: string().optional(),
27576
+ /** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
27577
+ collectionId: string().optional(),
27527
27578
  batchId: string().optional(),
27528
27579
  /** Only frames the operator marked complete (all subjects boxed). */
27529
- completeOnly: boolean().optional()
27580
+ completeOnly: boolean().optional(),
27581
+ /** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
27582
+ workState: RetrainFrameWorkStateSchema.optional(),
27583
+ /** Frames with at least one saved annotation in one of these classes. */
27584
+ classes: array(RetrainMacroClassSchema).optional()
27530
27585
  });
27531
27586
  /**
27532
27587
  * `frames`: the full frame copies, boxes in `annotations.json`.
@@ -27726,8 +27781,7 @@ var RetrainDatasetStatsSchema = object({
27726
27781
  completeFrames: number().int()
27727
27782
  })).readonly()
27728
27783
  });
27729
- /** An immutable dataset version, without its frame list. */
27730
- var RetrainDatasetVersionSchema = object({
27784
+ object({
27731
27785
  id: string(),
27732
27786
  name: string(),
27733
27787
  createdAt: number(),
@@ -27735,22 +27789,33 @@ var RetrainDatasetVersionSchema = object({
27735
27789
  layout: RetrainExportLayoutSchema,
27736
27790
  completeOnly: boolean(),
27737
27791
  frameCount: number().int(),
27738
- /** sha256 of what the frames taught when the version was frozen. */
27739
27792
  annotationHash: string(),
27740
- /** The export manifest schema the version was cut under. */
27741
27793
  manifestSchema: string(),
27742
27794
  stats: RetrainDatasetStatsSchema
27743
27795
  });
27744
- var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
27745
- kind: literal("created"),
27746
- version: RetrainDatasetVersionSchema
27796
+ /**
27797
+ * Live training corpus criteria — same shape as `TrainingCorpusSelection` on
27798
+ * the training cap. Resolved here so plan/start and the annotated export share
27799
+ * one definition of "the frames" (`buildRetrainExportPlan`).
27800
+ */
27801
+ var RetrainTrainingCorpusSelectionSchema = object({
27802
+ collectionIds: array(string()).min(1),
27803
+ workState: _enum([
27804
+ "complete",
27805
+ "annotated_or_complete",
27806
+ "any_annotated"
27807
+ ]).default("complete")
27808
+ });
27809
+ var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
27810
+ kind: literal("resolved"),
27811
+ frameIds: array(string()).max(2e4).readonly(),
27812
+ stats: RetrainDatasetStatsSchema,
27813
+ annotationHash: string(),
27814
+ layout: RetrainExportLayoutSchema
27747
27815
  }), object({
27748
27816
  kind: literal("refused"),
27749
- reason: _enum([
27750
- "empty-name",
27751
- "duplicate-name",
27752
- "no-frames"
27753
- ])
27817
+ reason: _enum(["unknown-collection", "no-frames"]),
27818
+ detail: string()
27754
27819
  })]);
27755
27820
  /** The outcome of a lifecycle move owned by the retrain page. */
27756
27821
  var RetrainTransitionResultSchema = object({
@@ -28896,6 +28961,26 @@ var pipelineAnalyticsCapability = {
28896
28961
  auth: "admin"
28897
28962
  }),
28898
28963
  /**
28964
+ * Paginated corpus copies for the Frames grid — index reads only.
28965
+ *
28966
+ * Filters AND (`workState`, cameras, one collection, annotated classes).
28967
+ * An answered empty match is `{ frames: [], total: 0, … }` (D315), never a
28968
+ * pending masquerade. Classification uses `workStateOf` (annotation count
28969
+ * wins over a stray `complete` flag).
28970
+ */
28971
+ listRetrainCorpusPage: method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
28972
+ kind: "query",
28973
+ auth: "admin"
28974
+ }),
28975
+ /**
28976
+ * Global + per-camera corpus KPI. Unfiltered totals; `%` on a camera row is
28977
+ * `complete(camera) / corpus total`, or `null` when the corpus is empty.
28978
+ */
28979
+ getRetrainCorpusKpi: method(object({}), RetrainCorpusKpiSchema, {
28980
+ kind: "query",
28981
+ auth: "admin"
28982
+ }),
28983
+ /**
28899
28984
  * What a track can contribute, and what it already has.
28900
28985
  *
28901
28986
  * `candidates` are the track's whole, unannotated frames — index rows only,
@@ -29122,53 +29207,6 @@ var pipelineAnalyticsCapability = {
29122
29207
  auth: "admin",
29123
29208
  timeoutMs: 12e4
29124
29209
  }),
29125
- /** The counts a selection would freeze — class × camera × day/night,
29126
- * completeness — without freezing anything. Index reads only. */
29127
- previewRetrainDataset: method(object({
29128
- selection: RetrainDatasetSelectionSchema,
29129
- completeOnly: boolean().optional()
29130
- }), RetrainDatasetStatsSchema, {
29131
- kind: "query",
29132
- auth: "admin"
29133
- }),
29134
- /**
29135
- * Freeze a dataset version: the frames the selection yields (the same plan
29136
- * the annotated export builds), the hash of what they teach, the export
29137
- * parameters and the counts. Immutable — a different selection is a new
29138
- * version. Export it with `getRetrainExportUrl({ datasetVersionId })`.
29139
- */
29140
- createRetrainDatasetVersion: method(object({
29141
- name: string().max(120),
29142
- selection: RetrainDatasetSelectionSchema,
29143
- layout: RetrainExportLayoutSchema,
29144
- completeOnly: boolean()
29145
- }), CreateRetrainDatasetVersionResultSchema, {
29146
- kind: "mutation",
29147
- auth: "admin",
29148
- timeoutMs: 12e4
29149
- }),
29150
- /** Every dataset version, newest first. */
29151
- listRetrainDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
29152
- kind: "query",
29153
- auth: "admin"
29154
- }),
29155
- /** Delete a version. Its frames stay in the dataset. */
29156
- deleteRetrainDatasetVersion: method(object({ id: string() }), object({ deleted: boolean() }), {
29157
- kind: "mutation",
29158
- auth: "admin"
29159
- }),
29160
- /** Does the corpus still teach what the version froze? `missingFrames`
29161
- * counts frames that left the dataset (or lost every box and tick). */
29162
- verifyRetrainDatasetVersion: method(object({ id: string() }), object({
29163
- found: boolean(),
29164
- annotationHash: string(),
29165
- matches: boolean(),
29166
- missingFrames: number().int()
29167
- }), {
29168
- kind: "query",
29169
- auth: "admin",
29170
- timeoutMs: 12e4
29171
- }),
29172
29210
  /** The enabled, vision-capable LLM profiles, each saying whether a frame
29173
29211
  * sent to it leaves the house. */
29174
29212
  listRetrainAssistProfiles: method(object({}), array(RetrainAssistProfileSchema).readonly(), {
@@ -29215,6 +29253,16 @@ var pipelineAnalyticsCapability = {
29215
29253
  kind: "query",
29216
29254
  auth: "admin"
29217
29255
  }),
29256
+ /**
29257
+ * Resolve a live training corpus selection to frame ids + stats (index
29258
+ * reads only). Same plan the annotated export builds — training plan/start
29259
+ * calls this instead of a frozen dataset version.
29260
+ */
29261
+ resolveRetrainTrainingCorpus: method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
29262
+ kind: "query",
29263
+ auth: "admin",
29264
+ timeoutMs: 6e4
29265
+ }),
29218
29266
  renameRetrainCollection: method(object({
29219
29267
  id: string(),
29220
29268
  name: string().max(120)
@@ -30168,11 +30216,14 @@ var HardwareClassIdSchema = _enum([
30168
30216
  "intel-n-series",
30169
30217
  "apple-m-base",
30170
30218
  "apple-m-pro",
30219
+ "amd-phoenix",
30171
30220
  "unknown"
30172
30221
  ]);
30173
30222
  var AcceleratorKindSchema = _enum([
30174
30223
  "intel-npu",
30175
30224
  "intel-igpu",
30225
+ "amd-igpu",
30226
+ "amd-npu",
30176
30227
  "x86-cpu",
30177
30228
  "arm-cpu",
30178
30229
  "apple-ane",
@@ -32308,6 +32359,8 @@ var AgentPipelineSettingsSchema = object({
32308
32359
  * address is wrong (multi-homed host, NAT, custom interface).
32309
32360
  */
32310
32361
  reachableHost: string().optional(),
32362
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
32363
+ color: NodeColorIdSchema.optional(),
32311
32364
  /**
32312
32365
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
32313
32366
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -33034,8 +33087,9 @@ var pipelineOrchestratorCapability = {
33034
33087
  */
33035
33088
  setAgentReachableHost: method(object({
33036
33089
  agentNodeId: string(),
33037
- reachableHost: string().nullable()
33038
- }), object({ success: literal(true) }), {
33090
+ reachableHost: string().nullable().optional(),
33091
+ color: NodeColorIdSchema.nullable().optional()
33092
+ }).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
33039
33093
  kind: "mutation",
33040
33094
  auth: "admin"
33041
33095
  }),
@@ -44029,7 +44083,15 @@ var GpuInfoSchema = object({
44029
44083
  name: string(),
44030
44084
  memoryMB: number().optional()
44031
44085
  });
44032
- var NpuInfoSchema = object({ type: _enum(["apple-ane", "intel-npu"]) });
44086
+ var NpuInfoSchema = object({
44087
+ type: _enum([
44088
+ "apple-ane",
44089
+ "intel-npu",
44090
+ "amd-xdna"
44091
+ ]),
44092
+ name: string().optional(),
44093
+ generation: _enum(["xdna1", "xdna2"]).optional()
44094
+ });
44033
44095
  var CoralInfoSchema = object({
44034
44096
  type: literal("coral-edgetpu"),
44035
44097
  bus: string().optional()
@@ -49356,9 +49418,11 @@ var zoneRulesCapability = {
49356
49418
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
49357
49419
  * manifest entry and nothing else.
49358
49420
  *
49359
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
49360
- * `notification-output` posture); `describe` concat-fans across providers.
49361
- * Every method is `admin`: these spend money.
49421
+ * Collection of provider **types** (addons). Each addon owns zero or more
49422
+ * **entries** (credentials + defaults). Concat-fans: `describe`,
49423
+ * `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
49424
+ * `entryId`; callers also pass the owning `addonId` as the collection
49425
+ * selector (broker posture). Every method is `admin`: these spend money.
49362
49426
  *
49363
49427
  * Every cloud object a provider creates is tagged with the orchestrator's
49364
49428
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -49382,8 +49446,8 @@ var TrainingRegionOptionSchema = object({
49382
49446
  priceMultiplier: number().positive()
49383
49447
  });
49384
49448
  /**
49385
- * The provider's per-account settings, as the orchestrator reads them. They
49386
- * live in the PROVIDER addon's settings (operator decision 2026-10-08: they
49449
+ * The provider's per-entry settings, as the orchestrator reads them. They
49450
+ * live on the PROVIDER addon's entry (operator decision 2026-10-08: they
49387
49451
  * depend on the user's account), never hard-coded in the orchestrator.
49388
49452
  */
49389
49453
  var TrainingProviderDefaultsSchema = object({
@@ -49394,9 +49458,32 @@ var TrainingProviderDefaultsSchema = object({
49394
49458
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
49395
49459
  failedDatasetGraceHours: number().nonnegative()
49396
49460
  });
49461
+ /** One creatable provider type, for the Add-entry dialog. */
49462
+ var TrainingProviderTypeSchema = object({
49463
+ typeId: string(),
49464
+ label: string(),
49465
+ /** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
49466
+ iconAsset: string(),
49467
+ /** Owning `training-provider` addon — collection selector for createEntry. */
49468
+ addonId: string()
49469
+ });
49470
+ /** One configured account / workspace under a provider type. */
49471
+ var TrainingProviderEntrySchema = object({
49472
+ entryId: string(),
49473
+ typeId: string(),
49474
+ name: string(),
49475
+ addonId: string(),
49476
+ /** Credentials are present — never the values. */
49477
+ configured: boolean()
49478
+ });
49397
49479
  var TrainingProviderDescriptorSchema = object({
49398
49480
  addonId: string(),
49399
- /** `modal`, `runpod`, `fake`, … */
49481
+ entryId: string(),
49482
+ typeId: string(),
49483
+ /** Operator-chosen entry name. */
49484
+ name: string(),
49485
+ iconAsset: string(),
49486
+ /** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
49400
49487
  kind: string(),
49401
49488
  label: string(),
49402
49489
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -49460,8 +49547,9 @@ var TrainerSourceRefSchema = object({
49460
49547
  /** A commit sha (never a branch) — the job must be reproducible. */
49461
49548
  revision: string().regex(/^[0-9a-f]{7,64}$/)
49462
49549
  });
49550
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
49463
49551
  var JobRef = {
49464
- addonId: string(),
49552
+ entryId: string().min(1),
49465
49553
  jobKey: string().uuid()
49466
49554
  };
49467
49555
  var TrainingLogLineSchema = object({
@@ -49474,17 +49562,37 @@ var trainingProviderCapability = {
49474
49562
  mode: "collection",
49475
49563
  internal: true,
49476
49564
  methods: {
49477
- /** Every provider's offer and settings. Concat-fans across providers. */
49565
+ /** Every entry's offer and settings. Concat-fans across providers. */
49478
49566
  describe: method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }),
49479
- /** Call the provider with the stored credentials. Never returns them. */
49480
- validateCredentials: method(object({ addonId: string() }), TrainingCredentialCheckSchema, {
49567
+ /** Creatable types for the Add-entry dialog. Concat-fans. */
49568
+ describeTypes: method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }),
49569
+ /** Configured entries (pills). Concat-fans. */
49570
+ listEntries: method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }),
49571
+ /**
49572
+ * Create an entry under this provider type. Pin with `{ addonId }` of the
49573
+ * type's owning addon (from describeTypes).
49574
+ */
49575
+ createEntry: method(object({
49576
+ typeId: string().min(1),
49577
+ name: string().min(1)
49578
+ }), object({ entryId: string() }), {
49579
+ kind: "mutation",
49580
+ auth: "admin"
49581
+ }),
49582
+ /** Delete an entry. Pin with the owning `{ addonId }`. */
49583
+ deleteEntry: method(object({ entryId: string().min(1) }), object({ ok: literal(true) }), {
49584
+ kind: "mutation",
49585
+ auth: "admin"
49586
+ }),
49587
+ /** Call the provider with the entry's stored credentials. Never returns them. */
49588
+ validateCredentials: method(object({ entryId: string().min(1) }), TrainingCredentialCheckSchema, {
49481
49589
  kind: "mutation",
49482
49590
  auth: "admin",
49483
49591
  timeoutMs: 3e4
49484
49592
  }),
49485
49593
  /** USD range for a run of `gpuSeconds` on `gpuType` in `region`. */
49486
49594
  estimateJob: method(object({
49487
- addonId: string(),
49595
+ entryId: string().min(1),
49488
49596
  gpuType: string(),
49489
49597
  region: string(),
49490
49598
  datasetBytes: number().int().nonnegative(),
@@ -49580,8 +49688,11 @@ var trainingProviderCapability = {
49580
49688
  auth: "admin",
49581
49689
  timeoutMs: 5 * 6e4
49582
49690
  }),
49583
- /** Every job the provider can still see — the orphan sweep diffs it against our records. */
49584
- listJobs: method(object({ addonId: string() }), array(ProviderJobStatusSchema).readonly(), {
49691
+ /**
49692
+ * Jobs this provider can still see. Optional `entryId` filters; omit to
49693
+ * list every entry (orphan sweep). Pin with `{ addonId }`.
49694
+ */
49695
+ listJobs: method(object({ entryId: string().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
49585
49696
  auth: "admin",
49586
49697
  timeoutMs: 2 * 6e4
49587
49698
  })
@@ -49593,20 +49704,31 @@ var trainingProviderCapability = {
49593
49704
  *
49594
49705
  * It owns what every provider must agree on, written once:
49595
49706
  *
49596
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
49597
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
49598
- * the export plan) and reaches this store through the five row methods
49599
- * below, so the Retrain page and the export did not change.
49600
49707
  * - **Jobs.** A persisted state machine, a reconcile loop against the
49601
49708
  * provider, a cost guard, a daily orphan sweep and the retention rules.
49602
49709
  * - **The return flow.** Verified artefacts → Model Studio
49603
49710
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
49604
49711
  * rollback. Nothing is ever registered automatically.
49605
49712
  *
49713
+ * Plan/start takes a live {@link TrainingCorpusSelection} (collections +
49714
+ * work-state rule); frame ids are resolved via pipeline-analytics at that
49715
+ * moment and snapshotted on the job. No frozen dataset version.
49716
+ *
49606
49717
  * Every method is `admin`.
49607
49718
  */
49608
- /** A version WITH its frame list — what the export and a job read. */
49609
- var TrainingDatasetVersionRowSchema = RetrainDatasetVersionSchema.omit({ frameCount: true }).extend({ frameIds: array(string()).max(2e4).readonly() });
49719
+ /**
49720
+ * Live corpus criteria for plan/start (design §5.2). Default is complete-only.
49721
+ * Frame ids are resolved at plan/start — never a frozen version id.
49722
+ */
49723
+ var TrainingCorpusSelectionSchema = object({
49724
+ collectionIds: array(string()).min(1),
49725
+ /** Default complete-only for v1 */
49726
+ workState: _enum([
49727
+ "complete",
49728
+ "annotated_or_complete",
49729
+ "any_annotated"
49730
+ ]).default("complete")
49731
+ });
49610
49732
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
49611
49733
  var TrainingBaseModelSchema = object({
49612
49734
  modelId: string(),
@@ -49624,9 +49746,13 @@ var TrainingPresetSchema = _enum([
49624
49746
  "thorough"
49625
49747
  ]);
49626
49748
  var TrainingJobRequestSchema = object({
49627
- datasetVersionId: string().min(1),
49628
- /** The `training-provider` addon that runs it. */
49629
- addonId: string().min(1),
49749
+ /** Live collection + work-state criteria; resolved at plan/start. */
49750
+ selection: TrainingCorpusSelectionSchema,
49751
+ /**
49752
+ * The provider **entry** that runs it (credentials + defaults).
49753
+ * Resolve to an owning addon via `training-provider.describe` / `listEntries`.
49754
+ */
49755
+ entryId: string().min(1),
49630
49756
  gpuType: string().min(1),
49631
49757
  region: string(),
49632
49758
  baseModelId: string().min(1),
@@ -49685,6 +49811,7 @@ var TrainingJobPlanSchema = object({
49685
49811
  * result lives after the operator acted on it.
49686
49812
  */
49687
49813
  var TrainingJobStateSchema = _enum([
49814
+ "queued",
49688
49815
  "uploading",
49689
49816
  "submitted",
49690
49817
  "starting",
@@ -49738,6 +49865,11 @@ var TrainingJobSchema = object({
49738
49865
  createdAt: number(),
49739
49866
  updatedAt: number(),
49740
49867
  state: TrainingJobStateSchema,
49868
+ /**
49869
+ * Shared by every job enqueued together via `startJobBatch`.
49870
+ * `null` for a lone `startJob`. The engine advances queued siblings by this id.
49871
+ */
49872
+ batchId: string().nullable().default(null),
49741
49873
  stage: TrainingStageSchema.nullable(),
49742
49874
  failure: object({
49743
49875
  reason: TrainingFailureReasonSchema,
@@ -49749,6 +49881,12 @@ var TrainingJobSchema = object({
49749
49881
  maxRuntimeSec: number().int().positive(),
49750
49882
  trainer: TrainerSourceRefSchema,
49751
49883
  datasetLayout: RetrainExportLayoutSchema,
49884
+ /** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
49885
+ frameCount: number().int().nonnegative(),
49886
+ /** Resolved frame ids at start — the archive ships exactly these. */
49887
+ frameIds: array(string()).max(2e4).readonly(),
49888
+ /** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
49889
+ annotationHash: string(),
49752
49890
  dataset: object({
49753
49891
  bytes: number().int(),
49754
49892
  sha256: string(),
@@ -49796,19 +49934,6 @@ var trainingCapability = {
49796
49934
  mode: "singleton",
49797
49935
  mount: { kind: "hub-only" },
49798
49936
  methods: {
49799
- /** Store a version once. `stored: false` = that id already exists (immutable). */
49800
- putDatasetVersion: method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
49801
- kind: "mutation",
49802
- auth: "admin"
49803
- }),
49804
- getDatasetVersion: method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }),
49805
- /** Every version without its frame list, newest first. */
49806
- listDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }),
49807
- findDatasetVersionIdByName: method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }),
49808
- removeDatasetVersion: method(IdInput, object({ removed: boolean() }), {
49809
- kind: "mutation",
49810
- auth: "admin"
49811
- }),
49812
49937
  listBaseModels: method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }),
49813
49938
  /** Split, estimate, defaults and any named refusal — nothing is started. */
49814
49939
  planJob: method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
@@ -49837,6 +49962,32 @@ var trainingCapability = {
49837
49962
  auth: "admin",
49838
49963
  timeoutMs: 12e4
49839
49964
  }),
49965
+ /**
49966
+ * Enqueue one job per base model (same selection, entry, caps). The first
49967
+ * becomes `uploading`; the rest stay `queued` until the prior job settles.
49968
+ * One ACTIVE job at a time — a parallel `startJob` still gets
49969
+ * `job-already-running`. The same `idempotencyKey` returns the batch it
49970
+ * already started.
49971
+ */
49972
+ startJobBatch: method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
49973
+ baseModelIds: array(string().min(1)).min(1),
49974
+ name: string().min(1).max(120),
49975
+ maxCostUsd: number().positive(),
49976
+ maxRuntimeSec: number().int().positive(),
49977
+ idempotencyKey: string().min(8).max(80)
49978
+ }), discriminatedUnion("kind", [object({
49979
+ kind: literal("started"),
49980
+ batchId: string(),
49981
+ jobs: array(TrainingJobSchema).min(1).readonly()
49982
+ }), object({
49983
+ kind: literal("refused"),
49984
+ reason: TrainingRefusalReasonSchema,
49985
+ detail: string()
49986
+ })]), {
49987
+ kind: "mutation",
49988
+ auth: "admin",
49989
+ timeoutMs: 12e4
49990
+ }),
49840
49991
  listJobs: method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }),
49841
49992
  getJob: method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }),
49842
49993
  cancelJob: method(IdInput, TrainingJobSchema, {
@@ -54410,12 +54561,6 @@ Object.freeze({
54410
54561
  addonId: null,
54411
54562
  access: "create"
54412
54563
  },
54413
- "pipelineAnalytics.createRetrainDatasetVersion": {
54414
- capName: "pipeline-analytics",
54415
- capScope: "device",
54416
- addonId: null,
54417
- access: "create"
54418
- },
54419
54564
  "pipelineAnalytics.deleteDeviceEvents": {
54420
54565
  capName: "pipeline-analytics",
54421
54566
  capScope: "device",
@@ -54428,12 +54573,6 @@ Object.freeze({
54428
54573
  addonId: null,
54429
54574
  access: "delete"
54430
54575
  },
54431
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
54432
- capName: "pipeline-analytics",
54433
- capScope: "device",
54434
- addonId: null,
54435
- access: "delete"
54436
- },
54437
54576
  "pipelineAnalytics.deleteTracks": {
54438
54577
  capName: "pipeline-analytics",
54439
54578
  capScope: "device",
@@ -54536,6 +54675,12 @@ Object.freeze({
54536
54675
  addonId: null,
54537
54676
  access: "view"
54538
54677
  },
54678
+ "pipelineAnalytics.getRetrainCorpusKpi": {
54679
+ capName: "pipeline-analytics",
54680
+ capScope: "device",
54681
+ addonId: null,
54682
+ access: "view"
54683
+ },
54539
54684
  "pipelineAnalytics.getRetrainExportUrl": {
54540
54685
  capName: "pipeline-analytics",
54541
54686
  capScope: "device",
@@ -54656,7 +54801,7 @@ Object.freeze({
54656
54801
  addonId: null,
54657
54802
  access: "view"
54658
54803
  },
54659
- "pipelineAnalytics.listRetrainDatasetVersions": {
54804
+ "pipelineAnalytics.listRetrainCorpusPage": {
54660
54805
  capName: "pipeline-analytics",
54661
54806
  capScope: "device",
54662
54807
  addonId: null,
@@ -54710,12 +54855,6 @@ Object.freeze({
54710
54855
  addonId: null,
54711
54856
  access: "create"
54712
54857
  },
54713
- "pipelineAnalytics.previewRetrainDataset": {
54714
- capName: "pipeline-analytics",
54715
- capScope: "device",
54716
- addonId: null,
54717
- access: "view"
54718
- },
54719
54858
  "pipelineAnalytics.proposeRetrainAnnotations": {
54720
54859
  capName: "pipeline-analytics",
54721
54860
  capScope: "device",
@@ -54794,6 +54933,12 @@ Object.freeze({
54794
54933
  addonId: null,
54795
54934
  access: "create"
54796
54935
  },
54936
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
54937
+ capName: "pipeline-analytics",
54938
+ capScope: "device",
54939
+ addonId: null,
54940
+ access: "view"
54941
+ },
54797
54942
  "pipelineAnalytics.restageRetrainTrack": {
54798
54943
  capName: "pipeline-analytics",
54799
54944
  capScope: "device",
@@ -54854,12 +54999,6 @@ Object.freeze({
54854
54999
  addonId: null,
54855
55000
  access: "create"
54856
55001
  },
54857
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
54858
- capName: "pipeline-analytics",
54859
- capScope: "device",
54860
- addonId: null,
54861
- access: "view"
54862
- },
54863
55002
  "pipelineAnalytics.wipeAllAnalytics": {
54864
55003
  capName: "pipeline-analytics",
54865
55004
  capScope: "device",
@@ -57254,18 +57393,6 @@ Object.freeze({
57254
57393
  addonId: null,
57255
57394
  access: "create"
57256
57395
  },
57257
- "training.findDatasetVersionIdByName": {
57258
- capName: "training",
57259
- capScope: "system",
57260
- addonId: null,
57261
- access: "view"
57262
- },
57263
- "training.getDatasetVersion": {
57264
- capName: "training",
57265
- capScope: "system",
57266
- addonId: null,
57267
- access: "view"
57268
- },
57269
57396
  "training.getJob": {
57270
57397
  capName: "training",
57271
57398
  capScope: "system",
@@ -57284,12 +57411,6 @@ Object.freeze({
57284
57411
  addonId: null,
57285
57412
  access: "view"
57286
57413
  },
57287
- "training.listDatasetVersions": {
57288
- capName: "training",
57289
- capScope: "system",
57290
- addonId: null,
57291
- access: "view"
57292
- },
57293
57414
  "training.listJobs": {
57294
57415
  capName: "training",
57295
57416
  capScope: "system",
@@ -57302,54 +57423,66 @@ Object.freeze({
57302
57423
  addonId: null,
57303
57424
  access: "view"
57304
57425
  },
57305
- "training.putDatasetVersion": {
57426
+ "training.registerResult": {
57306
57427
  capName: "training",
57307
57428
  capScope: "system",
57308
57429
  addonId: null,
57309
57430
  access: "create"
57310
57431
  },
57311
- "training.registerResult": {
57432
+ "training.rollbackCanary": {
57312
57433
  capName: "training",
57313
57434
  capScope: "system",
57314
57435
  addonId: null,
57315
57436
  access: "create"
57316
57437
  },
57317
- "training.removeDatasetVersion": {
57438
+ "training.startJob": {
57318
57439
  capName: "training",
57319
57440
  capScope: "system",
57320
57441
  addonId: null,
57321
- access: "delete"
57442
+ access: "create"
57322
57443
  },
57323
- "training.rollbackCanary": {
57444
+ "training.startJobBatch": {
57324
57445
  capName: "training",
57325
57446
  capScope: "system",
57326
57447
  addonId: null,
57327
57448
  access: "create"
57328
57449
  },
57329
- "training.startJob": {
57330
- capName: "training",
57450
+ "trainingProvider.cancelJob": {
57451
+ capName: "training-provider",
57331
57452
  capScope: "system",
57332
57453
  addonId: null,
57333
57454
  access: "create"
57334
57455
  },
57335
- "trainingProvider.cancelJob": {
57456
+ "trainingProvider.cleanupJob": {
57336
57457
  capName: "training-provider",
57337
57458
  capScope: "system",
57338
57459
  addonId: null,
57339
57460
  access: "create"
57340
57461
  },
57341
- "trainingProvider.cleanupJob": {
57462
+ "trainingProvider.createEntry": {
57342
57463
  capName: "training-provider",
57343
57464
  capScope: "system",
57344
57465
  addonId: null,
57345
57466
  access: "create"
57346
57467
  },
57468
+ "trainingProvider.deleteEntry": {
57469
+ capName: "training-provider",
57470
+ capScope: "system",
57471
+ addonId: null,
57472
+ access: "delete"
57473
+ },
57347
57474
  "trainingProvider.describe": {
57348
57475
  capName: "training-provider",
57349
57476
  capScope: "system",
57350
57477
  addonId: null,
57351
57478
  access: "view"
57352
57479
  },
57480
+ "trainingProvider.describeTypes": {
57481
+ capName: "training-provider",
57482
+ capScope: "system",
57483
+ addonId: null,
57484
+ access: "view"
57485
+ },
57353
57486
  "trainingProvider.estimateJob": {
57354
57487
  capName: "training-provider",
57355
57488
  capScope: "system",
@@ -57362,6 +57495,12 @@ Object.freeze({
57362
57495
  addonId: null,
57363
57496
  access: "view"
57364
57497
  },
57498
+ "trainingProvider.listEntries": {
57499
+ capName: "training-provider",
57500
+ capScope: "system",
57501
+ addonId: null,
57502
+ access: "view"
57503
+ },
57365
57504
  "trainingProvider.listJobEvents": {
57366
57505
  capName: "training-provider",
57367
57506
  capScope: "system",
@@ -60998,6 +61137,11 @@ Object.freeze({
60998
61137
  form: "array",
60999
61138
  optional: false
61000
61139
  }],
61140
+ "pipelineAnalytics.listRetrainCorpusPage": [{
61141
+ name: "deviceIds",
61142
+ form: "array",
61143
+ optional: true
61144
+ }],
61001
61145
  "pipelineAnalytics.listRetrainStaging": [{
61002
61146
  name: "deviceIds",
61003
61147
  form: "array",