@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.js CHANGED
@@ -5380,7 +5380,7 @@ var ZodIssueCode = {
5380
5380
  var ZodFirstPartyTypeKind;
5381
5381
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5382
5382
  //#endregion
5383
- //#region ../types/dist/sleep-r3RWkGVx.mjs
5383
+ //#region ../types/dist/sleep-CI0n5D44.mjs
5384
5384
  /**
5385
5385
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5386
5386
  * window to float samples (D455).
@@ -9421,6 +9421,16 @@ var CompositionSchema = object({
9421
9421
  seen.add(feature.cap);
9422
9422
  });
9423
9423
  });
9424
+ var NodeColorIdSchema = _enum([
9425
+ "node-a",
9426
+ "node-b",
9427
+ "node-c",
9428
+ "node-d",
9429
+ "node-e",
9430
+ "node-f",
9431
+ "node-g",
9432
+ "node-h"
9433
+ ]);
9424
9434
  new Set([
9425
9435
  "track",
9426
9436
  "face",
@@ -27513,24 +27523,69 @@ var RetrainFrameListSchema = object({
27513
27523
  /** What the page pre-selects — the native key frame when one survives. */
27514
27524
  autoPickMediaId: number().int().optional()
27515
27525
  });
27526
+ /** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
27527
+ var RetrainFrameWorkStateSchema = _enum([
27528
+ "unannotated",
27529
+ "annotated",
27530
+ "complete"
27531
+ ]);
27532
+ /**
27533
+ * Filters for paginated corpus list, KPI, and matching export (design §4.4).
27534
+ * Every narrowing field is ANDed; omitted fields impose no constraint.
27535
+ */
27536
+ var RetrainCorpusFilterSchema = object({
27537
+ workState: RetrainFrameWorkStateSchema.optional(),
27538
+ deviceIds: array(number()).max(500).optional(),
27539
+ /** When set, only frames in this named collection. */
27540
+ collectionId: string().optional(),
27541
+ /** Frames that carry at least one saved annotation in one of these classes. */
27542
+ classes: array(RetrainMacroClassSchema).optional(),
27543
+ page: number().int().positive().default(1),
27544
+ pageSize: number().int().positive().max(100).default(50)
27545
+ });
27546
+ var RetrainCorpusPageSchema = object({
27547
+ frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
27548
+ total: number().int().nonnegative(),
27549
+ page: number().int().positive(),
27550
+ pageSize: number().int().positive()
27551
+ });
27552
+ var RetrainCorpusKpiCameraRowSchema = object({
27553
+ deviceId: number(),
27554
+ unannotated: number().int().nonnegative(),
27555
+ annotated: number().int().nonnegative(),
27556
+ complete: number().int().nonnegative(),
27557
+ /** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
27558
+ * `null` when the corpus is empty (no ratio). */
27559
+ pctOfCorpus: number().min(0).max(1).nullable()
27560
+ });
27561
+ var RetrainCorpusKpiSchema = object({
27562
+ total: number().int().nonnegative(),
27563
+ unannotated: number().int().nonnegative(),
27564
+ annotated: number().int().nonnegative(),
27565
+ complete: number().int().nonnegative(),
27566
+ cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
27567
+ });
27516
27568
  /**
27517
27569
  * Which frames an annotated export carries. Every field narrows; an empty
27518
- * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
27519
- * list owned by whoever trains (the training orchestrator), so `frameIds` is
27520
- * the primitive a version export uses; `batchId` re-selects what an earlier
27521
- * export carried (`exportedInBatch`).
27570
+ * filter is every annotated copy. `frameIds` is the primitive a job or
27571
+ * download uses; `batchId` re-selects what an earlier export carried
27572
+ * (`exportedInBatch`). Frozen dataset versions were removed — live selection
27573
+ * resolves to `frameIds` at plan/start.
27522
27574
  */
27523
27575
  var RetrainExportFilterSchema = object({
27524
27576
  deviceIds: array(number()).optional(),
27525
27577
  frameIds: array(string()).max(2e4).optional(),
27526
27578
  /** Only frames in at least one of these named collections. */
27527
27579
  collectionIds: array(string()).max(200).optional(),
27528
- /** Exactly the frames of this dataset version (and its completeOnly). An
27529
- * unknown id selects nothing. */
27530
- datasetVersionId: string().optional(),
27580
+ /** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
27581
+ collectionId: string().optional(),
27531
27582
  batchId: string().optional(),
27532
27583
  /** Only frames the operator marked complete (all subjects boxed). */
27533
- completeOnly: boolean().optional()
27584
+ completeOnly: boolean().optional(),
27585
+ /** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
27586
+ workState: RetrainFrameWorkStateSchema.optional(),
27587
+ /** Frames with at least one saved annotation in one of these classes. */
27588
+ classes: array(RetrainMacroClassSchema).optional()
27534
27589
  });
