@camstack/addon-model-studio 1.1.216 → 1.1.218
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/{MotionZonesSettings-4HEAfNAZ.mjs → MotionZonesSettings-Capre9Um.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-CyrRi4XA.mjs → PrivacyMaskSettings-CTeuaW76.mjs} +4 -4
- package/dist/{SceneMonitorEditor-CprmQzlB.mjs → SceneMonitorEditor-B_wS3Aqg.mjs} +3 -3
- package/dist/_stub.js +2956 -2959
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DuZ4j4Tj.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-WTUyarUL.mjs} +4 -4
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CE6l15x5.mjs +26 -0
- package/dist/{hostInit-DgQAw-Tm.mjs → hostInit-N-aNmJfG.mjs} +3 -3
- package/dist/model-studio.addon.js +266 -10
- package/dist/model-studio.addon.mjs +266 -10
- package/dist/{player-overlays-2W0Mwbzt.mjs → player-overlays-CYNFSDYV.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-B69r95CT.mjs → responsive-oZzHP3lx.mjs} +1 -1
- package/dist/{scene-monitor-copy-CeTU5shK.mjs → scene-monitor-copy-C2YKn7wo.mjs} +1 -1
- package/dist/{square-Sw6O7lEO.mjs → square-DUBjO0Wq.mjs} +1 -1
- package/dist/{trash-2-Bess9rqf.mjs → trash-2-DpaexsRt.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BTcms_55.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BA6FOYZy.mjs} +1 -1
- package/package.json +1 -1
- package/python/__tests__/test_calibration.py +56 -0
- package/python/convert_lib.py +45 -16
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CQ2lOvCS.mjs +0 -26
|
@@ -5738,7 +5738,7 @@ var ZodIssueCode = {
|
|
|
5738
5738
|
var ZodFirstPartyTypeKind;
|
|
5739
5739
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5740
5740
|
//#endregion
|
|
5741
|
-
//#region ../types/dist/sleep-
|
|
5741
|
+
//#region ../types/dist/sleep-B0JG7-_F.mjs
|
|
5742
5742
|
/**
|
|
5743
5743
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5744
5744
|
* window to float samples (D455).
|
|
@@ -15396,6 +15396,10 @@ var DeviceInfoSchema = object({
|
|
|
15396
15396
|
isCamera: boolean(),
|
|
15397
15397
|
/** Current config values — serializable snapshot */
|
|
15398
15398
|
config: record(string(), unknown()),
|
|
15399
|
+
/** Paths inside `config` the device's schema declares secret (D783) —
|
|
15400
|
+
* what the non-admin redaction withholds. Paths, never values. Absent
|
|
15401
|
+
* when the owning runner has not reported them. */
|
|
15402
|
+
secretConfigPaths: array(string()).optional(),
|
|
15399
15403
|
/** Hardware + identity blob (manufacturer / model / firmware / sn /
|
|
15400
15404
|
* uid / mac / …). Populated by drivers; editable via setMetadata. */
|
|
15401
15405
|
metadata: record(string(), unknown()).nullable().optional(),
|
|
@@ -15601,7 +15605,13 @@ var DeviceRegisterPayloadSchema = object({
|
|
|
15601
15605
|
* call (workers re-register on init), so probe-driven updates
|
|
15602
15606
|
* (e.g. PTZ flag flipping after the abilities probe) propagate. */
|
|
15603
15607
|
features: array(string()).optional(),
|
|
15604
|
-
config: record(string(), unknown())
|
|
15608
|
+
config: record(string(), unknown()),
|
|
15609
|
+
/** Config paths the device's own schema DECLARES secret
|
|
15610
|
+
* (`.meta({ secret: true })` — dotted, `[]` for array items, e.g.
|
|
15611
|
+
* `connection.password`). Re-published on every register; the non-admin
|
|
15612
|
+
* redaction withholds them at any depth (D783). Optional: an older runner
|
|
15613
|
+
* omits it and the keyword backstop applies. */
|
|
15614
|
+
secretConfigPaths: array(string()).optional()
|
|
15605
15615
|
});
|
|
15606
15616
|
var DeviceRemovePayloadSchema = object({ deviceId: number() });
|
|
15607
15617
|
var DevicePersistConfigPayloadSchema = object({
|
|
@@ -17260,7 +17270,14 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
17260
17270
|
icon: string().optional(),
|
|
17261
17271
|
/** Addon-owned HTTP route the button navigates to (GET). */
|
|
17262
17272
|
startUrl: string(),
|
|
17263
|
-
stage: LoginStageEnum
|
|
17273
|
+
stage: LoginStageEnum,
|
|
17274
|
+
/**
|
|
17275
|
+
* The provider names an external identity a signed-in user can link to
|
|
17276
|
+
* their own account (D782): `auth.listLinkableProviders` /
|
|
17277
|
+
* `beginExternalLink` offer exactly the redirect methods that set this,
|
|
17278
|
+
* whatever their id. Absent / false — a login button only (magic-link).
|
|
17279
|
+
*/
|
|
17280
|
+
linkable: boolean().optional()
|
|
17264
17281
|
}),
|
|
17265
17282
|
object({
|
|
17266
17283
|
kind: literal("widget"),
|
|
@@ -22663,7 +22680,13 @@ var RetrainFrameSchema = object({
|
|
|
22663
22680
|
sizeBytes: number().int(),
|
|
22664
22681
|
width: number().int(),
|
|
22665
22682
|
height: number().int(),
|
|
22666
|
-
copiedAt: number()
|
|
22683
|
+
copiedAt: number(),
|
|
22684
|
+
/** When the CAMERA captured the frame. Absent on a copy taken before D785. */
|
|
22685
|
+
capturedAt: number().optional(),
|
|
22686
|
+
/** The operator's "every subject in this frame is boxed". Detector
|
|
22687
|
+
* evaluation keeps only complete frames: an unboxed subject would count as
|
|
22688
|
+
* a false positive. */
|
|
22689
|
+
complete: boolean()
|
|
22667
22690
|
});
|
|
22668
22691
|
/** Why a copy-on-select could not be honoured — named, never a silent skip. */
|
|
22669
22692
|
var RetrainCopyRefusalSchema = _enum([
|
|
@@ -22684,6 +22707,51 @@ var RetrainFrameListSchema = object({
|
|
|
22684
22707
|
/** What the page pre-selects — the native key frame when one survives. */
|
|
22685
22708
|
autoPickMediaId: number().int().optional()
|
|
22686
22709
|
});
|
|
22710
|
+
/**
|
|
22711
|
+
* Which frames an annotated export carries. Every field narrows; an empty
|
|
22712
|
+
* filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
|
|
22713
|
+
* list owned by whoever trains (the training orchestrator), so `frameIds` is
|
|
22714
|
+
* the primitive a version export uses; `batchId` re-selects what an earlier
|
|
22715
|
+
* export carried (`exportedInBatch`).
|
|
22716
|
+
*/
|
|
22717
|
+
var RetrainExportFilterSchema = object({
|
|
22718
|
+
deviceIds: array(number()).optional(),
|
|
22719
|
+
frameIds: array(string()).max(2e4).optional(),
|
|
22720
|
+
batchId: string().optional(),
|
|
22721
|
+
/** Only frames the operator marked complete (all subjects boxed). */
|
|
22722
|
+
completeOnly: boolean().optional()
|
|
22723
|
+
});
|
|
22724
|
+
/**
|
|
22725
|
+
* `frames`: the full frame copies, boxes in `annotations.json`.
|
|
22726
|
+
* `crops`: additionally one JPEG per subject, cut with the runtime detail-crop
|
|
22727
|
+
* convention — the classifier layout.
|
|
22728
|
+
*/
|
|
22729
|
+
var RetrainExportLayoutSchema = _enum(["frames", "crops"]);
|
|
22730
|
+
/**
|
|
22731
|
+
* Where `writeRetrainArchive` streams the tar: one HTTP request whose body is
|
|
22732
|
+
* the archive, sent chunk by chunk. Covers a presigned PUT and a provider
|
|
22733
|
+
* addon's data-plane upload route alike. Headers are sent verbatim and never
|
|
22734
|
+
* logged.
|
|
22735
|
+
*/
|
|
22736
|
+
var RetrainArchiveTargetSchema = object({
|
|
22737
|
+
kind: literal("http"),
|
|
22738
|
+
method: _enum(["PUT", "POST"]),
|
|
22739
|
+
url: string().url(),
|
|
22740
|
+
headers: record(string(), string()).optional()
|
|
22741
|
+
});
|
|
22742
|
+
var RetrainArchiveResultSchema = object({
|
|
22743
|
+
batchId: string(),
|
|
22744
|
+
frames: number().int(),
|
|
22745
|
+
crops: number().int(),
|
|
22746
|
+
annotations: number().int(),
|
|
22747
|
+
/** Frames planned but not shipped (unreadable copy, path too long). */
|
|
22748
|
+
missing: number().int(),
|
|
22749
|
+
bytes: number().int(),
|
|
22750
|
+
/** sha256 of the exact bytes sent. */
|
|
22751
|
+
sha256: string(),
|
|
22752
|
+
/** The target's HTTP status. */
|
|
22753
|
+
status: number().int()
|
|
22754
|
+
});
|
|
22687
22755
|
/** What the operator asked the assist to look for. */
|
|
22688
22756
|
var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
|
|
22689
22757
|
kind: literal("package"),
|
|
@@ -23478,9 +23546,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
23478
23546
|
}), RetrainTransitionResultSchema, {
|
|
23479
23547
|
kind: "mutation",
|
|
23480
23548
|
auth: "admin"
|
|
23481
|
-
}), method(
|
|
23549
|
+
}), method(RetrainExportFilterSchema.extend({ layout: RetrainExportLayoutSchema.optional() }), object({ url: string() }), {
|
|
23482
23550
|
kind: "query",
|
|
23483
23551
|
auth: "admin"
|
|
23552
|
+
}), method(object({
|
|
23553
|
+
deviceId: number(),
|
|
23554
|
+
trackId: string(),
|
|
23555
|
+
frameId: string(),
|
|
23556
|
+
complete: boolean()
|
|
23557
|
+
}), RetrainFrameSchema, {
|
|
23558
|
+
kind: "mutation",
|
|
23559
|
+
auth: "admin"
|
|
23560
|
+
}), method(object({
|
|
23561
|
+
filter: RetrainExportFilterSchema,
|
|
23562
|
+
layout: RetrainExportLayoutSchema,
|
|
23563
|
+
target: RetrainArchiveTargetSchema
|
|
23564
|
+
}), RetrainArchiveResultSchema, {
|
|
23565
|
+
kind: "mutation",
|
|
23566
|
+
auth: "admin",
|
|
23567
|
+
timeoutMs: 60 * 6e4
|
|
23484
23568
|
}), method(object({
|
|
23485
23569
|
/** Which of the three event tables owns the row. */
|
|
23486
23570
|
ownerType: EventOwnerTypeSchema,
|
|
@@ -26770,7 +26854,19 @@ var SsoBridgeClaimsSchema = object({
|
|
|
26770
26854
|
* editing a descriptor must not retroactively extend or shorten a link the
|
|
26771
26855
|
* operator already consented to.
|
|
26772
26856
|
*/
|
|
26773
|
-
refreshTtl: union([number().int().positive(), literal("never")]).optional()
|
|
26857
|
+
refreshTtl: union([number().int().positive(), literal("never")]).optional(),
|
|
26858
|
+
/**
|
|
26859
|
+
* Opaque handle of a hub-side LINK intent (D782). Set by an OIDC callback
|
|
26860
|
+
* that was started from a signed-in user's "Link" button: the finish then
|
|
26861
|
+
* links this identity to the intent's user instead of signing anyone in.
|
|
26862
|
+
* The handle carries no user id — the hub resolves it, single-use.
|
|
26863
|
+
*/
|
|
26864
|
+
linkIntent: string().optional(),
|
|
26865
|
+
/**
|
|
26866
|
+
* Verified `iss` of the id_token behind an OIDC login bridge (D782). A
|
|
26867
|
+
* subject is unique only per issuer, so a link is bound to it.
|
|
26868
|
+
*/
|
|
26869
|
+
issuer: string().optional()
|
|
26774
26870
|
});
|
|
26775
26871
|
method(object({
|
|
26776
26872
|
claims: SsoBridgeClaimsSchema,
|
|
@@ -28676,7 +28772,22 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
|
|
|
28676
28772
|
* field their hints were silently stripped by the schema and the
|
|
28677
28773
|
* adaptive ladder started blind on the client's display size.
|
|
28678
28774
|
*/
|
|
28679
|
-
hints: webrtcClientHintsSchema.optional()
|
|
28775
|
+
hints: webrtcClientHintsSchema.optional(),
|
|
28776
|
+
/**
|
|
28777
|
+
* Talk-back (D771): relay the PEER's audio to the device's speaker
|
|
28778
|
+
* through the `intercom` cap's push-talk triple. When `true` and the
|
|
28779
|
+
* offer lets the peer send audio, the answer's audio is `sendrecv`
|
|
28780
|
+
* and every inbound frame goes to `intercom.pushTalkAudio` for this
|
|
28781
|
+
* `deviceId`; absent/false answers `sendonly`, as for every viewer.
|
|
28782
|
+
*
|
|
28783
|
+
* TRUSTED-CALLER ONLY. Set by the Alexa export for an Echo on a camera
|
|
28784
|
+
* with `intercom`, when the linked user may control that camera. The
|
|
28785
|
+
* hub STRIPS it from every request-bound call (a browser), exactly as
|
|
28786
|
+
* it overwrites `relayOnly` — a viewer's talk permission is the
|
|
28787
|
+
* intercom cap's own surface (share tokens gate it there), and this
|
|
28788
|
+
* flag must not become a second door to the camera's speaker.
|
|
28789
|
+
*/
|
|
28790
|
+
talkback: boolean().optional()
|
|
28680
28791
|
}), object({
|
|
28681
28792
|
sessionId: string(),
|
|
28682
28793
|
sdpAnswer: string()
|
|
@@ -28978,6 +29089,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
28978
29089
|
var RestartAddonResultSchema = unknown();
|
|
28979
29090
|
var InstallPackageResultSchema = unknown();
|
|
28980
29091
|
var ReloadPackagesResultSchema = unknown();
|
|
29092
|
+
/**
|
|
29093
|
+
* What an uninstall did on ONE node.
|
|
29094
|
+
* - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
|
|
29095
|
+
* - `not-installed` — the node did not have it (nothing to do).
|
|
29096
|
+
* - `refused` — protected / bootstrap package; nothing touched.
|
|
29097
|
+
* - `failed` — attempted and did not complete; `error` says why.
|
|
29098
|
+
* - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
|
|
29099
|
+
* back-fill never returns the package, and the stale-addon sweep removes the
|
|
29100
|
+
* copy when the node registers again (only once the hub no longer has it).
|
|
29101
|
+
*/
|
|
29102
|
+
var UninstallNodeOutcomeSchema = _enum([
|
|
29103
|
+
"uninstalled",
|
|
29104
|
+
"not-installed",
|
|
29105
|
+
"refused",
|
|
29106
|
+
"failed",
|
|
29107
|
+
"pending-reconnect"
|
|
29108
|
+
]);
|
|
29109
|
+
var UninstallNodeResultSchema = object({
|
|
29110
|
+
nodeId: string(),
|
|
29111
|
+
outcome: UninstallNodeOutcomeSchema,
|
|
29112
|
+
error: string().optional(),
|
|
29113
|
+
addonIds: array(string()).readonly(),
|
|
29114
|
+
runnersStopped: array(string()).readonly(),
|
|
29115
|
+
warnings: array(string()).readonly()
|
|
29116
|
+
});
|
|
29117
|
+
var UninstallPackageResultSchema = object({
|
|
29118
|
+
/** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
|
|
29119
|
+
success: boolean(),
|
|
29120
|
+
packageName: string(),
|
|
29121
|
+
results: array(UninstallNodeResultSchema).readonly()
|
|
29122
|
+
});
|
|
29123
|
+
/**
|
|
29124
|
+
* `unreachable` lists online agents whose status read FAILED — absence from
|
|
29125
|
+
* `installations` is only "not installed" for a node that answered (D315).
|
|
29126
|
+
*/
|
|
29127
|
+
var PackageInstallationsSchema = object({
|
|
29128
|
+
installations: array(object({
|
|
29129
|
+
packageName: string(),
|
|
29130
|
+
nodeId: string(),
|
|
29131
|
+
nodeName: string(),
|
|
29132
|
+
isHub: boolean(),
|
|
29133
|
+
isOnline: boolean(),
|
|
29134
|
+
version: string().nullable(),
|
|
29135
|
+
addonIds: array(string()).readonly(),
|
|
29136
|
+
source: _enum(["live", "recorded"]),
|
|
29137
|
+
/** The hub installs this package too. `false` on an agent row = an orphan. */
|
|
29138
|
+
onHub: boolean()
|
|
29139
|
+
})).readonly(),
|
|
29140
|
+
unreachable: array(object({
|
|
29141
|
+
nodeId: string(),
|
|
29142
|
+
error: string()
|
|
29143
|
+
})).readonly()
|
|
29144
|
+
});
|
|
28981
29145
|
var BulkUpdateItemStatusSchema = _enum([
|
|
28982
29146
|
"queued",
|
|
28983
29147
|
"updating",
|
|
@@ -29060,10 +29224,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
29060
29224
|
}), method(object({ packageName: string() }), InstallPackageResultSchema, {
|
|
29061
29225
|
kind: "mutation",
|
|
29062
29226
|
auth: "admin"
|
|
29063
|
-
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
29227
|
+
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
29228
|
+
packageName: string().min(1),
|
|
29229
|
+
nodeId: string().optional(),
|
|
29230
|
+
everywhere: boolean().optional()
|
|
29231
|
+
}), UninstallPackageResultSchema, {
|
|
29064
29232
|
kind: "mutation",
|
|
29065
29233
|
auth: "admin"
|
|
29066
|
-
}), method(_void(), ReloadPackagesResultSchema, {
|
|
29234
|
+
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
29067
29235
|
kind: "mutation",
|
|
29068
29236
|
auth: "admin"
|
|
29069
29237
|
}), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
@@ -36663,6 +36831,32 @@ var TotpStatusSchema = object({
|
|
|
36663
36831
|
/** Null when no row exists OR the row is still pending confirmation. */
|
|
36664
36832
|
confirmedAt: number().nullable()
|
|
36665
36833
|
});
|
|
36834
|
+
/**
|
|
36835
|
+
* user-management — singleton capability for user accounts, API keys,
|
|
36836
|
+
* and scoped tokens.
|
|
36837
|
+
*
|
|
36838
|
+
* v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
|
|
36839
|
+
* — the subset check on `setUserScopes` / `createScopedToken` is moot
|
|
36840
|
+
* because non-admins never reach these. If/when we open non-admin
|
|
36841
|
+
* delegation, structural caller-scope subset check goes inside the
|
|
36842
|
+
* provider.
|
|
36843
|
+
*/
|
|
36844
|
+
var ExternalIdentitySchema = object({
|
|
36845
|
+
/** Login-method id of the provider instance, e.g. `auth-oidc/authentik`. */
|
|
36846
|
+
provider: string(),
|
|
36847
|
+
/** The IdP's stable subject (`sub`) for this account. */
|
|
36848
|
+
subject: string(),
|
|
36849
|
+
/** The verified `iss` of the IdP the identity was linked under — `sub` is unique only per issuer. */
|
|
36850
|
+
issuer: string(),
|
|
36851
|
+
userId: string(),
|
|
36852
|
+
/** What the IdP called the account at link time (username / email) — display only. */
|
|
36853
|
+
label: string().optional(),
|
|
36854
|
+
linkedAt: number()
|
|
36855
|
+
});
|
|
36856
|
+
var ExternalIdentityKeySchema = object({
|
|
36857
|
+
provider: string().min(1),
|
|
36858
|
+
subject: string().min(1)
|
|
36859
|
+
});
|
|
36666
36860
|
method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
|
|
36667
36861
|
kind: "mutation",
|
|
36668
36862
|
auth: "admin",
|
|
@@ -36776,7 +36970,22 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
|
|
|
36776
36970
|
userId: string(),
|
|
36777
36971
|
username: string(),
|
|
36778
36972
|
scopes: array(TokenScopeSchema)
|
|
36779
|
-
}).nullable(), { access: "view" }), method(
|
|
36973
|
+
}).nullable(), { access: "view" }), method(object({ userId: string() }), array(ExternalIdentitySchema), { auth: "admin" }), method(ExternalIdentityKeySchema, object({
|
|
36974
|
+
userId: string(),
|
|
36975
|
+
issuer: string()
|
|
36976
|
+
}).nullable(), { auth: "admin" }), method(ExternalIdentityKeySchema.extend({
|
|
36977
|
+
userId: string(),
|
|
36978
|
+
issuer: string().min(1),
|
|
36979
|
+
label: string().optional()
|
|
36980
|
+
}), object({ success: literal(true) }), {
|
|
36981
|
+
kind: "mutation",
|
|
36982
|
+
auth: "admin",
|
|
36983
|
+
access: "create"
|
|
36984
|
+
}), method(ExternalIdentityKeySchema.extend({ userId: string() }), object({ success: boolean() }), {
|
|
36985
|
+
kind: "mutation",
|
|
36986
|
+
auth: "admin",
|
|
36987
|
+
access: "delete"
|
|
36988
|
+
}), method(_void(), array(OauthSessionSummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: boolean() }), {
|
|
36780
36989
|
kind: "mutation",
|
|
36781
36990
|
auth: "admin",
|
|
36782
36991
|
access: "delete"
|
|
@@ -37450,6 +37659,12 @@ Object.freeze({
|
|
|
37450
37659
|
addonId: null,
|
|
37451
37660
|
access: "view"
|
|
37452
37661
|
},
|
|
37662
|
+
"addons.listInstallations": {
|
|
37663
|
+
capName: "addons",
|
|
37664
|
+
capScope: "system",
|
|
37665
|
+
addonId: null,
|
|
37666
|
+
access: "view"
|
|
37667
|
+
},
|
|
37453
37668
|
"addons.listJobs": {
|
|
37454
37669
|
capName: "addons",
|
|
37455
37670
|
capScope: "system",
|
|
@@ -41674,6 +41889,12 @@ Object.freeze({
|
|
|
41674
41889
|
addonId: null,
|
|
41675
41890
|
access: "create"
|
|
41676
41891
|
},
|
|
41892
|
+
"pipelineAnalytics.setRetrainFrameComplete": {
|
|
41893
|
+
capName: "pipeline-analytics",
|
|
41894
|
+
capScope: "device",
|
|
41895
|
+
addonId: null,
|
|
41896
|
+
access: "create"
|
|
41897
|
+
},
|
|
41677
41898
|
"pipelineAnalytics.setTrackFlags": {
|
|
41678
41899
|
capName: "pipeline-analytics",
|
|
41679
41900
|
capScope: "device",
|
|
@@ -41710,6 +41931,12 @@ Object.freeze({
|
|
|
41710
41931
|
addonId: null,
|
|
41711
41932
|
access: "delete"
|
|
41712
41933
|
},
|
|
41934
|
+
"pipelineAnalytics.writeRetrainArchive": {
|
|
41935
|
+
capName: "pipeline-analytics",
|
|
41936
|
+
capScope: "device",
|
|
41937
|
+
addonId: null,
|
|
41938
|
+
access: "create"
|
|
41939
|
+
},
|
|
41713
41940
|
"pipelineExecutor.cacheFrameInPool": {
|
|
41714
41941
|
capName: "pipeline-executor",
|
|
41715
41942
|
capScope: "system",
|
|
@@ -44062,18 +44289,36 @@ Object.freeze({
|
|
|
44062
44289
|
addonId: null,
|
|
44063
44290
|
access: "delete"
|
|
44064
44291
|
},
|
|
44292
|
+
"userManagement.findUserByExternalIdentity": {
|
|
44293
|
+
capName: "user-management",
|
|
44294
|
+
capScope: "system",
|
|
44295
|
+
addonId: null,
|
|
44296
|
+
access: "view"
|
|
44297
|
+
},
|
|
44065
44298
|
"userManagement.getTotpStatus": {
|
|
44066
44299
|
capName: "user-management",
|
|
44067
44300
|
capScope: "system",
|
|
44068
44301
|
addonId: null,
|
|
44069
44302
|
access: "view"
|
|
44070
44303
|
},
|
|
44304
|
+
"userManagement.linkExternalIdentity": {
|
|
44305
|
+
capName: "user-management",
|
|
44306
|
+
capScope: "system",
|
|
44307
|
+
addonId: null,
|
|
44308
|
+
access: "create"
|
|
44309
|
+
},
|
|
44071
44310
|
"userManagement.listApiKeys": {
|
|
44072
44311
|
capName: "user-management",
|
|
44073
44312
|
capScope: "system",
|
|
44074
44313
|
addonId: null,
|
|
44075
44314
|
access: "view"
|
|
44076
44315
|
},
|
|
44316
|
+
"userManagement.listExternalIdentities": {
|
|
44317
|
+
capName: "user-management",
|
|
44318
|
+
capScope: "system",
|
|
44319
|
+
addonId: null,
|
|
44320
|
+
access: "view"
|
|
44321
|
+
},
|
|
44077
44322
|
"userManagement.listOauthSessions": {
|
|
44078
44323
|
capName: "user-management",
|
|
44079
44324
|
capScope: "system",
|
|
@@ -44152,6 +44397,12 @@ Object.freeze({
|
|
|
44152
44397
|
addonId: null,
|
|
44153
44398
|
access: "create"
|
|
44154
44399
|
},
|
|
44400
|
+
"userManagement.unlinkExternalIdentity": {
|
|
44401
|
+
capName: "user-management",
|
|
44402
|
+
capScope: "system",
|
|
44403
|
+
addonId: null,
|
|
44404
|
+
access: "delete"
|
|
44405
|
+
},
|
|
44155
44406
|
"userManagement.updateUser": {
|
|
44156
44407
|
capName: "user-management",
|
|
44157
44408
|
capScope: "system",
|
|
@@ -47491,6 +47742,11 @@ Object.freeze({
|
|
|
47491
47742
|
form: "single",
|
|
47492
47743
|
optional: false
|
|
47493
47744
|
}],
|
|
47745
|
+
"pipelineAnalytics.setRetrainFrameComplete": [{
|
|
47746
|
+
name: "deviceId",
|
|
47747
|
+
form: "single",
|
|
47748
|
+
optional: false
|
|
47749
|
+
}],
|
|
47494
47750
|
"pipelineAnalytics.setTrackFlags": [{
|
|
47495
47751
|
name: "deviceId",
|
|
47496
47752
|
form: "single",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { b as e, g as t, l as n, u as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-CHL8loOl.mjs";
|
|
2
|
-
import { b as i, y as a } from "./responsive-
|
|
2
|
+
import { b as i, y as a } from "./responsive-oZzHP3lx.mjs";
|
|
3
3
|
import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
|
|
4
4
|
var l = i("chevron-down", [["path", {
|
|
5
5
|
d: "m6 9 6 6 6-6",
|
package/dist/remoteEntry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-
|
|
1
|
+
import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BA6FOYZy.mjs";
|
|
2
2
|
export { t as get, e as init };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as e, b as t, c as n, g as r, l as i, m as a, n as o, r as s, t as c, u as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-CHL8loOl.mjs";
|
|
2
2
|
import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
|
|
3
|
-
import { f as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-
|
|
3
|
+
import { f as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CE6l15x5.mjs";
|
|
4
4
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
|
|
5
5
|
t();
|
|
6
6
|
var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { b as e, c as t, g as n, m as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-CHL8loOl.mjs";
|
|
2
|
-
import { b as i } from "./responsive-
|
|
2
|
+
import { b as i } from "./responsive-oZzHP3lx.mjs";
|
|
3
3
|
var a = i("camera", [["path", {
|
|
4
4
|
d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
|
|
5
5
|
key: "18u6gg"
|
|
@@ -2753,7 +2753,7 @@ async function rr(e) {
|
|
|
2753
2753
|
}
|
|
2754
2754
|
}
|
|
2755
2755
|
async function ir() {
|
|
2756
|
-
return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-
|
|
2756
|
+
return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-WTUyarUL.mjs")).catch((e) => {
|
|
2757
2757
|
throw tr = void 0, e;
|
|
2758
2758
|
}), tr;
|
|
2759
2759
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""INT8 calibration inputs (cloud-training P6): which images, and how they are
|
|
2
|
+
fed. Calibration must see frames the way the runtime feeds the model — the
|
|
3
|
+
inference pool's letterbox is CENTRED (pad = (size - new) // 2, grey 114) —
|
|
4
|
+
and must be able to use the operator's own frames, i.e. the hub's annotated
|
|
5
|
+
export, whose frames sit in nested folders next to `annotations.json`."""
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
cv2 = pytest.importorskip("cv2")
|
|
10
|
+
|
|
11
|
+
from convert_lib import calibration_images, letterbox_for_calibration # noqa: E402
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _touch(path, data=b"x"):
|
|
15
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
path.write_bytes(data)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_a_flat_folder_is_read_in_file_name_order(tmp_path):
|
|
20
|
+
for name in ("b.jpg", "a.jpg", "c.png", "notes.txt"):
|
|
21
|
+
_touch(tmp_path / name)
|
|
22
|
+
assert [p.name for p in calibration_images(str(tmp_path), 10)] == ["a.jpg", "b.jpg", "c.png"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_the_sample_count_is_a_cap(tmp_path):
|
|
26
|
+
for i in range(5):
|
|
27
|
+
_touch(tmp_path / f"{i}.jpg")
|
|
28
|
+
assert len(calibration_images(str(tmp_path), 3)) == 3
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_an_export_directory_calibrates_on_its_frames_only(tmp_path):
|
|
32
|
+
_touch(tmp_path / "annotations.json", b"{}")
|
|
33
|
+
_touch(tmp_path / "frames" / "615" / "t1" / "a.jpg")
|
|
34
|
+
_touch(tmp_path / "frames" / "617" / "t2" / "b.jpg")
|
|
35
|
+
_touch(tmp_path / "crops" / "person" / "x.jpg")
|
|
36
|
+
names = [p.relative_to(tmp_path).as_posix() for p in calibration_images(str(tmp_path), 10)]
|
|
37
|
+
assert names == ["frames/615/t1/a.jpg", "frames/617/t2/b.jpg"]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_an_empty_folder_is_refused(tmp_path):
|
|
41
|
+
with pytest.raises(ValueError):
|
|
42
|
+
calibration_images(str(tmp_path), 10)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_the_letterbox_is_centred_like_the_runtime():
|
|
46
|
+
rgb = np.full((100, 200, 3), 255, dtype=np.uint8) # 2:1 white frame
|
|
47
|
+
out = letterbox_for_calibration(rgb, 64)
|
|
48
|
+
assert out.shape == (1, 3, 64, 64)
|
|
49
|
+
assert out.dtype == np.float32
|
|
50
|
+
# Content 64x32, centred: grey rows 0..15 and 48..63, white in between.
|
|
51
|
+
column = out[0, 0, :, 32]
|
|
52
|
+
assert column[0] == pytest.approx(114 / 255)
|
|
53
|
+
assert column[63] == pytest.approx(114 / 255)
|
|
54
|
+
assert column[32] == pytest.approx(1.0)
|
|
55
|
+
assert column[15] == pytest.approx(114 / 255)
|
|
56
|
+
assert column[16] == pytest.approx(1.0)
|
package/python/convert_lib.py
CHANGED
|
@@ -64,32 +64,61 @@ def validate_openvino_ir(xml_path: str) -> None:
|
|
|
64
64
|
raise ValueError(f"IR {xml_path} has an empty-named tensor")
|
|
65
65
|
|
|
66
66
|
|
|
67
|
+
CALIBRATION_SUFFIXES = {".jpg", ".jpeg", ".png"}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def calibration_images(calib_dir: str, max_samples: int) -> "list[Path]":
|
|
71
|
+
"""The first ``max_samples`` calibration images of ``calib_dir``, in path order.
|
|
72
|
+
|
|
73
|
+
A flat folder (COCO val2017) is read exactly as before: file-name order. A
|
|
74
|
+
folder is walked recursively, so the operator's own frames work as they
|
|
75
|
+
come. The hub's annotated export (a folder holding ``annotations.json``)
|
|
76
|
+
calibrates on its ``frames/`` only: its ``crops/`` are classifier inputs,
|
|
77
|
+
not what a root detector is fed.
|
|
78
|
+
"""
|
|
79
|
+
root = Path(calib_dir)
|
|
80
|
+
if not root.is_dir():
|
|
81
|
+
raise ValueError(f"calibration folder {calib_dir} does not exist")
|
|
82
|
+
base = root / "frames" if (root / "annotations.json").is_file() else root
|
|
83
|
+
images = sorted(
|
|
84
|
+
(p for p in base.rglob("*") if p.is_file() and p.suffix.lower() in CALIBRATION_SUFFIXES),
|
|
85
|
+
key=lambda p: p.relative_to(base).as_posix(),
|
|
86
|
+
)[:max_samples]
|
|
87
|
+
if not images:
|
|
88
|
+
raise ValueError(f"no calibration images in {calib_dir}")
|
|
89
|
+
return images
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def letterbox_for_calibration(rgb, imgsz: int):
|
|
93
|
+
"""``rgb`` (HxWx3 uint8) → ``[1,3,imgsz,imgsz]`` float32 in [0,1], letterboxed
|
|
94
|
+
as the inference pool does (``inference_pool.letterbox_image``): scale by the
|
|
95
|
+
long side, truncate, CENTRE with grey 114 padding."""
|
|
96
|
+
import cv2
|
|
97
|
+
import numpy as np
|
|
98
|
+
|
|
99
|
+
h, w = rgb.shape[:2]
|
|
100
|
+
scale = imgsz / max(h, w)
|
|
101
|
+
nw, nh = int(w * scale), int(h * scale)
|
|
102
|
+
pad_x, pad_y = (imgsz - nw) // 2, (imgsz - nh) // 2
|
|
103
|
+
resized = rgb if (nw, nh) == (w, h) else cv2.resize(rgb, (nw, nh), interpolation=cv2.INTER_LINEAR)
|
|
104
|
+
canvas = np.full((imgsz, imgsz, 3), 114, dtype=np.uint8)
|
|
105
|
+
canvas[pad_y : pad_y + nh, pad_x : pad_x + nw] = resized
|
|
106
|
+
chw = canvas.transpose(2, 0, 1).astype(np.float32) / 255.0
|
|
107
|
+
return chw[np.newaxis, ...]
|
|
108
|
+
|
|
109
|
+
|
|
67
110
|
def quantize_openvino_int8(
|
|
68
111
|
onnx_path: str, out_xml: str, calib_dir: str, imgsz: int, max_samples: int = 300
|
|
69
112
|
) -> None:
|
|
70
113
|
import cv2
|
|
71
|
-
import numpy as np
|
|
72
114
|
import openvino as ov
|
|
73
115
|
import nncf
|
|
74
116
|
|
|
75
|
-
|
|
76
|
-
images = sorted(
|
|
77
|
-
p for p in calib.iterdir() if p.suffix.lower() in {".jpg", ".jpeg", ".png"}
|
|
78
|
-
)[:max_samples]
|
|
79
|
-
if not images:
|
|
80
|
-
raise ValueError(f"no calibration images in {calib_dir}")
|
|
117
|
+
images = calibration_images(calib_dir, max_samples)
|
|
81
118
|
|
|
82
119
|
def preprocess(path: Path):
|
|
83
120
|
img = cv2.imread(str(path))
|
|
84
|
-
|
|
85
|
-
h, w = img.shape[:2]
|
|
86
|
-
scale = imgsz / max(h, w)
|
|
87
|
-
nh, nw = int(round(h * scale)), int(round(w * scale))
|
|
88
|
-
resized = cv2.resize(img, (nw, nh))
|
|
89
|
-
canvas = np.full((imgsz, imgsz, 3), 114, dtype=np.uint8)
|
|
90
|
-
canvas[:nh, :nw] = resized
|
|
91
|
-
chw = canvas.transpose(2, 0, 1).astype(np.float32) / 255.0
|
|
92
|
-
return chw[np.newaxis, ...]
|
|
121
|
+
return letterbox_for_calibration(cv2.cvtColor(img, cv2.COLOR_BGR2RGB), imgsz)
|
|
93
122
|
|
|
94
123
|
dataset = nncf.Dataset(images, lambda p: preprocess(p))
|
|
95
124
|
ov_model = ov.convert_model(onnx_path)
|