@camstack/addon-training 0.1.6 → 0.1.7

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 (43) hide show
  1. package/dist/MaskShapeCanvas-Kfg9dl6B.mjs +686 -0
  2. package/dist/{MotionZonesSettings-DPtcv80q.mjs → MotionZonesSettings-DKtYdHUO.mjs} +101 -119
  3. package/dist/{PrivacyMaskSettings-Wsn5QL0_.mjs → PrivacyMaskSettings-BvLUVz86.mjs} +45 -70
  4. package/dist/ReactKonva-DGuYUN0L.mjs +5416 -0
  5. package/dist/{SceneMonitorEditor-BlMwyiH8.mjs → SceneMonitorEditor-rFYGkGHV.mjs} +82 -82
  6. package/dist/_stub.js +28146 -12781
  7. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-Cbrdn9ib.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-B3xXUcaU.mjs} +3 -3
  8. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C7dks3FG.mjs +26 -0
  9. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DpjirGmB.mjs +89 -0
  10. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-CFCVuRAs.mjs +58 -0
  11. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-BkvDudqY.mjs +62 -0
  12. package/dist/{_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs → _virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs} +1 -1
  13. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs +34 -0
  14. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-DAZkHxxU.mjs +45 -0
  15. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-CHqN9NLt.mjs +34 -0
  16. package/dist/addon-training.css +1 -1
  17. package/dist/{dist-BhCRZEE4.js → dist-DVDBSrjw.js} +270 -146
  18. package/dist/{dist-Cqa2fHNk.mjs → dist-Phot2UwD.mjs} +271 -141
  19. package/dist/grid-2x2-Bl3xw1w7.mjs +21 -0
  20. package/dist/{hostInit-BI98RYIm.mjs → hostInit-BAGO4XYA.mjs} +2 -2
  21. package/dist/index.js +100 -39
  22. package/dist/index.mjs +99 -38
  23. package/dist/lib-CVGFTwe0.mjs +7770 -0
  24. package/dist/orchestrator/training.addon.js +376 -222
  25. package/dist/orchestrator/training.addon.mjs +376 -222
  26. package/dist/{player-overlays-BX3obOMu.mjs → player-overlays-BT-6fK9N.mjs} +26 -7
  27. package/dist/providers/modal/training-modal.addon.js +361 -155
  28. package/dist/providers/modal/training-modal.addon.mjs +364 -158
  29. package/dist/remoteEntry.js +1 -1
  30. package/dist/{responsive-CdDIJCpI.mjs → responsive-Dy5RAD1s.mjs} +42 -38
  31. package/dist/{scene-monitor-copy-5u5w3K-Y.mjs → scene-monitor-copy-7HImRbA5.mjs} +4 -4
  32. package/dist/{square-C-P1-89Q.mjs → square-DoPBhbZN.mjs} +29 -4
  33. package/dist/{trash-2-BikGYiWf.mjs → trash-2-BwunNgLf.mjs} +1 -1
  34. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-DGLUs0o6.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-gU49KvnZ.mjs} +399 -390
  35. package/package.json +1 -1
  36. package/dist/MaskShapeCanvas-BokARvOj.mjs +0 -13806
  37. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BkKuzhOJ.mjs +0 -26
  38. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CaB1jnkt.mjs +0 -25
  39. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-B3rryujf.mjs +0 -25
  40. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-nL4MGFRP.mjs +0 -26
  41. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.mjs +0 -26
  42. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-i_pnGDxd.mjs +0 -25
  43. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-gTIQrhKs.mjs +0 -25
@@ -5410,7 +5410,7 @@ var ZodIssueCode = {
5410
5410
  var ZodFirstPartyTypeKind;
5411
5411
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5412
5412
  //#endregion
5413
- //#region ../types/dist/sleep-r3RWkGVx.mjs
5413
+ //#region ../types/dist/sleep-CI0n5D44.mjs
5414
5414
  /**
5415
5415
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5416
5416
  * window to float samples (D455).
@@ -9339,6 +9339,16 @@ var CompositionSchema = object({
9339
9339
  seen.add(feature.cap);
9340
9340
  });
9341
9341
  });
9342
+ var NodeColorIdSchema = _enum([
9343
+ "node-a",
9344
+ "node-b",
9345
+ "node-c",
9346
+ "node-d",
9347
+ "node-e",
9348
+ "node-f",
9349
+ "node-g",
9350
+ "node-h"
9351
+ ]);
9342
9352
  new Set([
9343
9353
  "track",
9344
9354
  "face",
@@ -23933,24 +23943,69 @@ var RetrainFrameListSchema = object({
23933
23943
  /** What the page pre-selects — the native key frame when one survives. */
23934
23944
  autoPickMediaId: number().int().optional()
23935
23945
  });
