@camstack/addon-osd-manager 0.1.199 → 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-BtaL_riN.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-BItjkqZ8.mjs → hostInit-Pkln2STJ.mjs} +2 -2
  9. package/dist/index.js +290 -157
  10. package/dist/index.mjs +290 -157
  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-SHsfFbjJ.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)
@@ -32315,6 +32363,8 @@ var AgentPipelineSettingsSchema = object({
32315
32363
  * address is wrong (multi-homed host, NAT, custom interface).
32316
32364
  */
32317
32365
  reachableHost: string().optional(),
32366
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
32367
+ color: NodeColorIdSchema.optional(),
32318
32368
  /**
32319
32369
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
32320
32370
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -33041,8 +33091,9 @@ var pipelineOrchestratorCapability = {
33041
33091
  */
33042
33092
  setAgentReachableHost: method(object({
33043
33093
  agentNodeId: string(),
33044
- reachableHost: string().nullable()
33045
- }), 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) }), {
33046
33097
  kind: "mutation",
33047
33098
  auth: "admin"
33048
33099
  }),
@@ -49371,9 +49422,11 @@ var zoneRulesCapability = {
49371
49422
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
49372
49423
  * manifest entry and nothing else.
49373
49424
  *
49374
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
49375
- * `notification-output` posture); `describe` concat-fans across providers.
49376
- * 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.
49377
49430
  *
49378
49431
  * Every cloud object a provider creates is tagged with the orchestrator's
49379
49432
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -49397,8 +49450,8 @@ var TrainingRegionOptionSchema = object({
49397
49450
  priceMultiplier: number().positive()
49398
49451
  });
49399
49452
  /**
49400
- * The provider's per-account settings, as the orchestrator reads them. They
49401
- * 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
49402
49455
  * depend on the user's account), never hard-coded in the orchestrator.
49403
49456
  */