27535
27590
  /**
27536
27591
  * `frames`: the full frame copies, boxes in `annotations.json`.
@@ -27730,8 +27785,7 @@ var RetrainDatasetStatsSchema = object({
27730
27785
  completeFrames: number().int()
27731
27786
  })).readonly()
27732
27787
  });
27733
- /** An immutable dataset version, without its frame list. */
27734
- var RetrainDatasetVersionSchema = object({
27788
+ object({
27735
27789
  id: string(),
27736
27790
  name: string(),
27737
27791
  createdAt: number(),
@@ -27739,22 +27793,33 @@ var RetrainDatasetVersionSchema = object({
27739
27793
  layout: RetrainExportLayoutSchema,
27740
27794
  completeOnly: boolean(),
27741
27795
  frameCount: number().int(),
27742
- /** sha256 of what the frames taught when the version was frozen. */
27743
27796
  annotationHash: string(),
27744
- /** The export manifest schema the version was cut under. */
27745
27797
  manifestSchema: string(),
27746
27798
  stats: RetrainDatasetStatsSchema
27747
27799
  });
27748
- var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
27749
- kind: literal("created"),
27750
- version: RetrainDatasetVersionSchema
27800
+ /**
27801
+ * Live training corpus criteria — same shape as `TrainingCorpusSelection` on
27802
+ * the training cap. Resolved here so plan/start and the annotated export share
27803
+ * one definition of "the frames" (`buildRetrainExportPlan`).
27804
+ */
27805
+ var RetrainTrainingCorpusSelectionSchema = object({
27806
+ collectionIds: array(string()).min(1),
27807
+ workState: _enum([
27808
+ "complete",
27809
+ "annotated_or_complete",
27810
+ "any_annotated"
27811
+ ]).default("complete")
27812
+ });
27813
+ var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
27814
+ kind: literal("resolved"),
27815
+ frameIds: array(string()).max(2e4).readonly(),
27816
+ stats: RetrainDatasetStatsSchema,
27817
+ annotationHash: string(),
27818
+ layout: RetrainExportLayoutSchema
27751
27819
  }), object({
27752
27820
  kind: literal("refused"),
27753
- reason: _enum([
27754
- "empty-name",
27755
- "duplicate-name",
27756
- "no-frames"
27757
- ])
27821
+ reason: _enum(["unknown-collection", "no-frames"]),
27822
+ detail: string()
27758
27823
  })]);
27759
27824
  /** The outcome of a lifecycle move owned by the retrain page. */