23946
+ /** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
23947
+ var RetrainFrameWorkStateSchema = _enum([
23948
+ "unannotated",
23949
+ "annotated",
23950
+ "complete"
23951
+ ]);
23952
+ /**
23953
+ * Filters for paginated corpus list, KPI, and matching export (design §4.4).
23954
+ * Every narrowing field is ANDed; omitted fields impose no constraint.
23955
+ */
23956
+ var RetrainCorpusFilterSchema = object({
23957
+ workState: RetrainFrameWorkStateSchema.optional(),
23958
+ deviceIds: array(number()).max(500).optional(),
23959
+ /** When set, only frames in this named collection. */
23960
+ collectionId: string().optional(),
23961
+ /** Frames that carry at least one saved annotation in one of these classes. */
23962
+ classes: array(RetrainMacroClassSchema).optional(),
23963
+ page: number().int().positive().default(1),
23964
+ pageSize: number().int().positive().max(100).default(50)
23965
+ });
23966
+ var RetrainCorpusPageSchema = object({
23967
+ frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
23968
+ total: number().int().nonnegative(),
23969
+ page: number().int().positive(),
23970
+ pageSize: number().int().positive()
23971
+ });
23972
+ var RetrainCorpusKpiCameraRowSchema = object({
23973
+ deviceId: number(),
23974
+ unannotated: number().int().nonnegative(),
23975
+ annotated: number().int().nonnegative(),
23976
+ complete: number().int().nonnegative(),
23977
+ /** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
23978
+ * `null` when the corpus is empty (no ratio). */
23979
+ pctOfCorpus: number().min(0).max(1).nullable()
23980
+ });
23981
+ var RetrainCorpusKpiSchema = object({
23982
+ total: number().int().nonnegative(),
23983
+ unannotated: number().int().nonnegative(),
23984
+ annotated: number().int().nonnegative(),
23985
+ complete: number().int().nonnegative(),
23986
+ cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
23987
+ });
23936
23988
  /**
23937
23989
  * Which frames an annotated export carries. Every field narrows; an empty
23938
- * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
23939
- * list owned by whoever trains (the training orchestrator), so `frameIds` is
23940
- * the primitive a version export uses; `batchId` re-selects what an earlier
23941
- * export carried (`exportedInBatch`).
23990
+ * filter is every annotated copy. `frameIds` is the primitive a job or
23991
+ * download uses; `batchId` re-selects what an earlier export carried
23992
+ * (`exportedInBatch`). Frozen dataset versions were removed — live selection
23993
+ * resolves to `frameIds` at plan/start.
23942
23994
  */
23943
23995
  var RetrainExportFilterSchema = object({
23944
23996
  deviceIds: array(number()).optional(),
23945
23997
  frameIds: array(string()).max(2e4).optional(),
23946
23998
  /** Only frames in at least one of these named collections. */
23947
23999
  collectionIds: array(string()).max(200).optional(),
23948
- /** Exactly the frames of this dataset version (and its completeOnly). An
23949
- * unknown id selects nothing. */
23950
- datasetVersionId: string().optional(),
24000
+ /** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
24001
+ collectionId: string().optional(),
23951
24002
  batchId: string().optional(),
23952
24003
  /** Only frames the operator marked complete (all subjects boxed). */
23953
- completeOnly: boolean().optional()
24004
+ completeOnly: boolean().optional(),
24005
+ /** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
24006
+ workState: RetrainFrameWorkStateSchema.optional(),
24007
+ /** Frames with at least one saved annotation in one of these classes. */
24008
+ classes: array(RetrainMacroClassSchema).optional()
23954
24009
  });
