@camstack/addon-model-studio 1.1.204 → 1.1.206
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-f-Rb4FPx.mjs → MotionZonesSettings-C5YcAYX9.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-DzrwiikK.mjs → PrivacyMaskSettings-B1M6BI5F.mjs} +4 -4
- package/dist/{SceneMonitorEditor-pr_u7JDi.mjs → SceneMonitorEditor-8Nn6yjHl.mjs} +3 -3
- package/dist/_stub.js +5102 -4909
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DD6MdVfP.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-B4UQ5mJi.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-2O40KrYq.mjs +26 -0
- package/dist/{hostInit-dZ-iNlYE.mjs → hostInit-95eIoNUt.mjs} +2 -2
- package/dist/model-studio.addon.js +289 -34
- package/dist/model-studio.addon.mjs +289 -34
- package/dist/{player-overlays-DyoPwbMr.mjs → player-overlays-lpfo2ab8.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-_Hjo-SPS.mjs → responsive-CO_rI6GL.mjs} +1 -1
- package/dist/{scene-monitor-copy-DxG4-n1Z.mjs → scene-monitor-copy-Dx3Cq-sD.mjs} +1 -1
- package/dist/{square-BIirO7Z1.mjs → square-DQHBxjsn.mjs} +1 -1
- package/dist/{trash-2-B9qboTSI.mjs → trash-2-C6kfv9xl.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DExLMP5B.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CXb44kDc.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cjm3a0Rl.mjs +0 -26
|
@@ -5747,7 +5747,7 @@ var ZodIssueCode = {
|
|
|
5747
5747
|
var ZodFirstPartyTypeKind;
|
|
5748
5748
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5749
5749
|
//#endregion
|
|
5750
|
-
//#region ../types/dist/sleep-
|
|
5750
|
+
//#region ../types/dist/sleep-C16NCZR2.mjs
|
|
5751
5751
|
/**
|
|
5752
5752
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5753
5753
|
* window to float samples (D455).
|
|
@@ -11124,6 +11124,19 @@ var ModelProviderIdSchema = _enum([
|
|
|
11124
11124
|
"custom"
|
|
11125
11125
|
]);
|
|
11126
11126
|
/**
|
|
11127
|
+
* Resolve a catalog entry's picker provider. An explicit stamp always wins;
|
|
11128
|
+
* otherwise Frigate/Scrypted are recognised from id prefix or description.
|
|
11129
|
+
* Unstamped BYO registry rows fall through to `custom`. Family `yolov9` is
|
|
11130
|
+
* NOT a Scrypted signal — CamStack ships that family too.
|
|
11131
|
+
*/
|
|
11132
|
+
function inferModelProvider(entry) {
|
|
11133
|
+
if (entry.provider !== void 0) return entry.provider;
|
|
11134
|
+
const haystack = `${entry.id} ${entry.description ?? ""}`;
|
|
11135
|
+
if (/scrypted/i.test(haystack)) return "scrypted";
|
|
11136
|
+
if (/frigate/i.test(haystack)) return "frigate";
|
|
11137
|
+
return "custom";
|
|
11138
|
+
}
|
|
11139
|
+
/**
|
|
11127
11140
|
* The licence of a model, as a record rather than a bare SPDX string: a
|
|
11128
11141
|
* permissive CODE licence routinely sits on top of restrictive WEIGHTS or
|
|
11129
11142
|
* DATA, and the obligations (attribution, modification notices, source offers)
|
|
@@ -16523,6 +16536,12 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
|
|
|
16523
16536
|
kind: "mutation",
|
|
16524
16537
|
auth: "admin"
|
|
16525
16538
|
});
|
|
16539
|
+
var HUB_ADDRESS_ROLES = [
|
|
16540
|
+
"appConnections",
|
|
16541
|
+
"notificationTaps",
|
|
16542
|
+
"internal",
|
|
16543
|
+
"publicEndpoint"
|
|
16544
|
+
];
|
|
16526
16545
|
/**
|
|
16527
16546
|
* Transport bounds for AI capability methods.
|
|
16528
16547
|
*
|
|
@@ -20700,7 +20719,13 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
20700
20719
|
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
20701
20720
|
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
20702
20721
|
*/
|
|
20703
|
-
notifySensorRewatched: boolean().optional()
|
|
20722
|
+
notifySensorRewatched: boolean().optional(),
|
|
20723
|
+
/**
|
|
20724
|
+
* D735: notify "ignored" when a sensor this arm bypassed really MOVED while armed (its own
|
|
20725
|
+
* change time is after the arm) and set nothing off. Absent = false (logged, not sent). A
|
|
20726
|
+
* re-sync, a recovery from `unavailable` or a duplicate is never announced, switch or not.
|
|
20727
|
+
*/
|
|
20728
|
+
notifySensorIgnored: boolean().optional()
|
|
20704
20729
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20705
20730
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20706
20731
|
mode: AlarmArmModeSchema,
|
|
@@ -20713,7 +20738,9 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
20713
20738
|
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20714
20739
|
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
20715
20740
|
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20716
|
-
notifySensorRewatched: boolean().nullable().optional()
|
|
20741
|
+
notifySensorRewatched: boolean().nullable().optional(),
|
|
20742
|
+
/** D735: set the switch, or `null` to clear it (back to the default, false). */
|
|
20743
|
+
notifySensorIgnored: boolean().nullable().optional()
|
|
20717
20744
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20718
20745
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20719
20746
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -28465,6 +28492,14 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
|
|
|
28465
28492
|
*/
|
|
28466
28493
|
alive: boolean()
|
|
28467
28494
|
})), method(object({
|
|
28495
|
+
deviceId: number().int().nonnegative(),
|
|
28496
|
+
sessionId: string(),
|
|
28497
|
+
downlinkMbps: number().nonnegative()
|
|
28498
|
+
}), object({
|
|
28499
|
+
outcome: _enum(["switching", "held"]),
|
|
28500
|
+
tier: CamProfileSchema.nullable(),
|
|
28501
|
+
reason: string()
|
|
28502
|
+
}), { kind: "mutation" }), method(object({
|
|
28468
28503
|
deviceId: number().int().nonnegative(),
|
|
28469
28504
|
sessionId: string()
|
|
28470
28505
|
}), WebrtcSessionDebugSchema, { kind: "query" });
|
|
@@ -31140,7 +31175,8 @@ var ConnectionEndpointSchema = object({
|
|
|
31140
31175
|
"lan-ipv6",
|
|
31141
31176
|
"public",
|
|
31142
31177
|
"loopback",
|
|
31143
|
-
"app-link"
|
|
31178
|
+
"app-link",
|
|
31179
|
+
"custom"
|
|
31144
31180
|
]),
|
|
31145
31181
|
/**
|
|
31146
31182
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -31209,7 +31245,7 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
31209
31245
|
localPort: AdvertisedLocalPortSchema
|
|
31210
31246
|
});
|
|
31211
31247
|
/**
|
|
31212
|
-
* The address flagged for notification
|
|
31248
|
+
* The address flagged for notification taps (`notificationTaps`). `baseUrl: null` = AUTO, which
|
|
31213
31249
|
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
31214
31250
|
* so the UI can show it either way.
|
|
31215
31251
|
*/
|
|
@@ -31243,13 +31279,12 @@ var ViewerEndpointsSchema = object({
|
|
|
31243
31279
|
resolved: array(string()).readonly()
|
|
31244
31280
|
});
|
|
31245
31281
|
/**
|
|
31246
|
-
*
|
|
31247
|
-
*
|
|
31282
|
+
* DEPRECATED compatibility shape of `getHubAddresses` (D729 amendment, kept
|
|
31283
|
+
* for addons built against it): `cluster` is the `internal` role, `browser`
|
|
31284
|
+
* the `publicEndpoint` role; `override` is the flagged address.
|
|
31248
31285
|
*/
|
|
31249
31286
|
var HubAddressSnapshotSchema = object({
|
|
31250
|
-
/** The operator's override, or null for automatic. */
|
|
31251
31287
|
override: string().nullable(),
|
|
31252
|
-
/** The address in use, or null when nothing qualifies (never loopback). */
|
|
31253
31288
|
resolved: string().nullable(),
|
|
31254
31289
|
source: _enum([
|
|
31255
31290
|
"override",
|
|
@@ -31258,11 +31293,57 @@ var HubAddressSnapshotSchema = object({
|
|
|
31258
31293
|
])
|
|
31259
31294
|
});
|
|
31260
31295
|
var HubAddressesSchema = object({
|
|
31261
|
-
/** "Hub address for agents" — agents' bundle/model pulls, LAN devices. */
|
|
31262
31296
|
cluster: HubAddressSnapshotSchema,
|
|
31263
|
-
/** "Public address for sign-in links" — e-mail links, OIDC, WebAuthn, OAuth2. */
|
|
31264
31297
|
browser: HubAddressSnapshotSchema
|
|
31265
31298
|
});
|
|
31299
|
+
/**
|
|
31300
|
+
* What an address is used for (`hub-address.ts`, D734). `appConnections` is
|
|
31301
|
+
* many-valued; `notificationTaps`, `publicEndpoint` and `internal` are carried
|
|
31302
|
+
* by at most one address.
|
|
31303
|
+
*/
|
|
31304
|
+
var HubAddressRoleSchema = _enum(HUB_ADDRESS_ROLES);
|
|
31305
|
+
var RoleSourceSchema = _enum([
|
|
31306
|
+
"flagged",
|
|
31307
|
+
"auto",
|
|
31308
|
+
"none"
|
|
31309
|
+
]);
|
|
31310
|
+
/** One single-valued role: the flagged address, the one in use, and why. */
|
|
31311
|
+
var HubAddressRoleResolutionSchema = object({
|
|
31312
|
+
/** The address carrying the flag, or null = automatic. */
|
|
31313
|
+
flagged: string().nullable(),
|
|
31314
|
+
/** The address in use, or null when nothing qualifies (never loopback). */
|
|
31315
|
+
resolved: string().nullable(),
|
|
31316
|
+
source: RoleSourceSchema
|
|
31317
|
+
});
|
|
31318
|
+
var HubAppConnectionsResolutionSchema = object({
|
|
31319
|
+
/** The addresses flagged `appConnections`, or empty = automatic. */
|
|
31320
|
+
flagged: array(string()).readonly(),
|
|
31321
|
+
/** What the apps race right now. */
|
|
31322
|
+
resolved: array(string()).readonly(),
|
|
31323
|
+
source: RoleSourceSchema
|
|
31324
|
+
});
|
|
31325
|
+
var HubAddressBookSchema = object({
|
|
31326
|
+
rows: array(ConnectionEndpointSchema.extend({
|
|
31327
|
+
/** In the hub's detected palette right now. */
|
|
31328
|
+
detected: boolean(),
|
|
31329
|
+
/** Entered by the operator (removable). */
|
|
31330
|
+
custom: boolean(),
|
|
31331
|
+
/** The roles explicitly flagged on this address. */
|
|
31332
|
+
flags: array(HubAddressRoleSchema).readonly(),
|
|
31333
|
+
/** The roles this address serves right now — flagged or automatic. */
|
|
31334
|
+
inUse: array(HubAddressRoleSchema).readonly(),
|
|
31335
|
+
/** The roles this address may be flagged with. */
|
|
31336
|
+
eligible: array(HubAddressRoleSchema).readonly()
|
|
31337
|
+
})).readonly(),
|
|
31338
|
+
roles: object({
|
|
31339
|
+
appConnections: HubAppConnectionsResolutionSchema,
|
|
31340
|
+
notificationTaps: HubAddressRoleResolutionSchema,
|
|
31341
|
+
internal: HubAddressRoleResolutionSchema,
|
|
31342
|
+
publicEndpoint: HubAddressRoleResolutionSchema
|
|
31343
|
+
}),
|
|
31344
|
+
/** The `hub=` an app link carries (D709), or null. */
|
|
31345
|
+
appLinkHub: string().nullable()
|
|
31346
|
+
});
|
|
31266
31347
|
var AllowedAddressesSchema = object({
|
|
31267
31348
|
/**
|
|
31268
31349
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -31306,16 +31387,27 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
31306
31387
|
* tunnel always emits `https://` regardless. */
|
|
31307
31388
|
scheme: _enum(["http", "https"]).optional(),
|
|
31308
31389
|
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
31309
|
-
* an address notification
|
|
31390
|
+
* an address notification taps can be flagged with, not a hub
|
|
31310
31391
|
* route. Default `false`: racers and rankers never see it. */
|
|
31311
31392
|
includeAppLink: boolean().optional()
|
|
31312
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
}),
|
|
31393
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(object({ scheme: _enum(["http", "https"]).optional() }).optional(), HubAddressBookSchema), method(object({
|
|
31394
|
+
baseUrl: string(),
|
|
31395
|
+
label: string().max(80)
|
|
31396
|
+
}), HubAddressBookSchema, {
|
|
31316
31397
|
kind: "mutation",
|
|
31317
31398
|
auth: "admin"
|
|
31318
|
-
}), method(
|
|
31399
|
+
}), method(object({ baseUrl: string() }), HubAddressBookSchema, {
|
|
31400
|
+
kind: "mutation",
|
|
31401
|
+
auth: "admin"
|
|
31402
|
+
}), method(object({
|
|
31403
|
+
role: HubAddressRoleSchema,
|
|
31404
|
+
baseUrl: string().nullable(),
|
|
31405
|
+
enabled: boolean(),
|
|
31406
|
+
acceptInsecureHttp: boolean().optional()
|
|
31407
|
+
}), HubAddressBookSchema, {
|
|
31408
|
+
kind: "mutation",
|
|
31409
|
+
auth: "admin"
|
|
31410
|
+
}), method(_void(), HubAddressesSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
31319
31411
|
kind: "mutation",
|
|
31320
31412
|
auth: "admin"
|
|
31321
31413
|
}), method(object({
|
|
@@ -39842,12 +39934,24 @@ Object.freeze({
|
|
|
39842
39934
|
addonId: null,
|
|
39843
39935
|
access: "view"
|
|
39844
39936
|
},
|
|
39937
|
+
"localNetwork.addCustomAddress": {
|
|
39938
|
+
capName: "local-network",
|
|
39939
|
+
capScope: "system",
|
|
39940
|
+
addonId: null,
|
|
39941
|
+
access: "create"
|
|
39942
|
+
},
|
|
39845
39943
|
"localNetwork.downloadCa": {
|
|
39846
39944
|
capName: "local-network",
|
|
39847
39945
|
capScope: "system",
|
|
39848
39946
|
addonId: null,
|
|
39849
39947
|
access: "view"
|
|
39850
39948
|
},
|
|
39949
|
+
"localNetwork.getAddresses": {
|
|
39950
|
+
capName: "local-network",
|
|
39951
|
+
capScope: "system",
|
|
39952
|
+
addonId: null,
|
|
39953
|
+
access: "view"
|
|
39954
|
+
},
|
|
39851
39955
|
"localNetwork.getAllowedAddresses": {
|
|
39852
39956
|
capName: "local-network",
|
|
39853
39957
|
capScope: "system",
|
|
@@ -39902,6 +40006,12 @@ Object.freeze({
|
|
|
39902
40006
|
addonId: null,
|
|
39903
40007
|
access: "create"
|
|
39904
40008
|
},
|
|
40009
|
+
"localNetwork.removeCustomAddress": {
|
|
40010
|
+
capName: "local-network",
|
|
40011
|
+
capScope: "system",
|
|
40012
|
+
addonId: null,
|
|
40013
|
+
access: "delete"
|
|
40014
|
+
},
|
|
39905
40015
|
"localNetwork.resetAllowlistToBestMatch": {
|
|
39906
40016
|
capName: "local-network",
|
|
39907
40017
|
capScope: "system",
|
|
@@ -39914,13 +40024,13 @@ Object.freeze({
|
|
|
39914
40024
|
addonId: null,
|
|
39915
40025
|
access: "create"
|
|
39916
40026
|
},
|
|
39917
|
-
"localNetwork.
|
|
40027
|
+
"localNetwork.setAddressRole": {
|
|
39918
40028
|
capName: "local-network",
|
|
39919
40029
|
capScope: "system",
|
|
39920
40030
|
addonId: null,
|
|
39921
40031
|
access: "create"
|
|
39922
40032
|
},
|
|
39923
|
-
"localNetwork.
|
|
40033
|
+
"localNetwork.setAllowedAddresses": {
|
|
39924
40034
|
capName: "local-network",
|
|
39925
40035
|
capScope: "system",
|
|
39926
40036
|
addonId: null,
|
|
@@ -44174,6 +44284,12 @@ Object.freeze({
|
|
|
44174
44284
|
addonId: null,
|
|
44175
44285
|
access: "create"
|
|
44176
44286
|
},
|
|
44287
|
+
"webrtcSession.applyDownlinkProbe": {
|
|
44288
|
+
capName: "webrtc-session",
|
|
44289
|
+
capScope: "device",
|
|
44290
|
+
addonId: null,
|
|
44291
|
+
access: "create"
|
|
44292
|
+
},
|
|
44177
44293
|
"webrtcSession.closeSession": {
|
|
44178
44294
|
capName: "webrtc-session",
|
|
44179
44295
|
capScope: "device",
|
|
@@ -48096,6 +48212,11 @@ Object.freeze({
|
|
|
48096
48212
|
form: "single",
|
|
48097
48213
|
optional: false
|
|
48098
48214
|
}],
|
|
48215
|
+
"webrtcSession.applyDownlinkProbe": [{
|
|
48216
|
+
name: "deviceId",
|
|
48217
|
+
form: "single",
|
|
48218
|
+
optional: false
|
|
48219
|
+
}],
|
|
48099
48220
|
"webrtcSession.closeSession": [{
|
|
48100
48221
|
name: "deviceId",
|
|
48101
48222
|
form: "single",
|
|
@@ -49364,6 +49485,35 @@ function buildModelConvertProvider(deps) {
|
|
|
49364
49485
|
};
|
|
49365
49486
|
} };
|
|
49366
49487
|
}
|
|
49488
|
+
var CONTROL_CHARS = /[\u0000-\u001f\u007f]/;
|
|
49489
|
+
/** Whitespace runs collapse to one space; leading/trailing whitespace goes. */
|
|
49490
|
+
function parseDisplayName(raw) {
|
|
49491
|
+
const name = raw.replace(/\s+/g, " ").trim();
|
|
49492
|
+
if (name.length === 0) return { kind: "reset" };
|
|
49493
|
+
if (CONTROL_CHARS.test(name)) return {
|
|
49494
|
+
kind: "invalid",
|
|
49495
|
+
reason: "The name contains control characters."
|
|
49496
|
+
};
|
|
49497
|
+
if (name.length > 80) return {
|
|
49498
|
+
kind: "invalid",
|
|
49499
|
+
reason: `The name is ${name.length} characters long; the limit is 80.`
|
|
49500
|
+
};
|
|
49501
|
+
return {
|
|
49502
|
+
kind: "set",
|
|
49503
|
+
name
|
|
49504
|
+
};
|
|
49505
|
+
}
|
|
49506
|
+
/**
|
|
49507
|
+
* The optional display name typed on an import card: `undefined` when left
|
|
49508
|
+
* empty (the source's own default applies), the cleaned name otherwise.
|
|
49509
|
+
* Throws with the reason when the input is not acceptable.
|
|
49510
|
+
*/
|
|
49511
|
+
function optionalImportName(raw) {
|
|
49512
|
+
if (raw === void 0) return void 0;
|
|
49513
|
+
const parsed = parseDisplayName(raw);
|
|
49514
|
+
if (parsed.kind === "invalid") throw new Error(`Display name rejected: ${parsed.reason}`);
|
|
49515
|
+
return parsed.kind === "set" ? parsed.name : void 0;
|
|
49516
|
+
}
|
|
49367
49517
|
//#endregion
|
|
49368
49518
|
//#region src/model-registry.ts
|
|
49369
49519
|
/**
|
|
@@ -49395,22 +49545,18 @@ function upsertAvailability(map, modelId, nodeId, entry) {
|
|
|
49395
49545
|
});
|
|
49396
49546
|
}
|
|
49397
49547
|
/**
|
|
49398
|
-
* Pure registry operations over the custom-model list. Kept side-effect-free
|
|
49399
|
-
* so they unit-test without a live `BaseAddon` context — the addon class is a
|
|
49400
|
-
* thin durable-state wrapper around these.
|
|
49401
|
-
*/
|
|
49402
|
-
/**
|
|
49403
49548
|
* Insert or replace a descriptor keyed by `entry.id`. When the id already
|
|
49404
49549
|
* exists, **formats are merged** (Scrypted multi-format accumulate) — sibling
|
|
49405
49550
|
* formats on the prior entry are never dropped. Returns a new array.
|
|
49406
49551
|
*/
|
|
49407
|
-
function upsertCustomModel(list, descriptor) {
|
|
49552
|
+
function upsertCustomModel(list, descriptor, nameOrigin = "source") {
|
|
49408
49553
|
const prev = list.find((m) => m.entry.id === descriptor.entry.id);
|
|
49409
49554
|
const merged = prev === void 0 ? descriptor : {
|
|
49410
49555
|
stepId: descriptor.stepId,
|
|
49411
49556
|
entry: {
|
|
49412
49557
|
...prev.entry,
|
|
49413
49558
|
...descriptor.entry,
|
|
49559
|
+
name: nameOrigin === "operator" ? descriptor.entry.name : prev.entry.name,
|
|
49414
49560
|
formats: {
|
|
49415
49561
|
...prev.entry.formats,
|
|
49416
49562
|
...descriptor.entry.formats
|
|
@@ -49419,6 +49565,43 @@ function upsertCustomModel(list, descriptor) {
|
|
|
49419
49565
|
};
|
|
49420
49566
|
return [...list.filter((m) => m.entry.id !== descriptor.entry.id), merged];
|
|
49421
49567
|
}
|
|
49568
|
+
/**
|
|
49569
|
+
* Rename one IMPORTED registry row in place. Only `entry.name` changes — the
|
|
49570
|
+
* id, step, formats and every pin keyed by the id stay exactly as they were.
|
|
49571
|
+
* An empty name resets the row to the name it was imported with. Throws on an
|
|
49572
|
+
* unknown id, a CamStack catalog row, or a name `parseDisplayName` rejects.
|
|
49573
|
+
*/
|
|
49574
|
+
function renameCustomModel(list, importedNames, modelId, rawName) {
|
|
49575
|
+
const row = list.find((m) => m.entry.id === modelId);
|
|
49576
|
+
if (row === void 0) throw new Error(`renameCustomModel: model "${modelId}" is not registered`);
|
|
49577
|
+
if (!isRenameableEntry(row.entry)) throw new Error(`renameCustomModel: "${modelId}" is a CamStack catalog model and keeps its name`);
|
|
49578
|
+
const parsed = parseDisplayName(rawName);
|
|
49579
|
+
if (parsed.kind === "invalid") throw new Error(`renameCustomModel: ${parsed.reason}`);
|
|
49580
|
+
const original = importedNames[modelId] ?? row.entry.name;
|
|
49581
|
+
const name = parsed.kind === "set" ? parsed.name : original;
|
|
49582
|
+
const nextNames = { ...importedNames };
|
|
49583
|
+
if (parsed.kind === "set" && name !== original) nextNames[modelId] = original;
|
|
49584
|
+
else delete nextNames[modelId];
|
|
49585
|
+
return {
|
|
49586
|
+
list: list.map((m) => m.entry.id === modelId ? {
|
|
49587
|
+
stepId: m.stepId,
|
|
49588
|
+
entry: {
|
|
49589
|
+
...m.entry,
|
|
49590
|
+
name
|
|
49591
|
+
}
|
|
49592
|
+
} : m),
|
|
49593
|
+
importedNames: nextNames,
|
|
49594
|
+
name
|
|
49595
|
+
};
|
|
49596
|
+
}
|
|
49597
|
+
/** An imported row can be renamed; a CamStack catalog model cannot. */
|
|
49598
|
+
function isRenameableEntry(entry) {
|
|
49599
|
+
return inferModelProvider({
|
|
49600
|
+
id: entry.id,
|
|
49601
|
+
description: entry.description,
|
|
49602
|
+
provider: entry.provider
|
|
49603
|
+
}) !== "camstack";
|
|
49604
|
+
}
|
|
49422
49605
|
/** Drop the descriptor with the given `entry.id`. Reports whether anything changed. */
|
|
49423
49606
|
function removeCustomModel(list, modelId) {
|
|
49424
49607
|
const next = list.filter((m) => m.entry.id !== modelId);
|
|
@@ -50266,6 +50449,19 @@ var modelStudioActions = defineCustomActions({
|
|
|
50266
50449
|
clearedPins: number().int().nonnegative()
|
|
50267
50450
|
}), { kind: "mutation" }),
|
|
50268
50451
|
/**
|
|
50452
|
+
* Rename an IMPORTED registry row (Frigate, Frigate+, Scrypted, uploads,
|
|
50453
|
+
* conversions) in place. Only `entry.name` changes — never the id, so pins
|
|
50454
|
+
* and availability are untouched. An empty name restores the name the model
|
|
50455
|
+
* was imported with. CamStack catalog models are refused.
|
|
50456
|
+
*/
|
|
50457
|
+
renameCustomModel: customAction(object({
|
|
50458
|
+
modelId: string().min(1),
|
|
50459
|
+
name: string()
|
|
50460
|
+
}), object({
|
|
50461
|
+
modelId: string(),
|
|
50462
|
+
name: string()
|
|
50463
|
+
}), { kind: "mutation" }),
|
|
50464
|
+
/**
|
|
50269
50465
|
* Delete one format of a Library model from one node. Keeps the registry row
|
|
50270
50466
|
* and sibling formats/nodes; clears only that availability chip.
|
|
50271
50467
|
*/
|
|
@@ -50354,6 +50550,8 @@ var modelStudioActions = defineCustomActions({
|
|
|
50354
50550
|
})),
|
|
50355
50551
|
importScryptedCatalogModel: customAction(object({
|
|
50356
50552
|
manifestId: string(),
|
|
50553
|
+
/** Optional display name typed on the import card. */
|
|
50554
|
+
name: string().optional(),
|
|
50357
50555
|
targetNodeId: string().optional()
|
|
50358
50556
|
}), CustomModelDescriptorSchema, { kind: "mutation" }),
|
|
50359
50557
|
/**
|
|
@@ -50383,7 +50581,8 @@ var modelStudioActions = defineCustomActions({
|
|
|
50383
50581
|
modelId: string().optional(),
|
|
50384
50582
|
name: string().optional(),
|
|
50385
50583
|
/**
|
|
50386
|
-
* Native artifact class
|
|
50584
|
+
* Native artifact class of the chosen build (`plusImportLane`: neural →
|
|
50585
|
+
* onnx, coral → tflite). The
|
|
50387
50586
|
* model-detail API does not always carry `supportedDetectors`, so the
|
|
50388
50587
|
* browser passes what the catalog already knew (fixes ssd/yolo-generic
|
|
50389
50588
|
* EdgeTPU rows that `plusTypeTraits` alone would call onnx).
|
|
@@ -50435,6 +50634,8 @@ var modelStudioActions = defineCustomActions({
|
|
|
50435
50634
|
//#region src/model-studio.addon.ts
|
|
50436
50635
|
var KEY_CUSTOM_MODELS = "customModels";
|
|
50437
50636
|
var KEY_AVAILABILITY = "availability";
|
|
50637
|
+
var KEY_IMPORTED_NAMES = "importedNames";
|
|
50638
|
+
var ImportedNamesSchema = record(string(), string());
|
|
50438
50639
|
var CustomModelsSchema = array(CustomModelDescriptorSchema);
|
|
50439
50640
|
var pythonDirCache;
|
|
50440
50641
|
function resolveAddonPythonDir() {
|
|
@@ -50497,12 +50698,18 @@ function spawnRunConvert(jobPath, pythonPath, onProgress, _sessionId) {
|
|
|
50497
50698
|
});
|
|
50498
50699
|
});
|
|
50499
50700
|
}
|
|
50701
|
+
/** A name the operator typed replaces an existing row's name; a derived one never does. */
|
|
50702
|
+
function nameOriginOf(operatorName) {
|
|
50703
|
+
return operatorName !== void 0 ? { nameOrigin: "operator" } : {};
|
|
50704
|
+
}
|
|
50500
50705
|
/** Global-fetch adapter for the injected Frigate+ client seam. */
|
|
50501
50706
|
var plusFetch = async (url, init) => fetch(url, init);
|
|
50502
50707
|
var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
50503
50708
|
id = "model-studio";
|
|
50504
50709
|
modelsState = null;
|
|
50505
50710
|
availabilityState = null;
|
|
50711
|
+
/** modelId → the name a renamed registry row had before its first rename. */
|
|
50712
|
+
importedNamesState = null;
|
|
50506
50713
|
/** Lazily-built chunked-upload store (hub only) — see `upload/model-upload-store.ts`. */
|
|
50507
50714
|
uploadStore = null;
|
|
50508
50715
|
/**
|
|
@@ -50585,6 +50792,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50585
50792
|
const state = this.state(KEY_CUSTOM_MODELS, CustomModelsSchema, []);
|
|
50586
50793
|
this.modelsState = state;
|
|
50587
50794
|
this.availabilityState = this.state(KEY_AVAILABILITY, ModelAvailabilityMapSchema, {});
|
|
50795
|
+
this.importedNamesState = this.state(KEY_IMPORTED_NAMES, ImportedNamesSchema, {});
|
|
50588
50796
|
const rawNode = this.ctx.kernel?.localNodeId ?? "hub";
|
|
50589
50797
|
const isHub = (rawNode.includes("/") ? rawNode.split("/")[0] : rawNode) === "hub";
|
|
50590
50798
|
const pagesProvider = {
|
|
@@ -50618,7 +50826,11 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50618
50826
|
return result;
|
|
50619
50827
|
},
|
|
50620
50828
|
abortModelUpload: async (input) => (await this.getUploadStore()).abort(input),
|
|
50621
|
-
registerCustomModel: async (input) => this.registerCustomModel(input, {
|
|
50829
|
+
registerCustomModel: async (input) => this.registerCustomModel(input, {
|
|
50830
|
+
ensureEngines: true,
|
|
50831
|
+
nameOrigin: "operator"
|
|
50832
|
+
}),
|
|
50833
|
+
renameCustomModel: async (input) => this.renameCustomModel_(input),
|
|
50622
50834
|
ensureFormatsThenDistribute: async (input) => this.ensureFormatsThenDistribute_(input.modelId),
|
|
50623
50835
|
ensureModelFormats: async (input) => this.ensureModelFormats_(input.modelId, input.formats),
|
|
50624
50836
|
removeCustomModel: async (input) => this.removeCustomModel(input),
|
|
@@ -50770,6 +50982,35 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50770
50982
|
if (!this.modelsState) throw new Error("ModelStudioAddon: durable state not initialized");
|
|
50771
50983
|
return this.modelsState;
|
|
50772
50984
|
}
|
|
50985
|
+
get importedNames_() {
|
|
50986
|
+
if (!this.importedNamesState) throw new Error("ModelStudioAddon: imported-names state not initialized");
|
|
50987
|
+
return this.importedNamesState;
|
|
50988
|
+
}
|
|
50989
|
+
/**
|
|
50990
|
+
* Rename an imported registry row in place (`renameCustomModel` decides).
|
|
50991
|
+
* The id is untouched, so pins, availability and files are unaffected; the
|
|
50992
|
+
* pipeline's catalog view picks the new name up on its next registry read.
|
|
50993
|
+
*/
|
|
50994
|
+
async renameCustomModel_(input) {
|
|
50995
|
+
const names = await this.importedNames_.get();
|
|
50996
|
+
const outcome = {};
|
|
50997
|
+
await this.state_.update((prev) => {
|
|
50998
|
+
const renamed = renameCustomModel(prev, names, input.modelId, input.name);
|
|
50999
|
+
outcome.result = renamed;
|
|
51000
|
+
return renamed.list;
|
|
51001
|
+
});
|
|
51002
|
+
const result = outcome.result;
|
|
51003
|
+
if (result === void 0) throw new Error("renameCustomModel: registry update did not run");
|
|
51004
|
+
await this.importedNames_.set(result.importedNames);
|
|
51005
|
+
this.ctx.logger.info("Renamed custom model", { meta: {
|
|
51006
|
+
modelId: input.modelId,
|
|
51007
|
+
name: result.name
|
|
51008
|
+
} });
|
|
51009
|
+
return {
|
|
51010
|
+
modelId: input.modelId,
|
|
51011
|
+
name: result.name
|
|
51012
|
+
};
|
|
51013
|
+
}
|
|
50773
51014
|
get availability_() {
|
|
50774
51015
|
if (!this.availabilityState) throw new Error("ModelStudioAddon: availability state not initialized");
|
|
50775
51016
|
return this.availabilityState;
|
|
@@ -50891,6 +51132,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50891
51132
|
* `targetNodeId` lands the HF URL on that node via download-on-target.
|
|
50892
51133
|
*/
|
|
50893
51134
|
async importScryptedCatalogFromManifest(input) {
|
|
51135
|
+
const name = optionalImportName(input.name);
|
|
50894
51136
|
const entry = getScryptedManifestEntry(input.manifestId);
|
|
50895
51137
|
if (!entry) throw new Error(`importScryptedCatalogModel: unknown manifest id "${input.manifestId}"`);
|
|
50896
51138
|
let drift;
|
|
@@ -50910,8 +51152,15 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50910
51152
|
};
|
|
50911
51153
|
}
|
|
50912
51154
|
if (drift.status !== "ok") throw new Error(`importScryptedCatalogModel: entry "${entry.id}" is blocked by drift (${drift.status}${drift.details ? `: ${drift.details}` : ""})`);
|
|
50913
|
-
const
|
|
50914
|
-
|
|
51155
|
+
const built = buildScryptedRegistryDescriptor(entry);
|
|
51156
|
+
const descriptor = name !== void 0 ? {
|
|
51157
|
+
stepId: built.stepId,
|
|
51158
|
+
entry: {
|
|
51159
|
+
...built.entry,
|
|
51160
|
+
name
|
|
51161
|
+
}
|
|
51162
|
+
} : built;
|
|
51163
|
+
await this.registerCustomModel(descriptor, nameOriginOf(name));
|
|
50915
51164
|
if (input.targetNodeId !== void 0 && input.targetNodeId.length > 0) await this.distributeModel({
|
|
50916
51165
|
modelId: descriptor.entry.id,
|
|
50917
51166
|
nodeId: input.targetNodeId,
|
|
@@ -50933,11 +51182,12 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50933
51182
|
async importFrigateCatalogModel(input) {
|
|
50934
51183
|
const cat = FRIGATE_PUBLIC_CATALOG.find((c) => c.id === input.catalogId);
|
|
50935
51184
|
if (!cat) throw new Error(`importFrigateCatalogModel: unknown catalog id "${input.catalogId}"`);
|
|
51185
|
+
const name = optionalImportName(input.name);
|
|
50936
51186
|
const descriptor = buildFrigateCatalogDescriptor(input.catalogId, {
|
|
50937
51187
|
...input.modelId !== void 0 ? { modelId: input.modelId } : {},
|
|
50938
|
-
...
|
|
51188
|
+
...name !== void 0 ? { name } : {}
|
|
50939
51189
|
});
|
|
50940
|
-
await this.registerCustomModel(descriptor);
|
|
51190
|
+
await this.registerCustomModel(descriptor, nameOriginOf(name));
|
|
50941
51191
|
let bytes = Math.round(cat.sizeMB * 1e6);
|
|
50942
51192
|
if (input.targetNodeId !== void 0 && input.targetNodeId.length > 0) {
|
|
50943
51193
|
const landed = await this.distributeModel({
|
|
@@ -50968,6 +51218,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50968
51218
|
*/
|
|
50969
51219
|
async importFrigatePlusModel(input) {
|
|
50970
51220
|
const modelId = frigatePlusRegistryId(input.plusModelId);
|
|
51221
|
+
const operatorName = optionalImportName(input.name);
|
|
50971
51222
|
const key = this.config.frigatePlusApiKey ?? "";
|
|
50972
51223
|
const { info, downloadUrl } = await requestPlusModelDownload(plusFetch, key, input.plusModelId);
|
|
50973
51224
|
const typeTraits = plusTypeTraits(info.type);
|
|
@@ -50992,12 +51243,15 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
50992
51243
|
const sha256 = await ModelStudioAddon.fileSha256(destPath);
|
|
50993
51244
|
const descriptor = plusInfoToDescriptor(info, {
|
|
50994
51245
|
modelId,
|
|
50995
|
-
name:
|
|
51246
|
+
name: operatorName ?? `Frigate+ ${info.type} (${input.plusModelId.slice(0, 8)})`,
|
|
50996
51247
|
filename,
|
|
50997
51248
|
sizeMB: Number((bytes / 1e6).toFixed(1)),
|
|
50998
51249
|
...input.format !== void 0 ? { format: input.format } : {}
|
|
50999
51250
|
});
|
|
51000
|
-
await this.registerCustomModel(descriptor, {
|
|
51251
|
+
await this.registerCustomModel(descriptor, {
|
|
51252
|
+
ensureEngines: false,
|
|
51253
|
+
...nameOriginOf(operatorName)
|
|
51254
|
+
});
|
|
51001
51255
|
await this.availability_.update((prev) => upsertAvailability(prev, modelId, "hub", {
|
|
51002
51256
|
format: traits.format,
|
|
51003
51257
|
sha256,
|
|
@@ -51030,7 +51284,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
51030
51284
|
async registerCustomModel(input, opts = {}) {
|
|
51031
51285
|
if (!input.stepId.trim()) throw new Error("registerCustomModel: stepId is required");
|
|
51032
51286
|
if (!input.entry.id.trim()) throw new Error("registerCustomModel: entry.id is required");
|
|
51033
|
-
await this.state_.update((prev) => upsertCustomModel(prev, input));
|
|
51287
|
+
await this.state_.update((prev) => upsertCustomModel(prev, input, opts.nameOrigin));
|
|
51034
51288
|
this.ctx.logger.info("Registered custom model", { meta: {
|
|
51035
51289
|
modelId: input.entry.id,
|
|
51036
51290
|
stepId: input.stepId
|
|
@@ -51287,6 +51541,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
|
|
|
51287
51541
|
removed = result.removed;
|
|
51288
51542
|
return result.next;
|
|
51289
51543
|
});
|
|
51544
|
+
await this.importedNames_.update((prev) => Object.fromEntries(Object.entries(prev).filter(([id]) => id !== input.modelId)));
|
|
51290
51545
|
this.ctx.logger.info("Removed custom model", { meta: {
|
|
51291
51546
|
modelId: input.modelId,
|
|
51292
51547
|
removed,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
|
|
2
|
-
import { o as i, s as a } from "./responsive-
|
|
2
|
+
import { o as i, s as a } from "./responsive-CO_rI6GL.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 = a("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-CXb44kDc.mjs";
|
|
2
2
|
export { t as get, e as init };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c as e, g as t, h as n, l as r, n as i, p as a, r as o, t as s, u as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.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 { c as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-
|
|
3
|
+
import { c as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-2O40KrYq.mjs";
|
|
4
4
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
|
|
5
5
|
l();
|
|
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 { c as e, h as t, p as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
|
|
2
|
-
import { s as i } from "./responsive-
|
|
2
|
+
import { s as i } from "./responsive-CO_rI6GL.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-B4UQ5mJi.mjs")).catch((e) => {
|
|
2757
2757
|
throw tr = void 0, e;
|
|
2758
2758
|
}), tr;
|
|
2759
2759
|
}
|