27760
27825
  var RetrainTransitionResultSchema = object({
@@ -28900,6 +28965,26 @@ var pipelineAnalyticsCapability = {
28900
28965
  auth: "admin"
28901
28966
  }),
28902
28967
  /**
28968
+ * Paginated corpus copies for the Frames grid — index reads only.
28969
+ *
28970
+ * Filters AND (`workState`, cameras, one collection, annotated classes).
28971
+ * An answered empty match is `{ frames: [], total: 0, … }` (D315), never a
28972
+ * pending masquerade. Classification uses `workStateOf` (annotation count
28973
+ * wins over a stray `complete` flag).
28974
+ */
28975
+ listRetrainCorpusPage: method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
28976
+ kind: "query",
28977
+ auth: "admin"
28978
+ }),
28979
+ /**
28980
+ * Global + per-camera corpus KPI. Unfiltered totals; `%` on a camera row is
28981
+ * `complete(camera) / corpus total`, or `null` when the corpus is empty.
28982
+ */
28983
+ getRetrainCorpusKpi: method(object({}), RetrainCorpusKpiSchema, {
28984
+ kind: "query",
28985
+ auth: "admin"
28986
+ }),
28987
+ /**
28903
28988
  * What a track can contribute, and what it already has.
28904
28989
  *
28905
28990
  * `candidates` are the track's whole, unannotated frames — index rows only,
@@ -29126,53 +29211,6 @@ var pipelineAnalyticsCapability = {
29126
29211
  auth: "admin",
29127
29212
  timeoutMs: 12e4
29128
29213
  }),
29129
- /** The counts a selection would freeze — class × camera × day/night,
29130
- * completeness — without freezing anything. Index reads only. */
29131
- previewRetrainDataset: method(object({
29132
- selection: RetrainDatasetSelectionSchema,
29133
- completeOnly: boolean().optional()
29134
- }), RetrainDatasetStatsSchema, {
29135
- kind: "query",
29136
- auth: "admin"
29137
- }),
29138
- /**
29139
- * Freeze a dataset version: the frames the selection yields (the same plan
29140
- * the annotated export builds), the hash of what they teach, the export
29141
- * parameters and the counts. Immutable — a different selection is a new
29142
- * version. Export it with `getRetrainExportUrl({ datasetVersionId })`.
29143
- */
29144
- createRetrainDatasetVersion: method(object({
29145
- name: string().max(120),
29146
- selection: RetrainDatasetSelectionSchema,
29147
- layout: RetrainExportLayoutSchema,
29148
- completeOnly: boolean()
29149
- }), CreateRetrainDatasetVersionResultSchema, {
29150
- kind: "mutation",
29151
- auth: "admin",
29152
- timeoutMs: 12e4
29153
- }),
29154
- /** Every dataset version, newest first. */
29155
- listRetrainDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
29156
- kind: "query",
29157
- auth: "admin"
29158
- }),
29159
- /** Delete a version. Its frames stay in the dataset. */
29160
- deleteRetrainDatasetVersion: method(object({ id: string() }), object({ deleted: boolean() }), {
29161
- kind: "mutation",
29162
- auth: "admin"
29163
- }),
29164
- /** Does the corpus still teach what the version froze? `missingFrames`
29165
- * counts frames that left the dataset (or lost every box and tick). */
29166
- verifyRetrainDatasetVersion: method(object({ id: string() }), object({
29167
- found: boolean(),
29168
- annotationHash: string(),
29169
- matches: boolean(),
29170
- missingFrames: number().int()
29171
- }), {
29172
- kind: "query",
29173
- auth: "admin",
29174
- timeoutMs: 12e4
29175
- }),
29176
29214
  /** The enabled, vision-capable LLM profiles, each saying whether a frame
29177
29215
  * sent to it leaves the house. */