23955
24010
  /**
23956
24011
  * `frames`: the full frame copies, boxes in `annotations.json`.
@@ -24150,8 +24205,7 @@ var RetrainDatasetStatsSchema = object({
24150
24205
  completeFrames: number().int()
24151
24206
  })).readonly()
24152
24207
  });
24153
- /** An immutable dataset version, without its frame list. */
24154
- var RetrainDatasetVersionSchema = object({
24208
+ object({
24155
24209
  id: string(),
24156
24210
  name: string(),
24157
24211
  createdAt: number(),
@@ -24159,22 +24213,33 @@ var RetrainDatasetVersionSchema = object({
24159
24213
  layout: RetrainExportLayoutSchema,
24160
24214
  completeOnly: boolean(),
24161
24215
  frameCount: number().int(),
24162
- /** sha256 of what the frames taught when the version was frozen. */
24163
24216
  annotationHash: string(),
24164
- /** The export manifest schema the version was cut under. */
24165
24217
  manifestSchema: string(),
24166
24218
  stats: RetrainDatasetStatsSchema
24167
24219
  });
24168
- var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
24169
- kind: literal("created"),
24170
- version: RetrainDatasetVersionSchema
24220
+ /**
24221
+ * Live training corpus criteria — same shape as `TrainingCorpusSelection` on
24222
+ * the training cap. Resolved here so plan/start and the annotated export share
24223
+ * one definition of "the frames" (`buildRetrainExportPlan`).
24224
+ */
24225
+ var RetrainTrainingCorpusSelectionSchema = object({
24226
+ collectionIds: array(string()).min(1),
24227
+ workState: _enum([
24228
+ "complete",
24229
+ "annotated_or_complete",
24230
+ "any_annotated"
24231
+ ]).default("complete")
24232
+ });
24233
+ var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
24234
+ kind: literal("resolved"),
24235
+ frameIds: array(string()).max(2e4).readonly(),
24236
+ stats: RetrainDatasetStatsSchema,
24237
+ annotationHash: string(),
24238
+ layout: RetrainExportLayoutSchema
24171
24239
  }), object({
24172
24240
  kind: literal("refused"),
24173
- reason: _enum([
24174
- "empty-name",
24175
- "duplicate-name",
24176
- "no-frames"
24177
- ])
24241
+ reason: _enum(["unknown-collection", "no-frames"]),
24242
+ detail: string()
24178
24243
  })]);
24179
24244
  /** The outcome of a lifecycle move owned by the retrain page. */
