@camstack/addon-post-analysis 1.2.351 → 1.2.353
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.
- package/dist/{clip-model-registry-DI12tTgY.js → clip-model-registry-CPNsQNt5.js} +302 -158
- package/dist/{clip-model-registry-CC-BJYiK.mjs → clip-model-registry-VI28etdt.mjs} +302 -158
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-5v6z6gQL.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Cfcb9thb.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-N64PaPIw.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Clwp5JZq.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-BKDWAGHG.mjs → hostInit-DpCJPMQZ.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +678 -942
- package/dist/pipeline-analytics/index.mjs +678 -942
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Du_tzgi2.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CQOJKiwa.mjs +0 -26
|
@@ -5449,7 +5449,7 @@ var ZodIssueCode = {
|
|
|
5449
5449
|
var ZodFirstPartyTypeKind;
|
|
5450
5450
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5451
5451
|
//#endregion
|
|
5452
|
-
//#region ../types/dist/sleep-
|
|
5452
|
+
//#region ../types/dist/sleep-CI0n5D44.mjs
|
|
5453
5453
|
/**
|
|
5454
5454
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5455
5455
|
* window to float samples (D455).
|
|
@@ -9939,6 +9939,16 @@ var CompositionSchema = object({
|
|
|
9939
9939
|
seen.add(feature.cap);
|
|
9940
9940
|
});
|
|
9941
9941
|
});
|
|
9942
|
+
var NodeColorIdSchema = _enum([
|
|
9943
|
+
"node-a",
|
|
9944
|
+
"node-b",
|
|
9945
|
+
"node-c",
|
|
9946
|
+
"node-d",
|
|
9947
|
+
"node-e",
|
|
9948
|
+
"node-f",
|
|
9949
|
+
"node-g",
|
|
9950
|
+
"node-h"
|
|
9951
|
+
]);
|
|
9942
9952
|
var OWNER_TYPES = new Set([
|
|
9943
9953
|
"track",
|
|
9944
9954
|
"face",
|
|
@@ -28950,24 +28960,69 @@ var RetrainFrameListSchema = object({
|
|
|
28950
28960
|
/** What the page pre-selects — the native key frame when one survives. */
|
|
28951
28961
|
autoPickMediaId: number().int().optional()
|
|
28952
28962
|
});
|
|
28963
|
+
/** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
|
|
28964
|
+
var RetrainFrameWorkStateSchema = _enum([
|
|
28965
|
+
"unannotated",
|
|
28966
|
+
"annotated",
|
|
28967
|
+
"complete"
|
|
28968
|
+
]);
|
|
28969
|
+
/**
|
|
28970
|
+
* Filters for paginated corpus list, KPI, and matching export (design §4.4).
|
|
28971
|
+
* Every narrowing field is ANDed; omitted fields impose no constraint.
|
|
28972
|
+
*/
|
|
28973
|
+
var RetrainCorpusFilterSchema = object({
|
|
28974
|
+
workState: RetrainFrameWorkStateSchema.optional(),
|
|
28975
|
+
deviceIds: array(number()).max(500).optional(),
|
|
28976
|
+
/** When set, only frames in this named collection. */
|
|
28977
|
+
collectionId: string().optional(),
|
|
28978
|
+
/** Frames that carry at least one saved annotation in one of these classes. */
|
|
28979
|
+
classes: array(RetrainMacroClassSchema).optional(),
|
|
28980
|
+
page: number().int().positive().default(1),
|
|
28981
|
+
pageSize: number().int().positive().max(100).default(50)
|
|
28982
|
+
});
|
|
28983
|
+
var RetrainCorpusPageSchema = object({
|
|
28984
|
+
frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
|
|
28985
|
+
total: number().int().nonnegative(),
|
|
28986
|
+
page: number().int().positive(),
|
|
28987
|
+
pageSize: number().int().positive()
|
|
28988
|
+
});
|
|
28989
|
+
var RetrainCorpusKpiCameraRowSchema = object({
|
|
28990
|
+
deviceId: number(),
|
|
28991
|
+
unannotated: number().int().nonnegative(),
|
|
28992
|
+
annotated: number().int().nonnegative(),
|
|
28993
|
+
complete: number().int().nonnegative(),
|
|
28994
|
+
/** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
|
|
28995
|
+
* `null` when the corpus is empty (no ratio). */
|
|
28996
|
+
pctOfCorpus: number().min(0).max(1).nullable()
|
|
28997
|
+
});
|
|
28998
|
+
var RetrainCorpusKpiSchema = object({
|
|
28999
|
+
total: number().int().nonnegative(),
|
|
29000
|
+
unannotated: number().int().nonnegative(),
|
|
29001
|
+
annotated: number().int().nonnegative(),
|
|
29002
|
+
complete: number().int().nonnegative(),
|
|
29003
|
+
cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
|
|
29004
|
+
});
|
|
28953
29005
|
/**
|
|
28954
29006
|
* Which frames an annotated export carries. Every field narrows; an empty
|
|
28955
|
-
* filter is every annotated copy.
|
|
28956
|
-
*
|
|
28957
|
-
*
|
|
28958
|
-
*
|
|
29007
|
+
* filter is every annotated copy. `frameIds` is the primitive a job or
|
|
29008
|
+
* download uses; `batchId` re-selects what an earlier export carried
|
|
29009
|
+
* (`exportedInBatch`). Frozen dataset versions were removed — live selection
|
|
29010
|
+
* resolves to `frameIds` at plan/start.
|
|
28959
29011
|
*/
|
|
28960
29012
|
var RetrainExportFilterSchema = object({
|
|
28961
29013
|
deviceIds: array(number()).optional(),
|
|
28962
29014
|
frameIds: array(string()).max(2e4).optional(),
|
|
28963
29015
|
/** Only frames in at least one of these named collections. */
|
|
28964
29016
|
collectionIds: array(string()).max(200).optional(),
|
|
28965
|
-
/**
|
|
28966
|
-
|
|
28967
|
-
datasetVersionId: string().optional(),
|
|
29017
|
+
/** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
|
|
29018
|
+
collectionId: string().optional(),
|
|
28968
29019
|
batchId: string().optional(),
|
|
28969
29020
|
/** Only frames the operator marked complete (all subjects boxed). */
|
|
28970
|
-
completeOnly: boolean().optional()
|
|
29021
|
+
completeOnly: boolean().optional(),
|
|
29022
|
+
/** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
|
|
29023
|
+
workState: RetrainFrameWorkStateSchema.optional(),
|
|
29024
|
+
/** Frames with at least one saved annotation in one of these classes. */
|
|
29025
|
+
classes: array(RetrainMacroClassSchema).optional()
|
|
28971
29026
|
});
|
|
28972
29027
|
/**
|
|
28973
29028
|
* `frames`: the full frame copies, boxes in `annotations.json`.
|
|
@@ -29167,8 +29222,7 @@ var RetrainDatasetStatsSchema = object({
|
|
|
29167
29222
|
completeFrames: number().int()
|
|
29168
29223
|
})).readonly()
|
|
29169
29224
|
});
|
|
29170
|
-
|
|
29171
|
-
var RetrainDatasetVersionSchema = object({
|
|
29225
|
+
object({
|
|
29172
29226
|
id: string(),
|
|
29173
29227
|
name: string(),
|
|
29174
29228
|
createdAt: number(),
|
|
@@ -29176,22 +29230,33 @@ var RetrainDatasetVersionSchema = object({
|
|
|
29176
29230
|
layout: RetrainExportLayoutSchema,
|
|
29177
29231
|
completeOnly: boolean(),
|
|
29178
29232
|
frameCount: number().int(),
|
|
29179
|
-
/** sha256 of what the frames taught when the version was frozen. */
|
|
29180
29233
|
annotationHash: string(),
|
|
29181
|
-
/** The export manifest schema the version was cut under. */
|
|
29182
29234
|
manifestSchema: string(),
|
|
29183
29235
|
stats: RetrainDatasetStatsSchema
|
|
29184
29236
|
});
|
|
29185
|
-
|
|
29186
|
-
|
|
29187
|
-
|
|
29237
|
+
/**
|
|
29238
|
+
* Live training corpus criteria — same shape as `TrainingCorpusSelection` on
|
|
29239
|
+
* the training cap. Resolved here so plan/start and the annotated export share
|
|
29240
|
+
* one definition of "the frames" (`buildRetrainExportPlan`).
|
|
29241
|
+
*/
|
|
29242
|
+
var RetrainTrainingCorpusSelectionSchema = object({
|
|
29243
|
+
collectionIds: array(string()).min(1),
|
|
29244
|
+
workState: _enum([
|
|
29245
|
+
"complete",
|
|
29246
|
+
"annotated_or_complete",
|
|
29247
|
+
"any_annotated"
|
|
29248
|
+
]).default("complete")
|
|
29249
|
+
});
|
|
29250
|
+
var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
|
|
29251
|
+
kind: literal("resolved"),
|
|
29252
|
+
frameIds: array(string()).max(2e4).readonly(),
|
|
29253
|
+
stats: RetrainDatasetStatsSchema,
|
|
29254
|
+
annotationHash: string(),
|
|
29255
|
+
layout: RetrainExportLayoutSchema
|
|
29188
29256
|
}), object({
|
|
29189
29257
|
kind: literal("refused"),
|
|
29190
|
-
reason: _enum([
|
|
29191
|
-
|
|
29192
|
-
"duplicate-name",
|
|
29193
|
-
"no-frames"
|
|
29194
|
-
])
|
|
29258
|
+
reason: _enum(["unknown-collection", "no-frames"]),
|
|
29259
|
+
detail: string()
|
|
29195
29260
|
})]);
|
|
29196
29261
|
/** The outcome of a lifecycle move owned by the retrain page. */
|
|
29197
29262
|
var RetrainTransitionResultSchema = object({
|
|
@@ -30367,6 +30432,26 @@ var pipelineAnalyticsCapability = {
|
|
|
30367
30432
|
auth: "admin"
|
|
30368
30433
|
}),
|
|
30369
30434
|
/**
|
|
30435
|
+
* Paginated corpus copies for the Frames grid — index reads only.
|
|
30436
|
+
*
|
|
30437
|
+
* Filters AND (`workState`, cameras, one collection, annotated classes).
|
|
30438
|
+
* An answered empty match is `{ frames: [], total: 0, … }` (D315), never a
|
|
30439
|
+
* pending masquerade. Classification uses `workStateOf` (annotation count
|
|
30440
|
+
* wins over a stray `complete` flag).
|
|
30441
|
+
*/
|
|
30442
|
+
listRetrainCorpusPage: method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
|
|
30443
|
+
kind: "query",
|
|
30444
|
+
auth: "admin"
|
|
30445
|
+
}),
|
|
30446
|
+
/**
|
|
30447
|
+
* Global + per-camera corpus KPI. Unfiltered totals; `%` on a camera row is
|
|
30448
|
+
* `complete(camera) / corpus total`, or `null` when the corpus is empty.
|
|
30449
|
+
*/
|
|
30450
|
+
getRetrainCorpusKpi: method(object({}), RetrainCorpusKpiSchema, {
|
|
30451
|
+
kind: "query",
|
|
30452
|
+
auth: "admin"
|
|
30453
|
+
}),
|
|
30454
|
+
/**
|
|
30370
30455
|
* What a track can contribute, and what it already has.
|
|
30371
30456
|
*
|
|
30372
30457
|
* `candidates` are the track's whole, unannotated frames — index rows only,
|
|
@@ -30593,53 +30678,6 @@ var pipelineAnalyticsCapability = {
|
|
|
30593
30678
|
auth: "admin",
|
|
30594
30679
|
timeoutMs: 12e4
|
|
30595
30680
|
}),
|
|
30596
|
-
/** The counts a selection would freeze — class × camera × day/night,
|
|
30597
|
-
* completeness — without freezing anything. Index reads only. */
|
|
30598
|
-
previewRetrainDataset: method(object({
|
|
30599
|
-
selection: RetrainDatasetSelectionSchema,
|
|
30600
|
-
completeOnly: boolean().optional()
|
|
30601
|
-
}), RetrainDatasetStatsSchema, {
|
|
30602
|
-
kind: "query",
|
|
30603
|
-
auth: "admin"
|
|
30604
|
-
}),
|
|
30605
|
-
/**
|
|
30606
|
-
* Freeze a dataset version: the frames the selection yields (the same plan
|
|
30607
|
-
* the annotated export builds), the hash of what they teach, the export
|
|
30608
|
-
* parameters and the counts. Immutable — a different selection is a new
|
|
30609
|
-
* version. Export it with `getRetrainExportUrl({ datasetVersionId })`.
|
|
30610
|
-
*/
|
|
30611
|
-
createRetrainDatasetVersion: method(object({
|
|
30612
|
-
name: string().max(120),
|
|
30613
|
-
selection: RetrainDatasetSelectionSchema,
|
|
30614
|
-
layout: RetrainExportLayoutSchema,
|
|
30615
|
-
completeOnly: boolean()
|
|
30616
|
-
}), CreateRetrainDatasetVersionResultSchema, {
|
|
30617
|
-
kind: "mutation",
|
|
30618
|
-
auth: "admin",
|
|
30619
|
-
timeoutMs: 12e4
|
|
30620
|
-
}),
|
|
30621
|
-
/** Every dataset version, newest first. */
|
|
30622
|
-
listRetrainDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
|
|
30623
|
-
kind: "query",
|
|
30624
|
-
auth: "admin"
|
|
30625
|
-
}),
|
|
30626
|
-
/** Delete a version. Its frames stay in the dataset. */
|
|
30627
|
-
deleteRetrainDatasetVersion: method(object({ id: string() }), object({ deleted: boolean() }), {
|
|
30628
|
-
kind: "mutation",
|
|
30629
|
-
auth: "admin"
|
|
30630
|
-
}),
|
|
30631
|
-
/** Does the corpus still teach what the version froze? `missingFrames`
|
|
30632
|
-
* counts frames that left the dataset (or lost every box and tick). */
|
|
30633
|
-
verifyRetrainDatasetVersion: method(object({ id: string() }), object({
|
|
30634
|
-
found: boolean(),
|
|
30635
|
-
annotationHash: string(),
|
|
30636
|
-
matches: boolean(),
|
|
30637
|
-
missingFrames: number().int()
|
|
30638
|
-
}), {
|
|
30639
|
-
kind: "query",
|
|
30640
|
-
auth: "admin",
|
|
30641
|
-
timeoutMs: 12e4
|
|
30642
|
-
}),
|
|
30643
30681
|
/** The enabled, vision-capable LLM profiles, each saying whether a frame
|
|
30644
30682
|
* sent to it leaves the house. */
|
|
30645
30683
|
listRetrainAssistProfiles: method(object({}), array(RetrainAssistProfileSchema).readonly(), {
|
|
@@ -30686,6 +30724,16 @@ var pipelineAnalyticsCapability = {
|
|
|
30686
30724
|
kind: "query",
|
|
30687
30725
|
auth: "admin"
|
|
30688
30726
|
}),
|
|
30727
|
+
/**
|
|
30728
|
+
* Resolve a live training corpus selection to frame ids + stats (index
|
|
30729
|
+
* reads only). Same plan the annotated export builds — training plan/start
|
|
30730
|
+
* calls this instead of a frozen dataset version.
|
|
30731
|
+
*/
|
|
30732
|
+
resolveRetrainTrainingCorpus: method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
|
|
30733
|
+
kind: "query",
|
|
30734
|
+
auth: "admin",
|
|
30735
|
+
timeoutMs: 6e4
|
|
30736
|
+
}),
|
|
30689
30737
|
renameRetrainCollection: method(object({
|
|
30690
30738
|
id: string(),
|
|
30691
30739
|
name: string().max(120)
|
|
@@ -31639,11 +31687,14 @@ var HardwareClassIdSchema = _enum([
|
|
|
31639
31687
|
"intel-n-series",
|
|
31640
31688
|
"apple-m-base",
|
|
31641
31689
|
"apple-m-pro",
|
|
31690
|
+
"amd-phoenix",
|
|
31642
31691
|
"unknown"
|
|
31643
31692
|
]);
|
|
31644
31693
|
var AcceleratorKindSchema = _enum([
|
|
31645
31694
|
"intel-npu",
|
|
31646
31695
|
"intel-igpu",
|
|
31696
|
+
"amd-igpu",
|
|
31697
|
+
"amd-npu",
|
|
31647
31698
|
"x86-cpu",
|
|
31648
31699
|
"arm-cpu",
|
|
31649
31700
|
"apple-ane",
|
|
@@ -33779,6 +33830,8 @@ var AgentPipelineSettingsSchema = object({
|
|
|
33779
33830
|
* address is wrong (multi-homed host, NAT, custom interface).
|
|
33780
33831
|
*/
|
|
33781
33832
|
reachableHost: string().optional(),
|
|
33833
|
+
/** Hub-persisted UI colour (`--color-node-*` theme tokens). */
|
|
33834
|
+
color: NodeColorIdSchema.optional(),
|
|
33782
33835
|
/**
|
|
33783
33836
|
* Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
|
|
33784
33837
|
* weight, steps}. Absent / all-disabled ⇒ the node's single default
|
|
@@ -34505,8 +34558,9 @@ var pipelineOrchestratorCapability = {
|
|
|
34505
34558
|
*/
|
|
34506
34559
|
setAgentReachableHost: method(object({
|
|
34507
34560
|
agentNodeId: string(),
|
|
34508
|
-
reachableHost: string().nullable()
|
|
34509
|
-
|
|
34561
|
+
reachableHost: string().nullable().optional(),
|
|
34562
|
+
color: NodeColorIdSchema.nullable().optional()
|
|
34563
|
+
}).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
|
|
34510
34564
|
kind: "mutation",
|
|
34511
34565
|
auth: "admin"
|
|
34512
34566
|
}),
|
|
@@ -45610,7 +45664,15 @@ var GpuInfoSchema = object({
|
|
|
45610
45664
|
name: string(),
|
|
45611
45665
|
memoryMB: number().optional()
|
|
45612
45666
|
});
|
|
45613
|
-
var NpuInfoSchema = object({
|
|
45667
|
+
var NpuInfoSchema = object({
|
|
45668
|
+
type: _enum([
|
|
45669
|
+
"apple-ane",
|
|
45670
|
+
"intel-npu",
|
|
45671
|
+
"amd-xdna"
|
|
45672
|
+
]),
|
|
45673
|
+
name: string().optional(),
|
|
45674
|
+
generation: _enum(["xdna1", "xdna2"]).optional()
|
|
45675
|
+
});
|
|
45614
45676
|
var CoralInfoSchema = object({
|
|
45615
45677
|
type: literal("coral-edgetpu"),
|
|
45616
45678
|
bus: string().optional()
|
|
@@ -50987,9 +51049,11 @@ var zoneRulesCapability = {
|
|
|
50987
51049
|
* once is what makes a second provider (RunPod, a local NVIDIA node) a new
|
|
50988
51050
|
* manifest entry and nothing else.
|
|
50989
51051
|
*
|
|
50990
|
-
* Collection
|
|
50991
|
-
*
|
|
50992
|
-
*
|
|
51052
|
+
* Collection of provider **types** (addons). Each addon owns zero or more
|
|
51053
|
+
* **entries** (credentials + defaults). Concat-fans: `describe`,
|
|
51054
|
+
* `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
|
|
51055
|
+
* `entryId`; callers also pass the owning `addonId` as the collection
|
|
51056
|
+
* selector (broker posture). Every method is `admin`: these spend money.
|
|
50993
51057
|
*
|
|
50994
51058
|
* Every cloud object a provider creates is tagged with the orchestrator's
|
|
50995
51059
|
* `jobKey`, so a retried submit finds the job it already started instead of
|
|
@@ -51013,8 +51077,8 @@ var TrainingRegionOptionSchema = object({
|
|
|
51013
51077
|
priceMultiplier: number().positive()
|
|
51014
51078
|
});
|
|
51015
51079
|
/**
|
|
51016
|
-
* The provider's per-
|
|
51017
|
-
* live
|
|
51080
|
+
* The provider's per-entry settings, as the orchestrator reads them. They
|
|
51081
|
+
* live on the PROVIDER addon's entry (operator decision 2026-10-08: they
|
|
51018
51082
|
* depend on the user's account), never hard-coded in the orchestrator.
|
|
51019
51083
|
*/
|
|
51020
51084
|
var TrainingProviderDefaultsSchema = object({
|
|
@@ -51025,9 +51089,32 @@ var TrainingProviderDefaultsSchema = object({
|
|
|
51025
51089
|
/** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
|
|
51026
51090
|
failedDatasetGraceHours: number().nonnegative()
|
|
51027
51091
|
});
|
|
51092
|
+
/** One creatable provider type, for the Add-entry dialog. */
|
|
51093
|
+
var TrainingProviderTypeSchema = object({
|
|
51094
|
+
typeId: string(),
|
|
51095
|
+
label: string(),
|
|
51096
|
+
/** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
|
|
51097
|
+
iconAsset: string(),
|
|
51098
|
+
/** Owning `training-provider` addon — collection selector for createEntry. */
|
|
51099
|
+
addonId: string()
|
|
51100
|
+
});
|
|
51101
|
+
/** One configured account / workspace under a provider type. */
|
|
51102
|
+
var TrainingProviderEntrySchema = object({
|
|
51103
|
+
entryId: string(),
|
|
51104
|
+
typeId: string(),
|
|
51105
|
+
name: string(),
|
|
51106
|
+
addonId: string(),
|
|
51107
|
+
/** Credentials are present — never the values. */
|
|
51108
|
+
configured: boolean()
|
|
51109
|
+
});
|
|
51028
51110
|
var TrainingProviderDescriptorSchema = object({
|
|
51029
51111
|
addonId: string(),
|
|
51030
|
-
|
|
51112
|
+
entryId: string(),
|
|
51113
|
+
typeId: string(),
|
|
51114
|
+
/** Operator-chosen entry name. */
|
|
51115
|
+
name: string(),
|
|
51116
|
+
iconAsset: string(),
|
|
51117
|
+
/** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
|
|
51031
51118
|
kind: string(),
|
|
51032
51119
|
label: string(),
|
|
51033
51120
|
gpuTypes: array(TrainingGpuOptionSchema).readonly(),
|
|
@@ -51091,8 +51178,9 @@ var TrainerSourceRefSchema = object({
|
|
|
51091
51178
|
/** A commit sha (never a branch) — the job must be reproducible. */
|
|
51092
51179
|
revision: string().regex(/^[0-9a-f]{7,64}$/)
|
|
51093
51180
|
});
|
|
51181
|
+
/** Cloud job identity — route with the owning addon's `addonId` selector. */
|
|
51094
51182
|
var JobRef = {
|
|
51095
|
-
|
|
51183
|
+
entryId: string().min(1),
|
|
51096
51184
|
jobKey: string().uuid()
|
|
51097
51185
|
};
|
|
51098
51186
|
var TrainingLogLineSchema = object({
|
|
@@ -51105,17 +51193,37 @@ var trainingProviderCapability = {
|
|
|
51105
51193
|
mode: "collection",
|
|
51106
51194
|
internal: true,
|
|
51107
51195
|
methods: {
|
|
51108
|
-
/** Every
|
|
51196
|
+
/** Every entry's offer and settings. Concat-fans across providers. */
|
|
51109
51197
|
describe: method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }),
|
|
51110
|
-
/**
|
|
51111
|
-
|
|
51198
|
+
/** Creatable types for the Add-entry dialog. Concat-fans. */
|
|
51199
|
+
describeTypes: method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }),
|
|
51200
|
+
/** Configured entries (pills). Concat-fans. */
|
|
51201
|
+
listEntries: method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }),
|
|
51202
|
+
/**
|
|
51203
|
+
* Create an entry under this provider type. Pin with `{ addonId }` of the
|
|
51204
|
+
* type's owning addon (from describeTypes).
|
|
51205
|
+
*/
|
|
51206
|
+
createEntry: method(object({
|
|
51207
|
+
typeId: string().min(1),
|
|
51208
|
+
name: string().min(1)
|
|
51209
|
+
}), object({ entryId: string() }), {
|
|
51210
|
+
kind: "mutation",
|
|
51211
|
+
auth: "admin"
|
|
51212
|
+
}),
|
|
51213
|
+
/** Delete an entry. Pin with the owning `{ addonId }`. */
|
|
51214
|
+
deleteEntry: method(object({ entryId: string().min(1) }), object({ ok: literal(true) }), {
|
|
51215
|
+
kind: "mutation",
|
|
51216
|
+
auth: "admin"
|
|
51217
|
+
}),
|
|
51218
|
+
/** Call the provider with the entry's stored credentials. Never returns them. */
|
|
51219
|
+
validateCredentials: method(object({ entryId: string().min(1) }), TrainingCredentialCheckSchema, {
|
|
51112
51220
|
kind: "mutation",
|
|
51113
51221
|
auth: "admin",
|
|
51114
51222
|
timeoutMs: 3e4
|
|
51115
51223
|
}),
|
|
51116
51224
|
/** USD range for a run of `gpuSeconds` on `gpuType` in `region`. */
|
|
51117
51225
|
estimateJob: method(object({
|
|
51118
|
-
|
|
51226
|
+
entryId: string().min(1),
|
|
51119
51227
|
gpuType: string(),
|
|
51120
51228
|
region: string(),
|
|
51121
51229
|
datasetBytes: number().int().nonnegative(),
|
|
@@ -51211,8 +51319,11 @@ var trainingProviderCapability = {
|
|
|
51211
51319
|
auth: "admin",
|
|
51212
51320
|
timeoutMs: 5 * 6e4
|
|
51213
51321
|
}),
|
|
51214
|
-
/**
|
|
51215
|
-
|
|
51322
|
+
/**
|
|
51323
|
+
* Jobs this provider can still see. Optional `entryId` filters; omit to
|
|
51324
|
+
* list every entry (orphan sweep). Pin with `{ addonId }`.
|
|
51325
|
+
*/
|
|
51326
|
+
listJobs: method(object({ entryId: string().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
|
|
51216
51327
|
auth: "admin",
|
|
51217
51328
|
timeoutMs: 2 * 6e4
|
|
51218
51329
|
})
|
|
@@ -51224,20 +51335,31 @@ var trainingProviderCapability = {
|
|
|
51224
51335
|
*
|
|
51225
51336
|
* It owns what every provider must agree on, written once:
|
|
51226
51337
|
*
|
|
51227
|
-
* - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
|
|
51228
|
-
* live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
|
|
51229
|
-
* the export plan) and reaches this store through the five row methods
|
|
51230
|
-
* below, so the Retrain page and the export did not change.
|
|
51231
51338
|
* - **Jobs.** A persisted state machine, a reconcile loop against the
|
|
51232
51339
|
* provider, a cost guard, a daily orphan sweep and the retention rules.
|
|
51233
51340
|
* - **The return flow.** Verified artefacts → Model Studio
|
|
51234
51341
|
* (`custom-model-registry.importModelBundle`) → canary on cameras →
|
|
51235
51342
|
* rollback. Nothing is ever registered automatically.
|
|
51236
51343
|
*
|
|
51344
|
+
* Plan/start takes a live {@link TrainingCorpusSelection} (collections +
|
|
51345
|
+
* work-state rule); frame ids are resolved via pipeline-analytics at that
|
|
51346
|
+
* moment and snapshotted on the job. No frozen dataset version.
|
|
51347
|
+
*
|
|
51237
51348
|
* Every method is `admin`.
|
|
51238
51349
|
*/
|
|
51239
|
-
/**
|
|
51240
|
-
|
|
51350
|
+
/**
|
|
51351
|
+
* Live corpus criteria for plan/start (design §5.2). Default is complete-only.
|
|
51352
|
+
* Frame ids are resolved at plan/start — never a frozen version id.
|
|
51353
|
+
*/
|
|
51354
|
+
var TrainingCorpusSelectionSchema = object({
|
|
51355
|
+
collectionIds: array(string()).min(1),
|
|
51356
|
+
/** Default complete-only for v1 */
|
|
51357
|
+
workState: _enum([
|
|
51358
|
+
"complete",
|
|
51359
|
+
"annotated_or_complete",
|
|
51360
|
+
"any_annotated"
|
|
51361
|
+
]).default("complete")
|
|
51362
|
+
});
|
|
51241
51363
|
/** A base model a detector job can fine-tune, and the baseline it is judged against. */
|
|
51242
51364
|
var TrainingBaseModelSchema = object({
|
|
51243
51365
|
modelId: string(),
|
|
@@ -51255,9 +51377,13 @@ var TrainingPresetSchema = _enum([
|
|
|
51255
51377
|
"thorough"
|
|
51256
51378
|
]);
|
|
51257
51379
|
var TrainingJobRequestSchema = object({
|
|
51258
|
-
|
|
51259
|
-
|
|
51260
|
-
|
|
51380
|
+
/** Live collection + work-state criteria; resolved at plan/start. */
|
|
51381
|
+
selection: TrainingCorpusSelectionSchema,
|
|
51382
|
+
/**
|
|
51383
|
+
* The provider **entry** that runs it (credentials + defaults).
|
|
51384
|
+
* Resolve to an owning addon via `training-provider.describe` / `listEntries`.
|
|
51385
|
+
*/
|
|
51386
|
+
entryId: string().min(1),
|
|
51261
51387
|
gpuType: string().min(1),
|
|
51262
51388
|
region: string(),
|
|
51263
51389
|
baseModelId: string().min(1),
|
|
@@ -51316,6 +51442,7 @@ var TrainingJobPlanSchema = object({
|
|
|
51316
51442
|
* result lives after the operator acted on it.
|
|
51317
51443
|
*/
|
|
51318
51444
|
var TrainingJobStateSchema = _enum([
|
|
51445
|
+
"queued",
|
|
51319
51446
|
"uploading",
|
|
51320
51447
|
"submitted",
|
|
51321
51448
|
"starting",
|
|
@@ -51369,6 +51496,11 @@ var TrainingJobSchema = object({
|
|
|
51369
51496
|
createdAt: number(),
|
|
51370
51497
|
updatedAt: number(),
|
|
51371
51498
|
state: TrainingJobStateSchema,
|
|
51499
|
+
/**
|
|
51500
|
+
* Shared by every job enqueued together via `startJobBatch`.
|
|
51501
|
+
* `null` for a lone `startJob`. The engine advances queued siblings by this id.
|
|
51502
|
+
*/
|
|
51503
|
+
batchId: string().nullable().default(null),
|
|
51372
51504
|
stage: TrainingStageSchema.nullable(),
|
|
51373
51505
|
failure: object({
|
|
51374
51506
|
reason: TrainingFailureReasonSchema,
|
|
@@ -51380,6 +51512,12 @@ var TrainingJobSchema = object({
|
|
|
51380
51512
|
maxRuntimeSec: number().int().positive(),
|
|
51381
51513
|
trainer: TrainerSourceRefSchema,
|
|
51382
51514
|
datasetLayout: RetrainExportLayoutSchema,
|
|
51515
|
+
/** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
|
|
51516
|
+
frameCount: number().int().nonnegative(),
|
|
51517
|
+
/** Resolved frame ids at start — the archive ships exactly these. */
|
|
51518
|
+
frameIds: array(string()).max(2e4).readonly(),
|
|
51519
|
+
/** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
|
|
51520
|
+
annotationHash: string(),
|
|
51383
51521
|
dataset: object({
|
|
51384
51522
|
bytes: number().int(),
|
|
51385
51523
|
sha256: string(),
|
|
@@ -51427,19 +51565,6 @@ var trainingCapability = {
|
|
|
51427
51565
|
mode: "singleton",
|
|
51428
51566
|
mount: { kind: "hub-only" },
|
|
51429
51567
|
methods: {
|
|
51430
|
-
/** Store a version once. `stored: false` = that id already exists (immutable). */
|
|
51431
|
-
putDatasetVersion: method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
|
|
51432
|
-
kind: "mutation",
|
|
51433
|
-
auth: "admin"
|
|
51434
|
-
}),
|
|
51435
|
-
getDatasetVersion: method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }),
|
|
51436
|
-
/** Every version without its frame list, newest first. */
|
|
51437
|
-
listDatasetVersions: method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }),
|
|
51438
|
-
findDatasetVersionIdByName: method(object({ name: string() }), object({ id: string().nullable() }), { auth: "admin" }),
|
|
51439
|
-
removeDatasetVersion: method(IdInput, object({ removed: boolean() }), {
|
|
51440
|
-
kind: "mutation",
|
|
51441
|
-
auth: "admin"
|
|
51442
|
-
}),
|
|
51443
51568
|
listBaseModels: method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }),
|
|
51444
51569
|
/** Split, estimate, defaults and any named refusal — nothing is started. */
|
|
51445
51570
|
planJob: method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
|
|
@@ -51468,6 +51593,32 @@ var trainingCapability = {
|
|
|
51468
51593
|
auth: "admin",
|
|
51469
51594
|
timeoutMs: 12e4
|
|
51470
51595
|
}),
|
|
51596
|
+
/**
|
|
51597
|
+
* Enqueue one job per base model (same selection, entry, caps). The first
|
|
51598
|
+
* becomes `uploading`; the rest stay `queued` until the prior job settles.
|
|
51599
|
+
* One ACTIVE job at a time — a parallel `startJob` still gets
|
|
51600
|
+
* `job-already-running`. The same `idempotencyKey` returns the batch it
|
|
51601
|
+
* already started.
|
|
51602
|
+
*/
|
|
51603
|
+
startJobBatch: method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
|
|
51604
|
+
baseModelIds: array(string().min(1)).min(1),
|
|
51605
|
+
name: string().min(1).max(120),
|
|
51606
|
+
maxCostUsd: number().positive(),
|
|
51607
|
+
maxRuntimeSec: number().int().positive(),
|
|
51608
|
+
idempotencyKey: string().min(8).max(80)
|
|
51609
|
+
}), discriminatedUnion("kind", [object({
|
|
51610
|
+
kind: literal("started"),
|
|
51611
|
+
batchId: string(),
|
|
51612
|
+
jobs: array(TrainingJobSchema).min(1).readonly()
|
|
51613
|
+
}), object({
|
|
51614
|
+
kind: literal("refused"),
|
|
51615
|
+
reason: TrainingRefusalReasonSchema,
|
|
51616
|
+
detail: string()
|
|
51617
|
+
})]), {
|
|
51618
|
+
kind: "mutation",
|
|
51619
|
+
auth: "admin",
|
|
51620
|
+
timeoutMs: 12e4
|
|
51621
|
+
}),
|
|
51471
51622
|
listJobs: method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }),
|
|
51472
51623
|
getJob: method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }),
|
|
51473
51624
|
cancelJob: method(IdInput, TrainingJobSchema, {
|
|
@@ -56826,12 +56977,6 @@ Object.freeze({
|
|
|
56826
56977
|
addonId: null,
|
|
56827
56978
|
access: "create"
|
|
56828
56979
|
},
|
|
56829
|
-
"pipelineAnalytics.createRetrainDatasetVersion": {
|
|
56830
|
-
capName: "pipeline-analytics",
|
|
56831
|
-
capScope: "device",
|
|
56832
|
-
addonId: null,
|
|
56833
|
-
access: "create"
|
|
56834
|
-
},
|
|
56835
56980
|
"pipelineAnalytics.deleteDeviceEvents": {
|
|
56836
56981
|
capName: "pipeline-analytics",
|
|
56837
56982
|
capScope: "device",
|
|
@@ -56844,12 +56989,6 @@ Object.freeze({
|
|
|
56844
56989
|
addonId: null,
|
|
56845
56990
|
access: "delete"
|
|
56846
56991
|
},
|
|
56847
|
-
"pipelineAnalytics.deleteRetrainDatasetVersion": {
|
|
56848
|
-
capName: "pipeline-analytics",
|
|
56849
|
-
capScope: "device",
|
|
56850
|
-
addonId: null,
|
|
56851
|
-
access: "delete"
|
|
56852
|
-
},
|
|
56853
56992
|
"pipelineAnalytics.deleteTracks": {
|
|
56854
56993
|
capName: "pipeline-analytics",
|
|
56855
56994
|
capScope: "device",
|
|
@@ -56952,6 +57091,12 @@ Object.freeze({
|
|
|
56952
57091
|
addonId: null,
|
|
56953
57092
|
access: "view"
|
|
56954
57093
|
},
|
|
57094
|
+
"pipelineAnalytics.getRetrainCorpusKpi": {
|
|
57095
|
+
capName: "pipeline-analytics",
|
|
57096
|
+
capScope: "device",
|
|
57097
|
+
addonId: null,
|
|
57098
|
+
access: "view"
|
|
57099
|
+
},
|
|
56955
57100
|
"pipelineAnalytics.getRetrainExportUrl": {
|
|
56956
57101
|
capName: "pipeline-analytics",
|
|
56957
57102
|
capScope: "device",
|
|
@@ -57072,7 +57217,7 @@ Object.freeze({
|
|
|
57072
57217
|
addonId: null,
|
|
57073
57218
|
access: "view"
|
|
57074
57219
|
},
|
|
57075
|
-
"pipelineAnalytics.
|
|
57220
|
+
"pipelineAnalytics.listRetrainCorpusPage": {
|
|
57076
57221
|
capName: "pipeline-analytics",
|
|
57077
57222
|
capScope: "device",
|
|
57078
57223
|
addonId: null,
|
|
@@ -57126,12 +57271,6 @@ Object.freeze({
|
|
|
57126
57271
|
addonId: null,
|
|
57127
57272
|
access: "create"
|
|
57128
57273
|
},
|
|
57129
|
-
"pipelineAnalytics.previewRetrainDataset": {
|
|
57130
|
-
capName: "pipeline-analytics",
|
|
57131
|
-
capScope: "device",
|
|
57132
|
-
addonId: null,
|
|
57133
|
-
access: "view"
|
|
57134
|
-
},
|
|
57135
57274
|
"pipelineAnalytics.proposeRetrainAnnotations": {
|
|
57136
57275
|
capName: "pipeline-analytics",
|
|
57137
57276
|
capScope: "device",
|
|
@@ -57210,6 +57349,12 @@ Object.freeze({
|
|
|
57210
57349
|
addonId: null,
|
|
57211
57350
|
access: "create"
|
|
57212
57351
|
},
|
|
57352
|
+
"pipelineAnalytics.resolveRetrainTrainingCorpus": {
|
|
57353
|
+
capName: "pipeline-analytics",
|
|
57354
|
+
capScope: "device",
|
|
57355
|
+
addonId: null,
|
|
57356
|
+
access: "view"
|
|
57357
|
+
},
|
|
57213
57358
|
"pipelineAnalytics.restageRetrainTrack": {
|
|
57214
57359
|
capName: "pipeline-analytics",
|
|
57215
57360
|
capScope: "device",
|
|
@@ -57270,12 +57415,6 @@ Object.freeze({
|
|
|
57270
57415
|
addonId: null,
|
|
57271
57416
|
access: "create"
|
|
57272
57417
|
},
|
|
57273
|
-
"pipelineAnalytics.verifyRetrainDatasetVersion": {
|
|
57274
|
-
capName: "pipeline-analytics",
|
|
57275
|
-
capScope: "device",
|
|
57276
|
-
addonId: null,
|
|
57277
|
-
access: "view"
|
|
57278
|
-
},
|
|
57279
57418
|
"pipelineAnalytics.wipeAllAnalytics": {
|
|
57280
57419
|
capName: "pipeline-analytics",
|
|
57281
57420
|
capScope: "device",
|
|
@@ -59670,18 +59809,6 @@ Object.freeze({
|
|
|
59670
59809
|
addonId: null,
|
|
59671
59810
|
access: "create"
|
|
59672
59811
|
},
|
|
59673
|
-
"training.findDatasetVersionIdByName": {
|
|
59674
|
-
capName: "training",
|
|
59675
|
-
capScope: "system",
|
|
59676
|
-
addonId: null,
|
|
59677
|
-
access: "view"
|
|
59678
|
-
},
|
|
59679
|
-
"training.getDatasetVersion": {
|
|
59680
|
-
capName: "training",
|
|
59681
|
-
capScope: "system",
|
|
59682
|
-
addonId: null,
|
|
59683
|
-
access: "view"
|
|
59684
|
-
},
|
|
59685
59812
|
"training.getJob": {
|
|
59686
59813
|
capName: "training",
|
|
59687
59814
|
capScope: "system",
|
|
@@ -59700,12 +59827,6 @@ Object.freeze({
|
|
|
59700
59827
|
addonId: null,
|
|
59701
59828
|
access: "view"
|
|
59702
59829
|
},
|
|
59703
|
-
"training.listDatasetVersions": {
|
|
59704
|
-
capName: "training",
|
|
59705
|
-
capScope: "system",
|
|
59706
|
-
addonId: null,
|
|
59707
|
-
access: "view"
|
|
59708
|
-
},
|
|
59709
59830
|
"training.listJobs": {
|
|
59710
59831
|
capName: "training",
|
|
59711
59832
|
capScope: "system",
|
|
@@ -59718,54 +59839,66 @@ Object.freeze({
|
|
|
59718
59839
|
addonId: null,
|
|
59719
59840
|
access: "view"
|
|
59720
59841
|
},
|
|
59721
|
-
"training.
|
|
59842
|
+
"training.registerResult": {
|
|
59722
59843
|
capName: "training",
|
|
59723
59844
|
capScope: "system",
|
|
59724
59845
|
addonId: null,
|
|
59725
59846
|
access: "create"
|
|
59726
59847
|
},
|
|
59727
|
-
"training.
|
|
59848
|
+
"training.rollbackCanary": {
|
|
59728
59849
|
capName: "training",
|
|
59729
59850
|
capScope: "system",
|
|
59730
59851
|
addonId: null,
|
|
59731
59852
|
access: "create"
|
|
59732
59853
|
},
|
|
59733
|
-
"training.
|
|
59854
|
+
"training.startJob": {
|
|
59734
59855
|
capName: "training",
|
|
59735
59856
|
capScope: "system",
|
|
59736
59857
|
addonId: null,
|
|
59737
|
-
access: "
|
|
59858
|
+
access: "create"
|
|
59738
59859
|
},
|
|
59739
|
-
"training.
|
|
59860
|
+
"training.startJobBatch": {
|
|
59740
59861
|
capName: "training",
|
|
59741
59862
|
capScope: "system",
|
|
59742
59863
|
addonId: null,
|
|
59743
59864
|
access: "create"
|
|
59744
59865
|
},
|
|
59745
|
-
"
|
|
59746
|
-
capName: "training",
|
|
59866
|
+
"trainingProvider.cancelJob": {
|
|
59867
|
+
capName: "training-provider",
|
|
59747
59868
|
capScope: "system",
|
|
59748
59869
|
addonId: null,
|
|
59749
59870
|
access: "create"
|
|
59750
59871
|
},
|
|
59751
|
-
"trainingProvider.
|
|
59872
|
+
"trainingProvider.cleanupJob": {
|
|
59752
59873
|
capName: "training-provider",
|
|
59753
59874
|
capScope: "system",
|
|
59754
59875
|
addonId: null,
|
|
59755
59876
|
access: "create"
|
|
59756
59877
|
},
|
|
59757
|
-
"trainingProvider.
|
|
59878
|
+
"trainingProvider.createEntry": {
|
|
59758
59879
|
capName: "training-provider",
|
|
59759
59880
|
capScope: "system",
|
|
59760
59881
|
addonId: null,
|
|
59761
59882
|
access: "create"
|
|
59762
59883
|
},
|
|
59884
|
+
"trainingProvider.deleteEntry": {
|
|
59885
|
+
capName: "training-provider",
|
|
59886
|
+
capScope: "system",
|
|
59887
|
+
addonId: null,
|
|
59888
|
+
access: "delete"
|
|
59889
|
+
},
|
|
59763
59890
|
"trainingProvider.describe": {
|
|
59764
59891
|
capName: "training-provider",
|
|
59765
59892
|
capScope: "system",
|
|
59766
59893
|
addonId: null,
|
|
59767
59894
|
access: "view"
|
|
59768
59895
|
},
|
|
59896
|
+
"trainingProvider.describeTypes": {
|
|
59897
|
+
capName: "training-provider",
|
|
59898
|
+
capScope: "system",
|
|
59899
|
+
addonId: null,
|
|
59900
|
+
access: "view"
|
|
59901
|
+
},
|
|
59769
59902
|
"trainingProvider.estimateJob": {
|
|
59770
59903
|
capName: "training-provider",
|
|
59771
59904
|
capScope: "system",
|
|
@@ -59778,6 +59911,12 @@ Object.freeze({
|
|
|
59778
59911
|
addonId: null,
|
|
59779
59912
|
access: "view"
|
|
59780
59913
|
},
|
|
59914
|
+
"trainingProvider.listEntries": {
|
|
59915
|
+
capName: "training-provider",
|
|
59916
|
+
capScope: "system",
|
|
59917
|
+
addonId: null,
|
|
59918
|
+
access: "view"
|
|
59919
|
+
},
|
|
59781
59920
|
"trainingProvider.listJobEvents": {
|
|
59782
59921
|
capName: "training-provider",
|
|
59783
59922
|
capScope: "system",
|
|
@@ -63414,6 +63553,11 @@ Object.freeze({
|
|
|
63414
63553
|
form: "array",
|
|
63415
63554
|
optional: false
|
|
63416
63555
|
}],
|
|
63556
|
+
"pipelineAnalytics.listRetrainCorpusPage": [{
|
|
63557
|
+
name: "deviceIds",
|
|
63558
|
+
form: "array",
|
|
63559
|
+
optional: true
|
|
63560
|
+
}],
|
|
63417
63561
|
"pipelineAnalytics.listRetrainStaging": [{
|
|
63418
63562
|
name: "deviceIds",
|
|
63419
63563
|
form: "array",
|