29178
29216
  listRetrainAssistProfiles: method(object({}), array(RetrainAssistProfileSchema).readonly(), {
@@ -29219,6 +29257,16 @@ var pipelineAnalyticsCapability = {
29219
29257
  kind: "query",
29220
29258
  auth: "admin"
29221
29259
  }),
29260
+ /**
29261
+ * Resolve a live training corpus selection to frame ids + stats (index
29262
+ * reads only). Same plan the annotated export builds — training plan/start
29263
+ * calls this instead of a frozen dataset version.
29264
+ */
29265
+ resolveRetrainTrainingCorpus: method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
29266
+ kind: "query",
29267
+ auth: "admin",
29268
+ timeoutMs: 6e4
29269
+ }),
29222
29270
  renameRetrainCollection: method(object({
29223
29271
  id: string(),
29224
29272
  name: string().max(120)
@@ -30172,11 +30220,14 @@ var HardwareClassIdSchema = _enum([
30172
30220
  "intel-n-series",
30173
30221
  "apple-m-base",
30174
30222
  "apple-m-pro",
30223
+ "amd-phoenix",
30175
30224
  "unknown"
30176
30225
  ]);
30177
30226
  var AcceleratorKindSchema = _enum([
30178
30227
  "intel-npu",
30179
30228
  "intel-igpu",
30229
+ "amd-igpu",
30230
+ "amd-npu",
30180
30231
  "x86-cpu",
30181
30232
  "arm-cpu",
30182
30233
  "apple-ane",
@@ -32312,6 +32363,8 @@ var AgentPipelineSettingsSchema = object({
32312
32363
  * address is wrong (multi-homed host, NAT, custom interface).
32313
32364
  */
32314
32365
  reachableHost: string().optional(),
32366
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
32367
+ color: NodeColorIdSchema.optional(),
32315
32368
  /**
32316
32369
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
32317
32370
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -33038,8 +33091,9 @@ var pipelineOrchestratorCapability = {
33038
33091
  */
33039
33092
  setAgentReachableHost: method(object({
33040
33093
  agentNodeId: string(),
33041
- reachableHost: string().nullable()
33042
- }), object({ success: literal(true) }), {
33094
+ reachableHost: string().nullable().optional(),
33095
+ color: NodeColorIdSchema.nullable().optional()
33096
+ }).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
33043
33097
  kind: "mutation",
33044
33098
  auth: "admin"
33045
33099
  }),
@@ -44033,7 +44087,15 @@ var GpuInfoSchema = object({
44033
44087
  name: string(),
44034
44088
  memoryMB: number().optional()
44035
44089
  });
44036
- var NpuInfoSchema = object({ type: _enum(["apple-ane", "intel-npu"]) });
44090
+ var NpuInfoSchema = object({
44091
+ type: _enum([
44092
+ "apple-ane",
44093
+ "intel-npu",
44094
+ "amd-xdna"
44095
+ ]),
44096
+ name: string().optional(),
44097
+ generation: _enum(["xdna1", "xdna2"]).optional()
44098
+ });
44037
44099
  var CoralInfoSchema = object({
44038
44100
  type: literal("coral-edgetpu"),
44039
44101
  bus: string().optional()
@@ -49360,9 +49422,11 @@ var zoneRulesCapability = {
49360
49422
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
49361
49423
  * manifest entry and nothing else.
49362
49424
  *
49363
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
49364
- * `notification-output` posture); `describe` concat-fans across providers.
49365
- * Every method is `admin`: these spend money.
49425
+ * Collection of provider **types** (addons). Each addon owns zero or more
49426
+ * **entries** (credentials + defaults). Concat-fans: `describe`,
49427
+ * `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
49428
+ * `entryId`; callers also pass the owning `addonId` as the collection
49429
+ * selector (broker posture). Every method is `admin`: these spend money.
49366
49430
  *
49367
49431
  * Every cloud object a provider creates is tagged with the orchestrator's
49368
49432
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -49386,8 +49450,8 @@ var TrainingRegionOptionSchema = object({
49386
49450
  priceMultiplier: number().positive()
49387
49451
  });
49388
49452
  /**
49389
- * The provider's per-account settings, as the orchestrator reads them. They
49390
- * live in the PROVIDER addon's settings (operator decision 2026-10-08: they
49453
+ * The provider's per-entry settings, as the orchestrator reads them. They
49454
+ * live on the PROVIDER addon's entry (operator decision 2026-10-08: they
49391
49455
  * depend on the user's account), never hard-coded in the orchestrator.
49392
49456
  */
49393
49457
  var TrainingProviderDefaultsSchema = object({
@@ -49398,9 +49462,32 @@ var TrainingProviderDefaultsSchema = object({
49398
49462
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
49399
49463
  failedDatasetGraceHours: number().nonnegative()
49400
49464
  });
49465
+ /** One creatable provider type, for the Add-entry dialog. */
49466
+ var TrainingProviderTypeSchema = object({
49467
+ typeId: string(),
49468
+ label: string(),
49469
+ /** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
49470
+ iconAsset: string(),
49471
+ /** Owning `training-provider` addon — collection selector for createEntry. */
49472
+ addonId: string()
49473
+ });
49474
+ /** One configured account / workspace under a provider type. */
49475
+ var TrainingProviderEntrySchema = object({
49476
+ entryId: string(),
49477
+ typeId: string(),
49478
+ name: string(),
49479
+ addonId: string(),
49480
+ /** Credentials are present — never the values. */
49481
+ configured: boolean()
49482
+ });
49401
49483
  var TrainingProviderDescriptorSchema = object({
49402
49484
  addonId: string(),
49403
- /** `modal`, `runpod`, `fake`, … */
49485
+ entryId: string(),
49486
+ typeId: string(),
49487
+ /** Operator-chosen entry name. */
49488
+ name: string(),
49489
+ iconAsset: string(),
49490
+ /** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
49404
49491
  kind: string(),
49405
49492
  label: string(),
49406
49493
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -49464,8 +49551,9 @@ var TrainerSourceRefSchema = object({
49464
49551
  /** A commit sha (never a branch) — the job must be reproducible. */
49465
49552
  revision: string().regex(/^[0-9a-f]{7,64}$/)
49466
49553
  });
49554
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
49467
49555
  var JobRef = {
49468
- addonId: string(),
49556
+ entryId: string().min(1),
49469
49557
  jobKey: string().uuid()
49470
49558
  };
49471
49559
  var TrainingLogLineSchema = object({
@@ -49478,17 +49566,37 @@ var trainingProviderCapability = {
49478
49566
  mode: "collection",
49479
49567
  internal: true,
49480
49568
  methods: {
49481
- /** Every provider's offer and settings. Concat-fans across providers. */
49569
+ /** Every entry's offer and settings. Concat-fans across providers. */
49482
49570
  describe: method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }),
49483
- /** Call the provider with the stored credentials. Never returns them. */
49484
- validateCredentials: method(object({ addonId: string() }), TrainingCredentialCheckSchema, {
49571
+ /** Creatable types for the Add-entry dialog. Concat-fans. */
49572
+ describeTypes: method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }),
49573
+ /** Configured entries (pills). Concat-fans. */
49574
+ listEntries: method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }),
49575
+ /**
49576
+ * Create an entry under this provider type. Pin with `{ addonId }` of the
49577
+ * type's owning addon (from describeTypes).
49578
+ */
49579
+ createEntry: method(object({
49580
+ typeId: string().min(1),
49581
+ name: string().min(1)
49582
+ }), object({ entryId: string() }), {
49583
+ kind: "mutation",
49584
+ auth: "admin"
49585
+ }),
49586
+ /** Delete an entry. Pin with the owning `{ addonId }`. */
49587
+ deleteEntry: method(object({ entryId: string().min(1) }), object({ ok: literal(true) }), {
49588
+ kind: "mutation",
49589
+ auth: "admin"
49590
+ }),
49591
+ /** Call the provider with the entry's stored credentials. Never returns them. */
49592
+ validateCredentials: method(object({ entryId: string().min(1) }), TrainingCredentialCheckSchema, {
49485
49593
  kind: "mutation",
49486
49594
  auth: "admin",
49487
49595
  timeoutMs: 3e4
49488
49596
  }),
49489
49597
  /** USD range for a run of `gpuSeconds` on `gpuType` in `region`. */
49490
49598
  estimateJob: method(object({
49491
- addonId: string(),
49599
+ entryId: string().min(1),
49492
49600
  gpuType: string(),
49493
49601
  region: string(),
49494
49602
  datasetBytes: number().int().nonnegative(),
@@ -49584,8 +49692,11 @@ var trainingProviderCapability = {
49584
49692
  auth: "admin",
49585
49693
  timeoutMs: 5 * 6e4
49586
49694
  }),
49587
- /** Every job the provider can still see — the orphan sweep diffs it against our records. */
49588
- listJobs: method(object({ addonId: string() }), array(ProviderJobStatusSchema).readonly(), {
49695
+ /**
49696
+ * Jobs this provider can still see. Optional `entryId` filters; omit to
49697
+ * list every entry (orphan sweep). Pin with `{ addonId }`.
49698
+ */
49699
+ listJobs: method(object({ entryId: string().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
49589
49700
  auth: "admin",
49590
49701
  timeoutMs: 2 * 6e4
49591
49702
  })
@@ -49597,20 +49708,31 @@ var trainingProviderCapability = {
49597
49708
  *
49598
49709
  * It owns what every provider must agree on, written once:
49599
49710
  *
49600
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
49601
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
49602
- * the export plan) and reaches this store through the five row methods
49603
- * below, so the Retrain page and the export did not change.
49604
49711
  * - **Jobs.** A persisted state machine, a reconcile loop against the
49605
49712
  * provider, a cost guard, a daily orphan sweep and the retention rules.
49606
49713
  * - **The return flow.** Verified artefacts → Model Studio
49607
49714
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
49608
49715
  * rollback. Nothing is ever registered automatically.
49609
49716
  *
49717
+ * Plan/start takes a live {@link TrainingCorpusSelection} (collections +
49718
+ * work-state rule); frame ids are resolved via pipeline-analytics at that
49719
+ * moment and snapshotted on the job. No frozen dataset version.
49720
+ *
49610
49721
  * Every method is `admin`.
49611
49722
  */
49612
- /** A version WITH its frame list — what the export and a job read. */
49613
- var TrainingDatasetVersionRowSchema = RetrainDatasetVersionSchema.omit({ frameCount: true }).extend({ frameIds: array(string()).max(2e4).readonly() });
49723
+ /**
49724
+ * Live corpus criteria for plan/start (design §5.2). Default is complete-only.
49725
+ * Frame ids are resolved at plan/start — never a frozen version id.
49726
+ */
49727
+ var TrainingCorpusSelectionSchema = object({
49728
+ collectionIds: array(string()).min(1),
49729
+ /** Default complete-only for v1 */
49730
+ workState: _enum([
49731
+ "complete",
49732
+ "annotated_or_complete",
49733
+ "any_annotated"
49734
+ ]).default("complete")
49735
+ });
49614
49736
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
49615
49737
  var TrainingBaseModelSchema = object({
49616
49738
  modelId: string(),
@@ -49628,9 +49750,13 @@ var TrainingPresetSchema = _enum([
49628
49750
  "thorough"
49629
49751
  ]);
49630
49752
  var TrainingJobRequestSchema = object({
49631
- datasetVersionId: string().min(1),
49632
- /** The `training-provider` addon that runs it. */
49633
- addonId: string().min(1),
49753
+ /** Live collection + work-state criteria; resolved at plan/start. */
49754
+ selection: TrainingCorpusSelectionSchema,
49755
+ /**
49756
+ * The provider **entry** that runs it (credentials + defaults).
49757
+ * Resolve to an owning addon via `training-provider.describe` / `listEntries`.
49758
+ */
49759
+ entryId: string().min(1),
49634
49760
  gpuType: string().min(1),
49635
49761
  region: string(),
49636
49762
  baseModelId: string().min(1),
@@ -49689,6 +49815,7 @@ var TrainingJobPlanSchema = object({
49689
49815
  * result lives after the operator acted on it.
49690
49816
  */
49691
49817
  var TrainingJobStateSchema = _enum([
49818
+ "queued",
49692
49819
  "uploading",
49693
49820
  "submitted",
49694
49821
  "starting",
@@ -49742,6 +49869,11 @@ var TrainingJobSchema = object({
49742
49869
  createdAt: number(),
49743
49870
  updatedAt: number(),
49744
49871
  state: TrainingJobStateSchema,
49872
+ /**
49873
+ * Shared by every job enqueued together via `startJobBatch`.
49874
+ * `null` for a lone `startJob`. The engine advances queued siblings by this id.
49875
+ */
49876
+ batchId: string().nullable().default(null),
49745
49877
  stage: TrainingStageSchema.nullable(),
49746
49878
  failure: object({
49747
49879
  reason: TrainingFailureReasonSchema,
@@ -49753,6 +49885,12 @@ var TrainingJobSchema = object({
49753
49885
  maxRuntimeSec: number().int().positive(),
49754
49886
  trainer: TrainerSourceRefSchema,
49755
49887
  datasetLayout: RetrainExportLayoutSchema,
49888
+ /** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
49889
+ frameCount: number().int().nonnegative(),
49890
+ /** Resolved frame ids at start — the archive ships exactly these. */
49891
+ frameIds: array(string()).max(2e4).readonly(),
49892
+ /** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
49893
+ annotationHash: string(),
49756
49894
  dataset: object({
49757
49895
  bytes: number().int(),
49758
49896
  sha256: string(),
@@ -49800,19 +49938,6 @@ var trainingCapability = {
49800
49938
  mode: "singleton",
49801
49939
  mount: { kind: "hub-only" },
49802
49940
  methods: {
49803
- /** Store a version once. `stored: false` = that id already exists (immutable). */
49804
- putDatasetVersion: method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
49805
- kind: "mutation",
49806
- auth: "admin"
49807
- }),
49808
- getDatasetVersion: method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }),
49809
- /** Every version without its frame list, newest first. */
49810
- listDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }),
49811
- findDatasetVersionIdByName: method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }),
49812
- removeDatasetVersion: method(IdInput, object({ removed: boolean() }), {
49813
- kind: "mutation",
49814
- auth: "admin"
49815
- }),
49816
49941
  listBaseModels: method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }),
49817
49942
  /** Split, estimate, defaults and any named refusal — nothing is started. */
49818
49943
  planJob: method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
@@ -49841,6 +49966,32 @@ var trainingCapability = {
49841
49966
  auth: "admin",
49842
49967
  timeoutMs: 12e4
49843
49968
  }),
49969
+ /**
49970
+ * Enqueue one job per base model (same selection, entry, caps). The first
49971
+ * becomes `uploading`; the rest stay `queued` until the prior job settles.
49972
+ * One ACTIVE job at a time — a parallel `startJob` still gets
49973
+ * `job-already-running`. The same `idempotencyKey` returns the batch it
49974
+ * already started.
49975
+ */
49976
+ startJobBatch: method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
49977
+ baseModelIds: array(string().min(1)).min(1),
49978
+ name: string().min(1).max(120),
49979
+ maxCostUsd: number().positive(),
49980
+ maxRuntimeSec: number().int().positive(),
49981
+ idempotencyKey: string().min(8).max(80)
49982
+ }), discriminatedUnion("kind", [object({
49983
+ kind: literal("started"),
49984
+ batchId: string(),
49985
+ jobs: array(TrainingJobSchema).min(1).readonly()
49986
+ }), object({
49987
+ kind: literal("refused"),
49988
+ reason: TrainingRefusalReasonSchema,
49989
+ detail: string()
49990
+ })]), {
49991
+ kind: "mutation",
49992
+ auth: "admin",
49993
+ timeoutMs: 12e4
49994
+ }),
49844
49995
  listJobs: method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }),
49845
49996
  getJob: method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }),
49846
49997
  cancelJob: method(IdInput, TrainingJobSchema, {
@@ -54414,12 +54565,6 @@ Object.freeze({
54414
54565
  addonId: null,
54415
54566
  access: "create"
54416
54567
  },
54417
- "pipelineAnalytics.createRetrainDatasetVersion": {
54418
- capName: "pipeline-analytics",
54419
- capScope: "device",
54420
- addonId: null,
54421
- access: "create"
54422
- },
54423
54568
  "pipelineAnalytics.deleteDeviceEvents": {
54424
54569
  capName: "pipeline-analytics",
54425
54570
  capScope: "device",
@@ -54432,12 +54577,6 @@ Object.freeze({
54432
54577
  addonId: null,
54433
54578
  access: "delete"
54434
54579
  },
54435
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
54436
- capName: "pipeline-analytics",
54437
- capScope: "device",
54438
- addonId: null,
54439
- access: "delete"
54440
- },
54441
54580
  "pipelineAnalytics.deleteTracks": {
54442
54581
  capName: "pipeline-analytics",
54443
54582
  capScope: "device",
@@ -54540,6 +54679,12 @@ Object.freeze({
54540
54679
  addonId: null,
54541
54680
  access: "view"
54542
54681
  },
54682
+ "pipelineAnalytics.getRetrainCorpusKpi": {
54683
+ capName: "pipeline-analytics",
54684
+ capScope: "device",
54685
+ addonId: null,
54686
+ access: "view"
54687
+ },
54543
54688
  "pipelineAnalytics.getRetrainExportUrl": {
54544
54689
  capName: "pipeline-analytics",
54545
54690
  capScope: "device",
@@ -54660,7 +54805,7 @@ Object.freeze({
54660
54805
  addonId: null,
54661
54806
  access: "view"
54662
54807
  },
54663
- "pipelineAnalytics.listRetrainDatasetVersions": {
54808
+ "pipelineAnalytics.listRetrainCorpusPage": {
54664
54809
  capName: "pipeline-analytics",
54665
54810
  capScope: "device",
54666
54811
  addonId: null,
@@ -54714,12 +54859,6 @@ Object.freeze({
54714
54859
  addonId: null,
54715
54860
  access: "create"
54716
54861
  },
54717
- "pipelineAnalytics.previewRetrainDataset": {
54718
- capName: "pipeline-analytics",
54719
- capScope: "device",
54720
- addonId: null,
54721
- access: "view"
54722
- },
54723
54862
  "pipelineAnalytics.proposeRetrainAnnotations": {
54724
54863
  capName: "pipeline-analytics",
54725
54864
  capScope: "device",
@@ -54798,6 +54937,12 @@ Object.freeze({
54798
54937
  addonId: null,
54799
54938
  access: "create"
54800
54939
  },
54940
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
54941
+ capName: "pipeline-analytics",
54942
+ capScope: "device",
54943
+ addonId: null,
54944
+ access: "view"
54945
+ },
54801
54946
  "pipelineAnalytics.restageRetrainTrack": {
54802
54947
  capName: "pipeline-analytics",
54803
54948
  capScope: "device",
@@ -54858,12 +55003,6 @@ Object.freeze({
54858
55003
  addonId: null,
54859
55004
  access: "create"
54860
55005
  },
54861
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
54862
- capName: "pipeline-analytics",
54863
- capScope: "device",
54864
- addonId: null,
54865
- access: "view"
54866
- },
54867
55006
  "pipelineAnalytics.wipeAllAnalytics": {
54868
55007
  capName: "pipeline-analytics",
54869
55008
  capScope: "device",
@@ -57258,18 +57397,6 @@ Object.freeze({
57258
57397
  addonId: null,
57259
57398
  access: "create"
57260
57399
  },
57261
- "training.findDatasetVersionIdByName": {
57262
- capName: "training",
57263
- capScope: "system",
57264
- addonId: null,
57265
- access: "view"
57266
- },
57267
- "training.getDatasetVersion": {
57268
- capName: "training",
57269
- capScope: "system",
57270
- addonId: null,
57271
- access: "view"
57272
- },
57273
57400
  "training.getJob": {
57274
57401
  capName: "training",
57275
57402
  capScope: "system",
@@ -57288,12 +57415,6 @@ Object.freeze({
57288
57415
  addonId: null,
57289
57416
  access: "view"
57290
57417
  },
57291
- "training.listDatasetVersions": {
57292
- capName: "training",
57293
- capScope: "system",
57294
- addonId: null,
57295
- access: "view"
57296
- },
57297
57418
  "training.listJobs": {
57298
57419
  capName: "training",
57299
57420
  capScope: "system",
@@ -57306,54 +57427,66 @@ Object.freeze({
57306
57427
  addonId: null,
57307
57428
  access: "view"
57308
57429
  },
57309
- "training.putDatasetVersion": {
57430
+ "training.registerResult": {
57310
57431
  capName: "training",
57311
57432
  capScope: "system",
57312
57433
  addonId: null,
57313
57434
  access: "create"
57314
57435
  },
57315
- "training.registerResult": {
57436
+ "training.rollbackCanary": {
57316
57437
  capName: "training",
57317
57438
  capScope: "system",
57318
57439
  addonId: null,
57319
57440
  access: "create"
57320
57441
  },
57321
- "training.removeDatasetVersion": {
57442
+ "training.startJob": {
57322
57443
  capName: "training",
57323
57444
  capScope: "system",
57324
57445
  addonId: null,
57325
- access: "delete"
57446
+ access: "create"
57326
57447
  },
57327
- "training.rollbackCanary": {
57448
+ "training.startJobBatch": {
57328
57449
  capName: "training",
57329
57450
  capScope: "system",
57330
57451
  addonId: null,
57331
57452
  access: "create"
57332
57453
  },
57333
- "training.startJob": {
57334
- capName: "training",
57454
+ "trainingProvider.cancelJob": {
57455
+ capName: "training-provider",
57335
57456
  capScope: "system",
57336
57457
  addonId: null,
57337
57458
  access: "create"
57338
57459
  },
57339
- "trainingProvider.cancelJob": {
57460
+ "trainingProvider.cleanupJob": {
57340
57461
  capName: "training-provider",
57341
57462
  capScope: "system",
57342
57463
  addonId: null,
57343
57464
  access: "create"
57344
57465
  },
57345
- "trainingProvider.cleanupJob": {
57466
+ "trainingProvider.createEntry": {
57346
57467
  capName: "training-provider",
57347
57468
  capScope: "system",
57348
57469
  addonId: null,
57349
57470
  access: "create"
57350
57471
  },
57472
+ "trainingProvider.deleteEntry": {
57473
+ capName: "training-provider",
57474
+ capScope: "system",
57475
+ addonId: null,
57476
+ access: "delete"
57477
+ },
57351
57478
  "trainingProvider.describe": {
57352
57479
  capName: "training-provider",
57353
57480
  capScope: "system",
57354
57481
  addonId: null,
57355
57482
  access: "view"
57356
57483
  },
57484
+ "trainingProvider.describeTypes": {
57485
+ capName: "training-provider",
57486
+ capScope: "system",
57487
+ addonId: null,
57488
+ access: "view"
57489
+ },
57357
57490
  "trainingProvider.estimateJob": {
57358
57491
  capName: "training-provider",
57359
57492
  capScope: "system",
@@ -57366,6 +57499,12 @@ Object.freeze({
57366
57499
  addonId: null,
57367
57500
  access: "view"
57368
57501
  },
57502
+ "trainingProvider.listEntries": {
57503
+ capName: "training-provider",
57504
+ capScope: "system",
57505
+ addonId: null,
57506
+ access: "view"
57507
+ },
57369
57508
  "trainingProvider.listJobEvents": {
57370
57509
  capName: "training-provider",
57371
57510
  capScope: "system",
@@ -61002,6 +61141,11 @@ Object.freeze({
61002
61141
  form: "array",
61003
61142
  optional: false
61004
61143
  }],
61144
+ "pipelineAnalytics.listRetrainCorpusPage": [{
61145
+ name: "deviceIds",
61146
+ form: "array",
61147
+ optional: true
61148
+ }],
61005
61149
  "pipelineAnalytics.listRetrainStaging": [{
61006
61150
  name: "deviceIds",
61007
61151
  form: "array",