24180
24245
  var RetrainTransitionResultSchema = object({
@@ -24881,6 +24946,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24881
24946
  }), array(RetrainTrackSchema).readonly(), {
24882
24947
  kind: "query",
24883
24948
  auth: "admin"
24949
+ }), method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
24950
+ kind: "query",
24951
+ auth: "admin"
24952
+ }), method(object({}), RetrainCorpusKpiSchema, {
24953
+ kind: "query",
24954
+ auth: "admin"
24884
24955
  }), method(object({ trackId: string() }), RetrainFrameListSchema, {
24885
24956
  kind: "query",
24886
24957
  auth: "admin"
@@ -24976,36 +25047,6 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24976
25047
  kind: "mutation",
24977
25048
  auth: "admin",
24978
25049
  timeoutMs: 12e4
24979
- }), method(object({
24980
- selection: RetrainDatasetSelectionSchema,
24981
- completeOnly: boolean().optional()
24982
- }), RetrainDatasetStatsSchema, {
24983
- kind: "query",
24984
- auth: "admin"
24985
- }), method(object({
24986
- name: string().max(120),
24987
- selection: RetrainDatasetSelectionSchema,
24988
- layout: RetrainExportLayoutSchema,
24989
- completeOnly: boolean()
24990
- }), CreateRetrainDatasetVersionResultSchema, {
24991
- kind: "mutation",
24992
- auth: "admin",
24993
- timeoutMs: 12e4
24994
- }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
24995
- kind: "query",
24996
- auth: "admin"
24997
- }), method(object({ id: string() }), object({ deleted: boolean() }), {
24998
- kind: "mutation",
24999
- auth: "admin"
25000
- }), method(object({ id: string() }), object({
25001
- found: boolean(),
25002
- annotationHash: string(),
25003
- matches: boolean(),
25004
- missingFrames: number().int()
25005
- }), {
25006
- kind: "query",
25007
- auth: "admin",
25008
- timeoutMs: 12e4
25009
25050
  }), method(object({}), array(RetrainAssistProfileSchema).readonly(), {
25010
25051
  kind: "query",
25011
25052
  auth: "admin"
@@ -25032,6 +25073,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25032
25073
  }), method(object({}), array(RetrainCollectionSchema).readonly(), {
25033
25074
  kind: "query",
25034
25075
  auth: "admin"
25076
+ }), method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
25077
+ kind: "query",
25078
+ auth: "admin",
25079
+ timeoutMs: 6e4
25035
25080
  }), method(object({
25036
25081
  id: string(),
25037
25082
  name: string().max(120)
@@ -27545,6 +27590,8 @@ var AgentPipelineSettingsSchema = object({
27545
27590
  * address is wrong (multi-homed host, NAT, custom interface).
27546
27591
  */
27547
27592
  reachableHost: string().optional(),
27593
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
27594
+ color: NodeColorIdSchema.optional(),
27548
27595
  /**
27549
27596
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
27550
27597
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -28094,8 +28141,9 @@ method(object({
28094
28141
  auth: "admin"
28095
28142
  }), method(object({
28096
28143
  agentNodeId: string(),
28097
- reachableHost: string().nullable()
28098
- }), object({ success: literal(true) }), {
28144
+ reachableHost: string().nullable().optional(),
28145
+ color: NodeColorIdSchema.nullable().optional()
28146
+ }).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
28099
28147
  kind: "mutation",
28100
28148
  auth: "admin"
28101
28149
  }), method(object({
@@ -39311,9 +39359,11 @@ DeviceType.Camera, method(object({
39311
39359
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
39312
39360
  * manifest entry and nothing else.
39313
39361
  *
39314
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
39315
- * `notification-output` posture); `describe` concat-fans across providers.
39316
- * Every method is `admin`: these spend money.
39362
+ * Collection of provider **types** (addons). Each addon owns zero or more
39363
+ * **entries** (credentials + defaults). Concat-fans: `describe`,
39364
+ * `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
39365
+ * `entryId`; callers also pass the owning `addonId` as the collection
39366
+ * selector (broker posture). Every method is `admin`: these spend money.
39317
39367
  *
39318
39368
  * Every cloud object a provider creates is tagged with the orchestrator's
39319
39369
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -39337,8 +39387,8 @@ var TrainingRegionOptionSchema = object({
39337
39387
  priceMultiplier: number().positive()
39338
39388
  });
39339
39389
  /**
39340
- * The provider's per-account settings, as the orchestrator reads them. They
39341
- * live in the PROVIDER addon's settings (operator decision 2026-10-08: they
39390
+ * The provider's per-entry settings, as the orchestrator reads them. They
39391
+ * live on the PROVIDER addon's entry (operator decision 2026-10-08: they
39342
39392
  * depend on the user's account), never hard-coded in the orchestrator.
39343
39393
  */
39344
39394
  var TrainingProviderDefaultsSchema = object({
@@ -39349,9 +39399,32 @@ var TrainingProviderDefaultsSchema = object({
39349
39399
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
39350
39400
  failedDatasetGraceHours: number().nonnegative()
39351
39401
  });
39402
+ /** One creatable provider type, for the Add-entry dialog. */
39403
+ var TrainingProviderTypeSchema = object({
39404
+ typeId: string(),
39405
+ label: string(),
39406
+ /** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
39407
+ iconAsset: string(),
39408
+ /** Owning `training-provider` addon — collection selector for createEntry. */
39409
+ addonId: string()
39410
+ });
39411
+ /** One configured account / workspace under a provider type. */
39412
+ var TrainingProviderEntrySchema = object({
39413
+ entryId: string(),
39414
+ typeId: string(),
39415
+ name: string(),
39416
+ addonId: string(),
39417
+ /** Credentials are present — never the values. */
39418
+ configured: boolean()
39419
+ });
39352
39420
  var TrainingProviderDescriptorSchema = object({
39353
39421
  addonId: string(),
39354
- /** `modal`, `runpod`, `fake`, … */
39422
+ entryId: string(),
39423
+ typeId: string(),
39424
+ /** Operator-chosen entry name. */
39425
+ name: string(),
39426
+ iconAsset: string(),
39427
+ /** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
39355
39428
  kind: string(),
39356
39429
  label: string(),
39357
39430
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -39415,8 +39488,9 @@ var TrainerSourceRefSchema = object({
39415
39488
  /** A commit sha (never a branch) — the job must be reproducible. */
39416
39489
  revision: string().regex(/^[0-9a-f]{7,64}$/)
39417
39490
  });
39491
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
39418
39492
  var JobRef = {
39419
- addonId: string(),
39493
+ entryId: string().min(1),
39420
39494
  jobKey: string().uuid()
39421
39495
  };
39422
39496
  var TrainingLogLineSchema = object({
@@ -39429,17 +39503,37 @@ var trainingProviderCapability = {
39429
39503
  mode: "collection",
39430
39504
  internal: true,
39431
39505
  methods: {
39432
- /** Every provider's offer and settings. Concat-fans across providers. */
39506
+ /** Every entry's offer and settings. Concat-fans across providers. */
39433
39507
  describe: method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }),
39434
- /** Call the provider with the stored credentials. Never returns them. */
39435
- validateCredentials: method(object({ addonId: string() }), TrainingCredentialCheckSchema, {
39508
+ /** Creatable types for the Add-entry dialog. Concat-fans. */
39509
+ describeTypes: method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }),
39510
+ /** Configured entries (pills). Concat-fans. */
39511
+ listEntries: method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }),
39512
+ /**
39513
+ * Create an entry under this provider type. Pin with `{ addonId }` of the
39514
+ * type's owning addon (from describeTypes).
39515
+ */
39516
+ createEntry: method(object({
39517
+ typeId: string().min(1),
39518
+ name: string().min(1)
39519
+ }), object({ entryId: string() }), {
39520
+ kind: "mutation",
39521
+ auth: "admin"
39522
+ }),
39523
+ /** Delete an entry. Pin with the owning `{ addonId }`. */
39524
+ deleteEntry: method(object({ entryId: string().min(1) }), object({ ok: literal(true) }), {
39525
+ kind: "mutation",
39526
+ auth: "admin"
39527
+ }),
39528
+ /** Call the provider with the entry's stored credentials. Never returns them. */
39529
+ validateCredentials: method(object({ entryId: string().min(1) }), TrainingCredentialCheckSchema, {
39436
39530
  kind: "mutation",
39437
39531
  auth: "admin",
39438
39532
  timeoutMs: 3e4
39439
39533
  }),
39440
39534
  /** USD range for a run of `gpuSeconds` on `gpuType` in `region`. */
39441
39535
  estimateJob: method(object({
39442
- addonId: string(),
39536
+ entryId: string().min(1),
39443
39537
  gpuType: string(),
39444
39538
  region: string(),
39445
39539
  datasetBytes: number().int().nonnegative(),
@@ -39535,8 +39629,11 @@ var trainingProviderCapability = {
39535
39629
  auth: "admin",
39536
39630
  timeoutMs: 5 * 6e4
39537
39631
  }),
39538
- /** Every job the provider can still see — the orphan sweep diffs it against our records. */
39539
- listJobs: method(object({ addonId: string() }), array(ProviderJobStatusSchema).readonly(), {
39632
+ /**
39633
+ * Jobs this provider can still see. Optional `entryId` filters; omit to
39634
+ * list every entry (orphan sweep). Pin with `{ addonId }`.
39635
+ */
39636
+ listJobs: method(object({ entryId: string().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
39540
39637
  auth: "admin",
39541
39638
  timeoutMs: 2 * 6e4
39542
39639
  })
@@ -39548,20 +39645,31 @@ var trainingProviderCapability = {
39548
39645
  *
39549
39646
  * It owns what every provider must agree on, written once:
39550
39647
  *
39551
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
39552
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
39553
- * the export plan) and reaches this store through the five row methods
39554
- * below, so the Retrain page and the export did not change.
39555
39648
  * - **Jobs.** A persisted state machine, a reconcile loop against the
39556
39649
  * provider, a cost guard, a daily orphan sweep and the retention rules.
39557
39650
  * - **The return flow.** Verified artefacts → Model Studio
39558
39651
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
39559
39652
  * rollback. Nothing is ever registered automatically.
39560
39653
  *
39654
+ * Plan/start takes a live {@link TrainingCorpusSelection} (collections +
39655
+ * work-state rule); frame ids are resolved via pipeline-analytics at that
39656
+ * moment and snapshotted on the job. No frozen dataset version.
39657
+ *
39561
39658
  * Every method is `admin`.
39562
39659
  */
39563
- /** A version WITH its frame list — what the export and a job read. */
39564
- var TrainingDatasetVersionRowSchema = RetrainDatasetVersionSchema.omit({ frameCount: true }).extend({ frameIds: array(string()).max(2e4).readonly() });
39660
+ /**
39661
+ * Live corpus criteria for plan/start (design §5.2). Default is complete-only.
39662
+ * Frame ids are resolved at plan/start — never a frozen version id.
39663
+ */
39664
+ var TrainingCorpusSelectionSchema = object({
39665
+ collectionIds: array(string()).min(1),
39666
+ /** Default complete-only for v1 */
39667
+ workState: _enum([
39668
+ "complete",
39669
+ "annotated_or_complete",
39670
+ "any_annotated"
39671
+ ]).default("complete")
39672
+ });
39565
39673
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
39566
39674
  var TrainingBaseModelSchema = object({
39567
39675
  modelId: string(),
@@ -39579,9 +39687,13 @@ var TrainingPresetSchema = _enum([
39579
39687
  "thorough"
39580
39688
  ]);
39581
39689
  var TrainingJobRequestSchema = object({
39582
- datasetVersionId: string().min(1),
39583
- /** The `training-provider` addon that runs it. */
39584
- addonId: string().min(1),
39690
+ /** Live collection + work-state criteria; resolved at plan/start. */
39691
+ selection: TrainingCorpusSelectionSchema,
39692
+ /**
39693
+ * The provider **entry** that runs it (credentials + defaults).
39694
+ * Resolve to an owning addon via `training-provider.describe` / `listEntries`.
39695
+ */
39696
+ entryId: string().min(1),
39585
39697
  gpuType: string().min(1),
39586
39698
  region: string(),
39587
39699
  baseModelId: string().min(1),
@@ -39640,6 +39752,7 @@ var TrainingJobPlanSchema = object({
39640
39752
  * result lives after the operator acted on it.
39641
39753
  */
39642
39754
  var TrainingJobStateSchema = _enum([
39755
+ "queued",
39643
39756
  "uploading",
39644
39757
  "submitted",
39645
39758
  "starting",
@@ -39693,6 +39806,11 @@ var TrainingJobSchema = object({
39693
39806
  createdAt: number(),
39694
39807
  updatedAt: number(),
39695
39808
  state: TrainingJobStateSchema,
39809
+ /**
39810
+ * Shared by every job enqueued together via `startJobBatch`.
39811
+ * `null` for a lone `startJob`. The engine advances queued siblings by this id.
39812
+ */
39813
+ batchId: string().nullable().default(null),
39696
39814
  stage: TrainingStageSchema.nullable(),
39697
39815
  failure: object({
39698
39816
  reason: TrainingFailureReasonSchema,
@@ -39704,6 +39822,12 @@ var TrainingJobSchema = object({
39704
39822
  maxRuntimeSec: number().int().positive(),
39705
39823
  trainer: TrainerSourceRefSchema,
39706
39824
  datasetLayout: RetrainExportLayoutSchema,
39825
+ /** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
39826
+ frameCount: number().int().nonnegative(),
39827
+ /** Resolved frame ids at start — the archive ships exactly these. */
39828
+ frameIds: array(string()).max(2e4).readonly(),
39829
+ /** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
39830
+ annotationHash: string(),
39707
39831
  dataset: object({
39708
39832
  bytes: number().int(),
39709
39833
  sha256: string(),
@@ -39751,19 +39875,6 @@ var trainingCapability = {
39751
39875
  mode: "singleton",
39752
39876
  mount: { kind: "hub-only" },
39753
39877
  methods: {
39754
- /** Store a version once. `stored: false` = that id already exists (immutable). */
39755
- putDatasetVersion: method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
39756
- kind: "mutation",
39757
- auth: "admin"
39758
- }),
39759
- getDatasetVersion: method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }),
39760
- /** Every version without its frame list, newest first. */
39761
- listDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }),
39762
- findDatasetVersionIdByName: method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }),
39763
- removeDatasetVersion: method(IdInput, object({ removed: boolean() }), {
39764
- kind: "mutation",
39765
- auth: "admin"
39766
- }),
39767
39878
  listBaseModels: method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }),
39768
39879
  /** Split, estimate, defaults and any named refusal — nothing is started. */
39769
39880
  planJob: method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
@@ -39792,6 +39903,32 @@ var trainingCapability = {
39792
39903
  auth: "admin",
39793
39904
  timeoutMs: 12e4
39794
39905
  }),
39906
+ /**
39907
+ * Enqueue one job per base model (same selection, entry, caps). The first
39908
+ * becomes `uploading`; the rest stay `queued` until the prior job settles.
39909
+ * One ACTIVE job at a time — a parallel `startJob` still gets
39910
+ * `job-already-running`. The same `idempotencyKey` returns the batch it
39911
+ * already started.
39912
+ */
39913
+ startJobBatch: method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
39914
+ baseModelIds: array(string().min(1)).min(1),
39915
+ name: string().min(1).max(120),
39916
+ maxCostUsd: number().positive(),
39917
+ maxRuntimeSec: number().int().positive(),
39918
+ idempotencyKey: string().min(8).max(80)
39919
+ }), discriminatedUnion("kind", [object({
39920
+ kind: literal("started"),
39921
+ batchId: string(),
39922
+ jobs: array(TrainingJobSchema).min(1).readonly()
39923
+ }), object({
39924
+ kind: literal("refused"),
39925
+ reason: TrainingRefusalReasonSchema,
39926
+ detail: string()
39927
+ })]), {
39928
+ kind: "mutation",
39929
+ auth: "admin",
39930
+ timeoutMs: 12e4
39931
+ }),
39795
39932
  listJobs: method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }),
39796
39933
  getJob: method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }),
39797
39934
  cancelJob: method(IdInput, TrainingJobSchema, {
@@ -44049,12 +44186,6 @@ Object.freeze({
44049
44186
  addonId: null,
44050
44187
  access: "create"
44051
44188
  },
44052
- "pipelineAnalytics.createRetrainDatasetVersion": {
44053
- capName: "pipeline-analytics",
44054
- capScope: "device",
44055
- addonId: null,
44056
- access: "create"
44057
- },
44058
44189
  "pipelineAnalytics.deleteDeviceEvents": {
44059
44190
  capName: "pipeline-analytics",
44060
44191
  capScope: "device",
@@ -44067,12 +44198,6 @@ Object.freeze({
44067
44198
  addonId: null,
44068
44199
  access: "delete"
44069
44200
  },
44070
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
44071
- capName: "pipeline-analytics",
44072
- capScope: "device",
44073
- addonId: null,
44074
- access: "delete"
44075
- },
44076
44201
  "pipelineAnalytics.deleteTracks": {
44077
44202
  capName: "pipeline-analytics",
44078
44203
  capScope: "device",
@@ -44175,6 +44300,12 @@ Object.freeze({
44175
44300
  addonId: null,
44176
44301
  access: "view"
44177
44302
  },
44303
+ "pipelineAnalytics.getRetrainCorpusKpi": {
44304
+ capName: "pipeline-analytics",
44305
+ capScope: "device",
44306
+ addonId: null,
44307
+ access: "view"
44308
+ },
44178
44309
  "pipelineAnalytics.getRetrainExportUrl": {
44179
44310
  capName: "pipeline-analytics",
44180
44311
  capScope: "device",
@@ -44295,7 +44426,7 @@ Object.freeze({
44295
44426
  addonId: null,
44296
44427
  access: "view"
44297
44428
  },
44298
- "pipelineAnalytics.listRetrainDatasetVersions": {
44429
+ "pipelineAnalytics.listRetrainCorpusPage": {
44299
44430
  capName: "pipeline-analytics",
44300
44431
  capScope: "device",
44301
44432
  addonId: null,
@@ -44349,12 +44480,6 @@ Object.freeze({
44349
44480
  addonId: null,
44350
44481
  access: "create"
44351
44482
  },
44352
- "pipelineAnalytics.previewRetrainDataset": {
44353
- capName: "pipeline-analytics",
44354
- capScope: "device",
44355
- addonId: null,
44356
- access: "view"
44357
- },
44358
44483
  "pipelineAnalytics.proposeRetrainAnnotations": {
44359
44484
  capName: "pipeline-analytics",
44360
44485
  capScope: "device",
@@ -44433,6 +44558,12 @@ Object.freeze({
44433
44558
  addonId: null,
44434
44559
  access: "create"
44435
44560
  },
44561
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
44562
+ capName: "pipeline-analytics",
44563
+ capScope: "device",
44564
+ addonId: null,
44565
+ access: "view"
44566
+ },
44436
44567
  "pipelineAnalytics.restageRetrainTrack": {
44437
44568
  capName: "pipeline-analytics",
44438
44569
  capScope: "device",
@@ -44493,12 +44624,6 @@ Object.freeze({
44493
44624
  addonId: null,
44494
44625
  access: "create"
44495
44626
  },
44496
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
44497
- capName: "pipeline-analytics",
44498
- capScope: "device",
44499
- addonId: null,
44500
- access: "view"
44501
- },
44502
44627
  "pipelineAnalytics.wipeAllAnalytics": {
44503
44628
  capName: "pipeline-analytics",
44504
44629
  capScope: "device",
@@ -46893,18 +47018,6 @@ Object.freeze({
46893
47018
  addonId: null,
46894
47019
  access: "create"
46895
47020
  },
46896
- "training.findDatasetVersionIdByName": {
46897
- capName: "training",
46898
- capScope: "system",
46899
- addonId: null,
46900
- access: "view"
46901
- },
46902
- "training.getDatasetVersion": {
46903
- capName: "training",
46904
- capScope: "system",
46905
- addonId: null,
46906
- access: "view"
46907
- },
46908
47021
  "training.getJob": {
46909
47022
  capName: "training",
46910
47023
  capScope: "system",
@@ -46923,12 +47036,6 @@ Object.freeze({
46923
47036
  addonId: null,
46924
47037
  access: "view"
46925
47038
  },
46926
- "training.listDatasetVersions": {
46927
- capName: "training",
46928
- capScope: "system",
46929
- addonId: null,
46930
- access: "view"
46931
- },
46932
47039
  "training.listJobs": {
46933
47040
  capName: "training",
46934
47041
  capScope: "system",
@@ -46941,54 +47048,66 @@ Object.freeze({
46941
47048
  addonId: null,
46942
47049
  access: "view"
46943
47050
  },
46944
- "training.putDatasetVersion": {
47051
+ "training.registerResult": {
46945
47052
  capName: "training",
46946
47053
  capScope: "system",
46947
47054
  addonId: null,
46948
47055
  access: "create"
46949
47056
  },
46950
- "training.registerResult": {
47057
+ "training.rollbackCanary": {
46951
47058
  capName: "training",
46952
47059
  capScope: "system",
46953
47060
  addonId: null,
46954
47061
  access: "create"
46955
47062
  },
46956
- "training.removeDatasetVersion": {
47063
+ "training.startJob": {
46957
47064
  capName: "training",
46958
47065
  capScope: "system",
46959
47066
  addonId: null,
46960
- access: "delete"
47067
+ access: "create"
46961
47068
  },
46962
- "training.rollbackCanary": {
47069
+ "training.startJobBatch": {
46963
47070
  capName: "training",
46964
47071
  capScope: "system",
46965
47072
  addonId: null,
46966
47073
  access: "create"
46967
47074
  },
46968
- "training.startJob": {
46969
- capName: "training",
47075
+ "trainingProvider.cancelJob": {
47076
+ capName: "training-provider",
46970
47077
  capScope: "system",
46971
47078
  addonId: null,
46972
47079
  access: "create"
46973
47080
  },
46974
- "trainingProvider.cancelJob": {
47081
+ "trainingProvider.cleanupJob": {
46975
47082
  capName: "training-provider",
46976
47083
  capScope: "system",
46977
47084
  addonId: null,
46978
47085
  access: "create"
46979
47086
  },
46980
- "trainingProvider.cleanupJob": {
47087
+ "trainingProvider.createEntry": {
46981
47088
  capName: "training-provider",
46982
47089
  capScope: "system",
46983
47090
  addonId: null,
46984
47091
  access: "create"
46985
47092
  },
47093
+ "trainingProvider.deleteEntry": {
47094
+ capName: "training-provider",
47095
+ capScope: "system",
47096
+ addonId: null,
47097
+ access: "delete"
47098
+ },
46986
47099
  "trainingProvider.describe": {
46987
47100
  capName: "training-provider",
46988
47101
  capScope: "system",
46989
47102
  addonId: null,
46990
47103
  access: "view"
46991
47104
  },
47105
+ "trainingProvider.describeTypes": {
47106
+ capName: "training-provider",
47107
+ capScope: "system",
47108
+ addonId: null,
47109
+ access: "view"
47110
+ },
46992
47111
  "trainingProvider.estimateJob": {
46993
47112
  capName: "training-provider",
46994
47113
  capScope: "system",
@@ -47001,6 +47120,12 @@ Object.freeze({
47001
47120
  addonId: null,
47002
47121
  access: "view"
47003
47122
  },
47123
+ "trainingProvider.listEntries": {
47124
+ capName: "training-provider",
47125
+ capScope: "system",
47126
+ addonId: null,
47127
+ access: "view"
47128
+ },
47004
47129
  "trainingProvider.listJobEvents": {
47005
47130
  capName: "training-provider",
47006
47131
  capScope: "system",
@@ -50457,6 +50582,11 @@ Object.freeze({
50457
50582
  form: "array",
50458
50583
  optional: false
50459
50584
  }],
50585
+ "pipelineAnalytics.listRetrainCorpusPage": [{
50586
+ name: "deviceIds",
50587
+ form: "array",
50588
+ optional: true
50589
+ }],
50460
50590
  "pipelineAnalytics.listRetrainStaging": [{
50461
50591
  name: "deviceIds",
50462
50592
  form: "array",
@@ -52617,12 +52747,6 @@ Object.defineProperty(exports, "TRAINING_JOB_SCHEMA", {
52617
52747
  return TRAINING_JOB_SCHEMA;
52618
52748
  }
52619
52749
  });
52620
- Object.defineProperty(exports, "TrainingDatasetVersionRowSchema", {
52621
- enumerable: true,
52622
- get: function() {
52623
- return TrainingDatasetVersionRowSchema;
52624
- }
52625
- });
52626
52750
  Object.defineProperty(exports, "TrainingJobSchema", {
52627
52751
  enumerable: true,
52628
52752
  get: function() {