49404
49457
  var TrainingProviderDefaultsSchema = object({
@@ -49409,9 +49462,32 @@ var TrainingProviderDefaultsSchema = object({
49409
49462
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
49410
49463
  failedDatasetGraceHours: number().nonnegative()
49411
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
+ });
49412
49483
  var TrainingProviderDescriptorSchema = object({
49413
49484
  addonId: string(),
49414
- /** `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. */
49415
49491
  kind: string(),
49416
49492
  label: string(),
49417
49493
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -49475,8 +49551,9 @@ var TrainerSourceRefSchema = object({
49475
49551
  /** A commit sha (never a branch) — the job must be reproducible. */
49476
49552
  revision: string().regex(/^[0-9a-f]{7,64}$/)
49477
49553
  });
49554
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
49478
49555
  var JobRef = {
49479
- addonId: string(),
49556
+ entryId: string().min(1),
49480
49557
  jobKey: string().uuid()
49481
49558
  };
49482
49559
  var TrainingLogLineSchema = object({
@@ -49489,17 +49566,37 @@ var trainingProviderCapability = {
49489
49566
  mode: "collection",
49490
49567
  internal: true,
49491
49568
  methods: {
49492
- /** Every provider's offer and settings. Concat-fans across providers. */
49569
+ /** Every entry's offer and settings. Concat-fans across providers. */
49493
49570
  describe: method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }),
49494
- /** Call the provider with the stored credentials. Never returns them. */
49495
- 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, {
49496
49593
  kind: "mutation",
49497
49594
  auth: "admin",
49498
49595
  timeoutMs: 3e4
49499
49596
  }),
49500
49597
  /** USD range for a run of `gpuSeconds` on `gpuType` in `region`. */
49501
49598
  estimateJob: method(object({
49502
- addonId: string(),
49599
+ entryId: string().min(1),
49503
49600
  gpuType: string(),
49504
49601
  region: string(),
49505
49602
  datasetBytes: number().int().nonnegative(),
@@ -49595,8 +49692,11 @@ var trainingProviderCapability = {
49595
49692
  auth: "admin",
49596
49693
  timeoutMs: 5 * 6e4
49597
49694
  }),
49598
- /** Every job the provider can still see — the orphan sweep diffs it against our records. */
49599
- 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(), {
49600
49700
  auth: "admin",
49601
49701
  timeoutMs: 2 * 6e4
49602
49702
  })
@@ -49608,20 +49708,31 @@ var trainingProviderCapability = {
49608
49708
  *
49609
49709
  * It owns what every provider must agree on, written once:
49610
49710
  *
49611
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
49612
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
49613
- * the export plan) and reaches this store through the five row methods
49614
- * below, so the Retrain page and the export did not change.
49615
49711
  * - **Jobs.** A persisted state machine, a reconcile loop against the
49616
49712
  * provider, a cost guard, a daily orphan sweep and the retention rules.
49617
49713
  * - **The return flow.** Verified artefacts → Model Studio
49618
49714
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
49619
49715
  * rollback. Nothing is ever registered automatically.
49620
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
+ *
49621
49721
  * Every method is `admin`.
49622
49722
  */
49623
- /** A version WITH its frame list — what the export and a job read. */
49624
- 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
+ });
49625
49736
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
49626
49737
  var TrainingBaseModelSchema = object({
49627
49738
  modelId: string(),
@@ -49639,9 +49750,13 @@ var TrainingPresetSchema = _enum([
49639
49750
  "thorough"
49640
49751
  ]);
49641
49752
  var TrainingJobRequestSchema = object({
49642
- datasetVersionId: string().min(1),
49643
- /** The `training-provider` addon that runs it. */
49644
- 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),
49645
49760
  gpuType: string().min(1),
49646
49761
  region: string(),
49647
49762
  baseModelId: string().min(1),
@@ -49700,6 +49815,7 @@ var TrainingJobPlanSchema = object({
49700
49815
  * result lives after the operator acted on it.
49701
49816
  */
49702
49817
  var TrainingJobStateSchema = _enum([
49818
+ "queued",
49703
49819
  "uploading",
49704
49820
  "submitted",
49705
49821
  "starting",
@@ -49753,6 +49869,11 @@ var TrainingJobSchema = object({
49753
49869
  createdAt: number(),
49754
49870
  updatedAt: number(),
49755
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),
49756
49877
  stage: TrainingStageSchema.nullable(),
49757
49878
  failure: object({
49758
49879
  reason: TrainingFailureReasonSchema,
@@ -49764,6 +49885,12 @@ var TrainingJobSchema = object({
49764
49885
  maxRuntimeSec: number().int().positive(),
49765
49886
  trainer: TrainerSourceRefSchema,
49766
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(),
49767
49894
  dataset: object({
49768
49895
  bytes: number().int(),
49769
49896
  sha256: string(),
@@ -49811,19 +49938,6 @@ var trainingCapability = {
49811
49938
  mode: "singleton",
49812
49939
  mount: { kind: "hub-only" },
49813
49940
  methods: {
49814
- /** Store a version once. `stored: false` = that id already exists (immutable). */
49815
- putDatasetVersion: method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
49816
- kind: "mutation",
49817
- auth: "admin"
49818
- }),
49819
- getDatasetVersion: method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }),
49820
- /** Every version without its frame list, newest first. */
49821
- listDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }),
49822
- findDatasetVersionIdByName: method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }),
49823
- removeDatasetVersion: method(IdInput, object({ removed: boolean() }), {
49824
- kind: "mutation",
49825
- auth: "admin"
49826
- }),
49827
49941
  listBaseModels: method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }),
49828
49942
  /** Split, estimate, defaults and any named refusal — nothing is started. */
49829
49943
  planJob: method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
@@ -49852,6 +49966,32 @@ var trainingCapability = {
49852
49966
  auth: "admin",
49853
49967
  timeoutMs: 12e4
49854
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
+ }),
49855
49995
  listJobs: method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }),
49856
49996
  getJob: method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }),
49857
49997
  cancelJob: method(IdInput, TrainingJobSchema, {
@@ -54425,12 +54565,6 @@ Object.freeze({
54425
54565
  addonId: null,
54426
54566
  access: "create"
54427
54567
  },
54428
- "pipelineAnalytics.createRetrainDatasetVersion": {
54429
- capName: "pipeline-analytics",
54430
- capScope: "device",
54431
- addonId: null,
54432
- access: "create"
54433
- },
54434
54568
  "pipelineAnalytics.deleteDeviceEvents": {
54435
54569
  capName: "pipeline-analytics",
54436
54570
  capScope: "device",
@@ -54443,12 +54577,6 @@ Object.freeze({
54443
54577
  addonId: null,
54444
54578
  access: "delete"
54445
54579
  },
54446
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
54447
- capName: "pipeline-analytics",
54448
- capScope: "device",
54449
- addonId: null,
54450
- access: "delete"
54451
- },
54452
54580
  "pipelineAnalytics.deleteTracks": {
54453
54581
  capName: "pipeline-analytics",
54454
54582
  capScope: "device",
@@ -54551,6 +54679,12 @@ Object.freeze({
54551
54679
  addonId: null,
54552
54680
  access: "view"
54553
54681
  },
54682
+ "pipelineAnalytics.getRetrainCorpusKpi": {
54683
+ capName: "pipeline-analytics",
54684
+ capScope: "device",
54685
+ addonId: null,
54686
+ access: "view"
54687
+ },
54554
54688
  "pipelineAnalytics.getRetrainExportUrl": {
54555
54689
  capName: "pipeline-analytics",
54556
54690
  capScope: "device",
@@ -54671,7 +54805,7 @@ Object.freeze({
54671
54805
  addonId: null,
54672
54806
  access: "view"
54673
54807
  },
54674
- "pipelineAnalytics.listRetrainDatasetVersions": {
54808
+ "pipelineAnalytics.listRetrainCorpusPage": {
54675
54809
  capName: "pipeline-analytics",
54676
54810
  capScope: "device",
54677
54811
  addonId: null,
@@ -54725,12 +54859,6 @@ Object.freeze({
54725
54859
  addonId: null,
54726
54860
  access: "create"
54727
54861
  },
54728
- "pipelineAnalytics.previewRetrainDataset": {
54729
- capName: "pipeline-analytics",
54730
- capScope: "device",
54731
- addonId: null,
54732
- access: "view"
54733
- },
54734
54862
  "pipelineAnalytics.proposeRetrainAnnotations": {
54735
54863
  capName: "pipeline-analytics",
54736
54864
  capScope: "device",
@@ -54809,6 +54937,12 @@ Object.freeze({
54809
54937
  addonId: null,
54810
54938
  access: "create"
54811
54939
  },
54940
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
54941
+ capName: "pipeline-analytics",
54942
+ capScope: "device",
54943
+ addonId: null,
54944
+ access: "view"
54945
+ },
54812
54946
  "pipelineAnalytics.restageRetrainTrack": {
54813
54947
  capName: "pipeline-analytics",
54814
54948
  capScope: "device",
@@ -54869,12 +55003,6 @@ Object.freeze({
54869
55003
  addonId: null,
54870
55004
  access: "create"
54871
55005
  },
54872
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
54873
- capName: "pipeline-analytics",
54874
- capScope: "device",
54875
- addonId: null,
54876
- access: "view"
54877
- },
54878
55006
  "pipelineAnalytics.wipeAllAnalytics": {
54879
55007
  capName: "pipeline-analytics",
54880
55008
  capScope: "device",
@@ -57269,18 +57397,6 @@ Object.freeze({
57269
57397
  addonId: null,
57270
57398
  access: "create"
57271
57399
  },
57272
- "training.findDatasetVersionIdByName": {
57273
- capName: "training",
57274
- capScope: "system",
57275
- addonId: null,
57276
- access: "view"
57277
- },
57278
- "training.getDatasetVersion": {
57279
- capName: "training",
57280
- capScope: "system",
57281
- addonId: null,
57282
- access: "view"
57283
- },
57284
57400
  "training.getJob": {
57285
57401
  capName: "training",
57286
57402
  capScope: "system",
@@ -57299,12 +57415,6 @@ Object.freeze({
57299
57415
  addonId: null,
57300
57416
  access: "view"
57301
57417
  },
57302
- "training.listDatasetVersions": {
57303
- capName: "training",
57304
- capScope: "system",
57305
- addonId: null,
57306
- access: "view"
57307
- },
57308
57418
  "training.listJobs": {
57309
57419
  capName: "training",
57310
57420
  capScope: "system",
@@ -57317,54 +57427,66 @@ Object.freeze({
57317
57427
  addonId: null,
57318
57428
  access: "view"
57319
57429
  },
57320
- "training.putDatasetVersion": {
57430
+ "training.registerResult": {
57321
57431
  capName: "training",
57322
57432
  capScope: "system",
57323
57433
  addonId: null,
57324
57434
  access: "create"
57325
57435
  },
57326
- "training.registerResult": {
57436
+ "training.rollbackCanary": {
57327
57437
  capName: "training",
57328
57438
  capScope: "system",
57329
57439
  addonId: null,
57330
57440
  access: "create"
57331
57441
  },
57332
- "training.removeDatasetVersion": {
57442
+ "training.startJob": {
57333
57443
  capName: "training",
57334
57444
  capScope: "system",
57335
57445
  addonId: null,
57336
- access: "delete"
57446
+ access: "create"
57337
57447
  },
57338
- "training.rollbackCanary": {
57448
+ "training.startJobBatch": {
57339
57449
  capName: "training",
57340
57450
  capScope: "system",
57341
57451
  addonId: null,
57342
57452
  access: "create"
57343
57453
  },
57344
- "training.startJob": {
57345
- capName: "training",
57454
+ "trainingProvider.cancelJob": {
57455
+ capName: "training-provider",
57346
57456
  capScope: "system",
57347
57457
  addonId: null,
57348
57458
  access: "create"
57349
57459
  },
57350
- "trainingProvider.cancelJob": {
57460
+ "trainingProvider.cleanupJob": {
57351
57461
  capName: "training-provider",
57352
57462
  capScope: "system",
57353
57463
  addonId: null,
57354
57464
  access: "create"
57355
57465
  },
57356
- "trainingProvider.cleanupJob": {
57466
+ "trainingProvider.createEntry": {
57357
57467
  capName: "training-provider",
57358
57468
  capScope: "system",
57359
57469
  addonId: null,
57360
57470
  access: "create"
57361
57471
  },
57472
+ "trainingProvider.deleteEntry": {
57473
+ capName: "training-provider",
57474
+ capScope: "system",
57475
+ addonId: null,
57476
+ access: "delete"
57477
+ },
57362
57478
  "trainingProvider.describe": {
57363
57479
  capName: "training-provider",
57364
57480
  capScope: "system",
57365
57481
  addonId: null,
57366
57482
  access: "view"
57367
57483
  },
57484
+ "trainingProvider.describeTypes": {
57485
+ capName: "training-provider",
57486
+ capScope: "system",
57487
+ addonId: null,
57488
+ access: "view"
57489
+ },
57368
57490
  "trainingProvider.estimateJob": {
57369
57491
  capName: "training-provider",
57370
57492
  capScope: "system",
@@ -57377,6 +57499,12 @@ Object.freeze({
57377
57499
  addonId: null,
57378
57500
  access: "view"
57379
57501
  },
57502
+ "trainingProvider.listEntries": {
57503
+ capName: "training-provider",
57504
+ capScope: "system",
57505
+ addonId: null,
57506
+ access: "view"
57507
+ },
57380
57508
  "trainingProvider.listJobEvents": {
57381
57509
  capName: "training-provider",
57382
57510
  capScope: "system",
@@ -61013,6 +61141,11 @@ Object.freeze({
61013
61141
  form: "array",
61014
61142
  optional: false
61015
61143
  }],
61144
+ "pipelineAnalytics.listRetrainCorpusPage": [{
61145
+ name: "deviceIds",
61146
+ form: "array",
61147
+ optional: true
61148
+ }],
61016
61149
  "pipelineAnalytics.listRetrainStaging": [{
61017
61150
  name: "deviceIds",
61018
61151
  form: "array",