@camstack/addon-training 0.1.22 → 0.1.24
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/MaskShapeCanvas-Kfg9dl6B.mjs +686 -0
- package/dist/MotionZonesSettings-0RO2vXPR.mjs +292 -0
- package/dist/{PrivacyMaskSettings-DDaIx7j5.mjs → PrivacyMaskSettings-DQUoMnuu.mjs} +45 -70
- package/dist/ReactKonva-DGuYUN0L.mjs +5416 -0
- package/dist/{SceneMonitorEditor-CuJ7xjyd.mjs → SceneMonitorEditor-C3FOjEom.mjs} +311 -311
- package/dist/_stub.js +16625 -7160
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-DJDgoXBt.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-BxPcEUyP.mjs} +2 -2
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-OmGE1nuE.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DpjirGmB.mjs +89 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-CFCVuRAs.mjs +58 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-BkvDudqY.mjs +62 -0
- package/dist/{_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs → _virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs} +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs +34 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-DAZkHxxU.mjs +45 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-CHqN9NLt.mjs +34 -0
- package/dist/{dist-DhCvklZW.mjs → dist-CoNkmm69.mjs} +24 -12
- package/dist/{dist-Dd6EAdVX.js → dist-e1vfYY_l.js} +59 -11
- package/dist/grid-2x2-Dip9973H.mjs +21 -0
- package/dist/{hostInit-DR-St7pA.mjs → hostInit-DESLun4m.mjs} +1 -1
- package/dist/index.js +1 -1
- package/dist/lib-CVGFTwe0.mjs +7770 -0
- package/dist/orchestrator/training.addon.js +8 -1
- package/dist/orchestrator/training.addon.mjs +8 -1
- package/dist/{player-overlays-DUZMtmvk.mjs → player-overlays-ChonJUSb.mjs} +32 -10
- package/dist/providers/modal/training-modal.addon.js +233 -53
- package/dist/providers/modal/training-modal.addon.mjs +233 -53
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-C7QsFtTb.mjs → responsive-vGH-n9E5.mjs} +42 -38
- package/dist/{scene-monitor-copy-BtffdnnW.mjs → scene-monitor-copy-Bv7SdZp4.mjs} +4 -4
- package/dist/{square-e5Ytjod_.mjs → square-CT7zu_EB.mjs} +29 -4
- package/dist/{trash-2-Clte6zIF.mjs → trash-2-JjHVW2_2.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-dy7yMOdw.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-BZV1gmqf.mjs} +399 -390
- package/package.json +1 -1
- package/dist/MaskShapeCanvas-BokARvOj.mjs +0 -13806
- package/dist/MotionZonesSettings-DshSNzpp.mjs +0 -310
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D7T4QEtw.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BSOdwqcC.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-B3rryujf.mjs +0 -25
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-nL4MGFRP.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-CK-LlgOt.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-gTIQrhKs.mjs +0 -25
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dist = require("../dist-
|
|
2
|
+
const require_dist = require("../dist-e1vfYY_l.js");
|
|
3
3
|
let node_path = require("node:path");
|
|
4
4
|
node_path = require_dist.__toESM(node_path);
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
@@ -32,6 +32,13 @@ function providerPort(api) {
|
|
|
32
32
|
addonId
|
|
33
33
|
});
|
|
34
34
|
},
|
|
35
|
+
updateEntry: async (i) => {
|
|
36
|
+
const addonId = await addonForEntry(i.entryId);
|
|
37
|
+
return p.updateEntry.mutate({
|
|
38
|
+
...i,
|
|
39
|
+
addonId
|
|
40
|
+
});
|
|
41
|
+
},
|
|
35
42
|
deleteEntry: async (i) => {
|
|
36
43
|
const addonId = await addonForEntry(i.entryId);
|
|
37
44
|
return p.deleteEntry.mutate({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as addonPagesSourceCapability, i as TrainingResultSchema, l as BaseAddon, n as TrainingJobSchema, o as parseTrainingEventLine, r as TrainingJobSpecSchema, s as trainingCapability, t as TRAINING_JOB_SCHEMA } from "../dist-
|
|
1
|
+
import { a as addonPagesSourceCapability, i as TrainingResultSchema, l as BaseAddon, n as TrainingJobSchema, o as parseTrainingEventLine, r as TrainingJobSpecSchema, s as trainingCapability, t as TRAINING_JOB_SCHEMA } from "../dist-CoNkmm69.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { createReadStream } from "node:fs";
|
|
@@ -30,6 +30,13 @@ function providerPort(api) {
|
|
|
30
30
|
addonId
|
|
31
31
|
});
|
|
32
32
|
},
|
|
33
|
+
updateEntry: async (i) => {
|
|
34
|
+
const addonId = await addonForEntry(i.entryId);
|
|
35
|
+
return p.updateEntry.mutate({
|
|
36
|
+
...i,
|
|
37
|
+
addonId
|
|
38
|
+
});
|
|
39
|
+
},
|
|
33
40
|
deleteEntry: async (i) => {
|
|
34
41
|
const addonId = await addonForEntry(i.entryId);
|
|
35
42
|
return p.deleteEntry.mutate({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-
|
|
4
|
-
var l =
|
|
1
|
+
import { S as e, _ as t, l as n, u as r } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs";
|
|
2
|
+
import { b as i, y as a } from "./responsive-vGH-n9E5.mjs";
|
|
3
|
+
import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs";
|
|
4
|
+
var l = i("chevron-down", [["path", {
|
|
5
5
|
d: "m6 9 6 6 6-6",
|
|
6
6
|
key: "qrunsl"
|
|
7
|
-
}]]), u =
|
|
7
|
+
}]]), u = i("chevron-right", [["path", {
|
|
8
8
|
d: "m9 18 6-6-6-6",
|
|
9
9
|
key: "mthhwq"
|
|
10
10
|
}]]);
|
|
@@ -32,13 +32,35 @@ function d({ title: e, icon: n, headerRight: r, collapsible: i = !1, defaultOpen
|
|
|
32
32
|
}) : null]
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
e
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
function f({ label: e, icon: t, children: n, footer: r }) {
|
|
36
|
+
return /* @__PURE__ */ s("div", {
|
|
37
|
+
className: "min-w-0 rounded-lg border border-border bg-surface p-2 sm:p-2.5",
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ s("div", {
|
|
40
|
+
className: "mb-0.5 flex min-w-0 items-center gap-1.5 text-[10px] uppercase tracking-wider text-foreground-subtle",
|
|
41
|
+
children: [t, /* @__PURE__ */ o("span", {
|
|
42
|
+
className: "min-w-0 truncate",
|
|
43
|
+
children: e
|
|
44
|
+
})]
|
|
45
|
+
}),
|
|
46
|
+
/* @__PURE__ */ o("div", {
|
|
47
|
+
className: "truncate text-lg font-semibold leading-tight text-foreground",
|
|
48
|
+
children: n
|
|
49
|
+
}),
|
|
50
|
+
r == null ? null : /* @__PURE__ */ o("div", {
|
|
51
|
+
className: "mt-0.5 truncate text-[10px] text-foreground-subtle",
|
|
52
|
+
children: r
|
|
53
|
+
})
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
e(), a("camstack:player-overlays-state", null);
|
|
58
|
+
var p = a("camstack:player-overlays-actions", null);
|
|
59
|
+
function m(e) {
|
|
60
|
+
let t = n(p);
|
|
39
61
|
r(() => {
|
|
40
62
|
if (!(!t || !e)) return t.setLayer(e), () => t.removeLayer(e.id);
|
|
41
63
|
}, [t, e]);
|
|
42
64
|
}
|
|
43
65
|
//#endregion
|
|
44
|
-
export { l as i,
|
|
66
|
+
export { l as a, u as i, f as n, d as r, m as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dist = require("../../dist-
|
|
2
|
+
const require_dist = require("../../dist-e1vfYY_l.js");
|
|
3
3
|
let node_path = require("node:path");
|
|
4
4
|
node_path = require_dist.__toESM(node_path, 1);
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
@@ -11,14 +11,43 @@ let timers_promises = require("timers/promises");
|
|
|
11
11
|
let node_console = require("node:console");
|
|
12
12
|
let node_os = require("node:os");
|
|
13
13
|
let node_stream = require("node:stream");
|
|
14
|
-
//#region src/providers/modal/
|
|
14
|
+
//#region src/providers/modal/entry-secret-view.ts
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Build the {@link SecretFieldView} the Providers edit form needs for an
|
|
17
|
+
* entry's token secret.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* `readStoredGlobalKey` / `this.config` answer VALUES (D798), never markers —
|
|
20
|
+
* so `toSecretFieldView(plaintext)` alone yields an inline view (`$secret:
|
|
21
|
+
* null`) and `SecretFieldControl` cannot reveal. When the secret is set we
|
|
22
|
+
* prefer the deterministic keychain ref (`ctx.secrets.ref`) so the eye can
|
|
23
|
+
* call `keychain-admin.reveal` (D789).
|
|
21
24
|
*/
|
|
25
|
+
/** View for one entry row, or `null` when nothing is stored. */
|
|
26
|
+
function entryTokenSecretView(tokenSecret, secrets, entryId) {
|
|
27
|
+
if (require_dist.isSecretMarker(tokenSecret)) return require_dist.toSecretFieldView(tokenSecret);
|
|
28
|
+
const plain = typeof tokenSecret === "string" ? tokenSecret.trim() : "";
|
|
29
|
+
if (plain === "") return null;
|
|
30
|
+
if (secrets === void 0) return require_dist.toSecretFieldView(plain);
|
|
31
|
+
return {
|
|
32
|
+
$secret: secrets.ref(require_dist.globalSecretScope(), require_dist.arrayItemFieldPath("entries", entryId, "tokenSecret")),
|
|
33
|
+
v: 1,
|
|
34
|
+
set: true
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** View for the legacy flat `tokenSecret` (pre-multi-entry Default). */
|
|
38
|
+
function flatTokenSecretView(tokenSecret, secrets) {
|
|
39
|
+
if (require_dist.isSecretMarker(tokenSecret)) return require_dist.toSecretFieldView(tokenSecret);
|
|
40
|
+
const plain = typeof tokenSecret === "string" ? tokenSecret.trim() : "";
|
|
41
|
+
if (plain === "") return null;
|
|
42
|
+
if (secrets === void 0) return require_dist.toSecretFieldView(plain);
|
|
43
|
+
return {
|
|
44
|
+
$secret: secrets.ref(require_dist.globalSecretScope(), "tokenSecret"),
|
|
45
|
+
v: 1,
|
|
46
|
+
set: true
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/providers/modal/modal-entries.ts
|
|
22
51
|
var MODAL_TYPE_ID = "modal";
|
|
23
52
|
var DEFAULT_MODAL_ENTRY_NAME = "Default";
|
|
24
53
|
var MODAL_ICON_ASSET = "assets/training-modal/icon.svg";
|
|
@@ -29,22 +58,44 @@ var DEFAULT_GRACE = 24;
|
|
|
29
58
|
function legacyConfigured(config) {
|
|
30
59
|
return (config.tokenId ?? "").trim() !== "" || (config.tokenSecret ?? "").trim() !== "";
|
|
31
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Keychain / secretStatePaths may omit an empty `tokenSecret` from a stored
|
|
63
|
+
* row (writing `''` is KEEP, not "store empty"). Readers must never see
|
|
64
|
+
* `undefined` and then call `.trim()`.
|
|
65
|
+
*/
|
|
66
|
+
function secretAsString(value) {
|
|
67
|
+
return typeof value === "string" ? value : "";
|
|
68
|
+
}
|
|
69
|
+
function normalizeModalEntry(entry) {
|
|
70
|
+
return {
|
|
71
|
+
id: entry.id,
|
|
72
|
+
name: entry.name ?? "Default",
|
|
73
|
+
tokenId: entry.tokenId ?? "",
|
|
74
|
+
tokenSecret: secretAsString(entry.tokenSecret),
|
|
75
|
+
environment: entry.environment ?? "",
|
|
76
|
+
gpuType: entry.gpuType ?? DEFAULT_GPU,
|
|
77
|
+
region: entry.region ?? "",
|
|
78
|
+
costCapUsd: entry.costCapUsd ?? DEFAULT_COST,
|
|
79
|
+
maxRuntimeHours: entry.maxRuntimeHours ?? DEFAULT_HOURS,
|
|
80
|
+
failedDatasetGraceHours: entry.failedDatasetGraceHours ?? DEFAULT_GRACE
|
|
81
|
+
};
|
|
82
|
+
}
|
|
32
83
|
/** Entries the operator sees — synthesises Default from legacy flat fields. */
|
|
33
84
|
function effectiveModalEntries(config) {
|
|
34
|
-
if (config.entries.length > 0) return config.entries;
|
|
85
|
+
if (config.entries.length > 0) return config.entries.map((e) => normalizeModalEntry(e));
|
|
35
86
|
if (!legacyConfigured(config)) return [];
|
|
36
|
-
return [{
|
|
87
|
+
return [normalizeModalEntry({
|
|
37
88
|
id: "legacy-default",
|
|
38
89
|
name: DEFAULT_MODAL_ENTRY_NAME,
|
|
39
|
-
tokenId: config.tokenId
|
|
40
|
-
tokenSecret: config.tokenSecret
|
|
41
|
-
environment: config.environment
|
|
42
|
-
gpuType: config.gpuType
|
|
43
|
-
region: config.region
|
|
44
|
-
costCapUsd: config.costCapUsd
|
|
45
|
-
maxRuntimeHours: config.maxRuntimeHours
|
|
46
|
-
failedDatasetGraceHours: config.failedDatasetGraceHours
|
|
47
|
-
}];
|
|
90
|
+
tokenId: config.tokenId,
|
|
91
|
+
tokenSecret: config.tokenSecret,
|
|
92
|
+
environment: config.environment,
|
|
93
|
+
gpuType: config.gpuType,
|
|
94
|
+
region: config.region,
|
|
95
|
+
costCapUsd: config.costCapUsd,
|
|
96
|
+
maxRuntimeHours: config.maxRuntimeHours,
|
|
97
|
+
failedDatasetGraceHours: config.failedDatasetGraceHours
|
|
98
|
+
})];
|
|
48
99
|
}
|
|
49
100
|
function findModalEntry(config, entryId) {
|
|
50
101
|
return effectiveModalEntries(config).find((e) => e.id === entryId) ?? null;
|
|
@@ -249,20 +300,6 @@ function trainerDockerfileUrl(repo, revision) {
|
|
|
249
300
|
return `https://huggingface.co/${repo}/resolve/${revision}/Dockerfile`;
|
|
250
301
|
}
|
|
251
302
|
//#endregion
|
|
252
|
-
//#region src/providers/modal/modal-gateway.ts
|
|
253
|
-
var MODAL_APP_NAME = "camstack-training";
|
|
254
|
-
var MODAL_CACHE_VOLUME = "camstack-training-cache";
|
|
255
|
-
/** A small public image with `sh` and `cat`, for the staging / collector sandboxes. */
|
|
256
|
-
var MODAL_TOOLS_IMAGE = "alpine:3.20";
|
|
257
|
-
var ModalAuthError = class extends Error {
|
|
258
|
-
reason;
|
|
259
|
-
constructor(reason, message) {
|
|
260
|
-
super(message);
|
|
261
|
-
this.reason = reason;
|
|
262
|
-
this.name = "ModalAuthError";
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
//#endregion
|
|
266
303
|
//#region src/providers/modal/modal-pricing.ts
|
|
267
304
|
var MODAL_GPUS = [
|
|
268
305
|
{
|
|
@@ -340,6 +377,96 @@ function modalPricePerSecond(gpuType, region) {
|
|
|
340
377
|
return gpu === void 0 ? 0 : gpu.usdPerHour * multiplier / 3600;
|
|
341
378
|
}
|
|
342
379
|
//#endregion
|
|
380
|
+
//#region src/providers/modal/modal-entry-schema.ts
|
|
381
|
+
var MODAL_ENTRY_CONFIG_SCHEMA = { sections: [{
|
|
382
|
+
id: "credentials",
|
|
383
|
+
title: "Credentials",
|
|
384
|
+
fields: [
|
|
385
|
+
{
|
|
386
|
+
type: "text",
|
|
387
|
+
key: "tokenId",
|
|
388
|
+
label: "Token id",
|
|
389
|
+
placeholder: "ak-…"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
type: "password",
|
|
393
|
+
key: "tokenSecret",
|
|
394
|
+
label: "Token secret",
|
|
395
|
+
placeholder: "as-…",
|
|
396
|
+
showToggle: true
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
type: "text",
|
|
400
|
+
key: "environment",
|
|
401
|
+
label: "Environment",
|
|
402
|
+
placeholder: "Optional workspace environment"
|
|
403
|
+
}
|
|
404
|
+
]
|
|
405
|
+
}, {
|
|
406
|
+
id: "defaults",
|
|
407
|
+
title: "Defaults",
|
|
408
|
+
fields: [
|
|
409
|
+
{
|
|
410
|
+
type: "select",
|
|
411
|
+
key: "gpuType",
|
|
412
|
+
label: "GPU",
|
|
413
|
+
default: "L4",
|
|
414
|
+
options: MODAL_GPUS.map((g) => ({
|
|
415
|
+
value: g.id,
|
|
416
|
+
label: g.label
|
|
417
|
+
}))
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
type: "select",
|
|
421
|
+
key: "region",
|
|
422
|
+
label: "Region",
|
|
423
|
+
default: "",
|
|
424
|
+
options: MODAL_REGIONS.map((r) => ({
|
|
425
|
+
value: r.id,
|
|
426
|
+
label: r.label
|
|
427
|
+
}))
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
type: "number",
|
|
431
|
+
key: "costCapUsd",
|
|
432
|
+
label: "Cost cap (USD)",
|
|
433
|
+
default: 5,
|
|
434
|
+
min: 0,
|
|
435
|
+
step: .5
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
type: "number",
|
|
439
|
+
key: "maxRuntimeHours",
|
|
440
|
+
label: "Max runtime (hours)",
|
|
441
|
+
default: 4,
|
|
442
|
+
min: .1,
|
|
443
|
+
step: .5
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
type: "number",
|
|
447
|
+
key: "failedDatasetGraceHours",
|
|
448
|
+
label: "Failed-job dataset grace (hours)",
|
|
449
|
+
default: 24,
|
|
450
|
+
min: 0,
|
|
451
|
+
step: 1
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
}] };
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region src/providers/modal/modal-gateway.ts
|
|
457
|
+
var MODAL_APP_NAME = "camstack-training";
|
|
458
|
+
var MODAL_CACHE_VOLUME = "camstack-training-cache";
|
|
459
|
+
/** A small public image with `sh` and `cat`, for the staging / collector sandboxes. */
|
|
460
|
+
var MODAL_TOOLS_IMAGE = "alpine:3.20";
|
|
461
|
+
var ModalAuthError = class extends Error {
|
|
462
|
+
reason;
|
|
463
|
+
constructor(reason, message) {
|
|
464
|
+
super(message);
|
|
465
|
+
this.reason = reason;
|
|
466
|
+
this.name = "ModalAuthError";
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
//#endregion
|
|
343
470
|
//#region src/providers/modal/modal-provider.ts
|
|
344
471
|
/**
|
|
345
472
|
* The Modal `training-provider` (D807), over {@link ModalGateway}.
|
|
@@ -381,12 +508,16 @@ var ModalTrainingProvider = class {
|
|
|
381
508
|
constructor(deps) {
|
|
382
509
|
this.deps = deps;
|
|
383
510
|
}
|
|
384
|
-
describe = async () =>
|
|
511
|
+
describe = async () => {
|
|
512
|
+
const views = await this.deps.secretViews();
|
|
513
|
+
return this.deps.listEntries().map((entry) => this.descriptorOf(entry, views.get(entry.id) ?? null));
|
|
514
|
+
};
|
|
385
515
|
describeTypes = async () => [{
|
|
386
516
|
typeId: MODAL_TYPE_ID,
|
|
387
517
|
label: "Modal",
|
|
388
518
|
iconAsset: MODAL_ICON_ASSET,
|
|
389
|
-
addonId: this.deps.addonId
|
|
519
|
+
addonId: this.deps.addonId,
|
|
520
|
+
configSchema: MODAL_ENTRY_CONFIG_SCHEMA
|
|
390
521
|
}];
|
|
391
522
|
listEntries = async () => this.deps.listEntries().map((entry) => ({
|
|
392
523
|
entryId: entry.id,
|
|
@@ -397,10 +528,11 @@ var ModalTrainingProvider = class {
|
|
|
397
528
|
}));
|
|
398
529
|
createEntry = async (input) => this.deps.createEntry(input);
|
|
399
530
|
updateEntry = async (input) => {
|
|
531
|
+
const secret = input.tokenSecret === void 0 ? {} : require_dist.isSecretClear(input.tokenSecret) ? { clearTokenSecret: true } : input.tokenSecret === "" ? {} : { tokenSecret: input.tokenSecret };
|
|
400
532
|
await this.deps.updateEntry(input.entryId, {
|
|
401
533
|
name: input.name,
|
|
402
534
|
...input.tokenId !== void 0 ? { tokenId: input.tokenId } : {},
|
|
403
|
-
...
|
|
535
|
+
...secret,
|
|
404
536
|
...input.environment !== void 0 ? { environment: input.environment } : {},
|
|
405
537
|
...input.gpuType !== void 0 ? { gpuType: input.gpuType } : {},
|
|
406
538
|
...input.region !== void 0 ? { region: input.region } : {},
|
|
@@ -687,9 +819,15 @@ var ModalTrainingProvider = class {
|
|
|
687
819
|
}))];
|
|
688
820
|
};
|
|
689
821
|
entryConfigured(entry) {
|
|
690
|
-
|
|
822
|
+
const secret = typeof entry.tokenSecret === "string" ? entry.tokenSecret : "";
|
|
823
|
+
return (entry.tokenId ?? "").trim() !== "" && secret.trim() !== "";
|
|
691
824
|
}
|
|
692
|
-
descriptorOf(entry) {
|
|
825
|
+
descriptorOf(entry, tokenSecretView) {
|
|
826
|
+
const gpuType = entry.gpuType ?? "L4";
|
|
827
|
+
const region = entry.region ?? "";
|
|
828
|
+
const costCapUsd = entry.costCapUsd ?? 5;
|
|
829
|
+
const maxRuntimeHours = entry.maxRuntimeHours ?? 4;
|
|
830
|
+
const failedDatasetGraceHours = entry.failedDatasetGraceHours ?? 24;
|
|
693
831
|
return {
|
|
694
832
|
addonId: this.deps.addonId,
|
|
695
833
|
entryId: entry.id,
|
|
@@ -706,15 +844,22 @@ var ModalTrainingProvider = class {
|
|
|
706
844
|
dataResidencyNote: "Modal keeps the frames on a Volume of your workspace for the length of the job; the training container sees them only while it runs.",
|
|
707
845
|
configured: this.entryConfigured(entry),
|
|
708
846
|
defaults: {
|
|
709
|
-
gpuType
|
|
710
|
-
region
|
|
711
|
-
costCapUsd
|
|
712
|
-
maxRuntimeSec: Math.round(
|
|
713
|
-
failedDatasetGraceHours
|
|
847
|
+
gpuType,
|
|
848
|
+
region,
|
|
849
|
+
costCapUsd,
|
|
850
|
+
maxRuntimeSec: Math.round(maxRuntimeHours * 3600),
|
|
851
|
+
failedDatasetGraceHours
|
|
714
852
|
},
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
853
|
+
formValues: {
|
|
854
|
+
tokenId: entry.tokenId ?? "",
|
|
855
|
+
tokenSecret: tokenSecretView ?? "",
|
|
856
|
+
environment: entry.environment ?? "",
|
|
857
|
+
gpuType,
|
|
858
|
+
region,
|
|
859
|
+
costCapUsd,
|
|
860
|
+
maxRuntimeHours,
|
|
861
|
+
failedDatasetGraceHours
|
|
862
|
+
}
|
|
718
863
|
};
|
|
719
864
|
}
|
|
720
865
|
requireGateway(entryId) {
|
|
@@ -88588,9 +88733,15 @@ var TrainingModalAddon = class extends require_dist.BaseAddon {
|
|
|
88588
88733
|
}
|
|
88589
88734
|
async onInitialize() {
|
|
88590
88735
|
let next = this.config;
|
|
88591
|
-
|
|
88736
|
+
let migratedLegacy = false;
|
|
88737
|
+
if (next.entries.length === 0) {
|
|
88738
|
+
const migrated = migrateLegacyModalConfig(next, () => (0, node_crypto.randomUUID)());
|
|
88739
|
+
migratedLegacy = migrated !== next;
|
|
88740
|
+
next = migrated;
|
|
88741
|
+
}
|
|
88592
88742
|
next = ensureModalEntryIds(next, () => (0, node_crypto.randomUUID)());
|
|
88593
88743
|
if (next !== this.config) await this.updateGlobalSettings(next);
|
|
88744
|
+
if (migratedLegacy) await this.clearSecrets(["tokenSecret"]);
|
|
88594
88745
|
this.ledgerState = this.state(LEDGER_KEY, LedgerSchema, {});
|
|
88595
88746
|
const peer = this.ctx.peerBytes;
|
|
88596
88747
|
if (peer === void 0) throw new Error("training-modal needs the peer-bytes facility");
|
|
@@ -88606,17 +88757,27 @@ var TrainingModalAddon = class extends require_dist.BaseAddon {
|
|
|
88606
88757
|
return { entryId: result.entryId };
|
|
88607
88758
|
},
|
|
88608
88759
|
updateEntry: async (entryId, patch) => {
|
|
88609
|
-
const
|
|
88760
|
+
const { clearTokenSecret, ...rest } = patch;
|
|
88761
|
+
const result = updateModalEntry(this.config, entryId, rest);
|
|
88610
88762
|
if (!result.ok) throw new Error(`cannot update entry: ${result.reason}`);
|
|
88611
|
-
await this.updateGlobalSettings(
|
|
88763
|
+
if (clearTokenSecret === true) await this.updateGlobalSettings({
|
|
88764
|
+
...result.config,
|
|
88765
|
+
entries: result.config.entries.map((entry) => entry.id === entryId ? {
|
|
88766
|
+
...entry,
|
|
88767
|
+
tokenSecret: require_dist.SECRET_CLEAR
|
|
88768
|
+
} : entry)
|
|
88769
|
+
});
|
|
88770
|
+
else await this.updateGlobalSettings(result.config);
|
|
88612
88771
|
this.closeGateway(entryId);
|
|
88613
88772
|
},
|
|
88614
88773
|
deleteEntry: async (entryId) => {
|
|
88615
88774
|
const result = deleteModalEntry(this.config, entryId);
|
|
88616
88775
|
if (!result.ok) throw new Error(`cannot delete entry: ${result.reason}`);
|
|
88617
88776
|
await this.updateGlobalSettings(result.config);
|
|
88777
|
+
await this.clearSecrets(["tokenSecret"]);
|
|
88618
88778
|
this.closeGateway(entryId);
|
|
88619
88779
|
},
|
|
88780
|
+
secretViews: () => this.readEntrySecretViews(),
|
|
88620
88781
|
ledger: this.ledger(),
|
|
88621
88782
|
peer,
|
|
88622
88783
|
fetchText,
|
|
@@ -88625,7 +88786,10 @@ var TrainingModalAddon = class extends require_dist.BaseAddon {
|
|
|
88625
88786
|
});
|
|
88626
88787
|
this.ctx.logger.info("Modal training provider ready", { meta: {
|
|
88627
88788
|
entries: effectiveModalEntries(this.config).length,
|
|
88628
|
-
configured: effectiveModalEntries(this.config).some((e) =>
|
|
88789
|
+
configured: effectiveModalEntries(this.config).some((e) => {
|
|
88790
|
+
const secret = typeof e.tokenSecret === "string" ? e.tokenSecret : "";
|
|
88791
|
+
return (e.tokenId ?? "").trim() !== "" && secret.trim() !== "";
|
|
88792
|
+
})
|
|
88629
88793
|
} });
|
|
88630
88794
|
return { providers: [{
|
|
88631
88795
|
capability: require_dist.trainingProviderCapability,
|
|
@@ -88643,15 +88807,18 @@ var TrainingModalAddon = class extends require_dist.BaseAddon {
|
|
|
88643
88807
|
gatewayFor(entryId) {
|
|
88644
88808
|
const entry = findModalEntry(this.config, entryId);
|
|
88645
88809
|
if (entry === null) return null;
|
|
88646
|
-
|
|
88647
|
-
const
|
|
88810
|
+
const tokenId = (entry.tokenId ?? "").trim();
|
|
88811
|
+
const tokenSecret = (typeof entry.tokenSecret === "string" ? entry.tokenSecret : "").trim();
|
|
88812
|
+
if (tokenId === "" || tokenSecret === "") return null;
|
|
88813
|
+
const environment = (entry.environment ?? "").trim();
|
|
88814
|
+
const key = `${tokenId}\u0000${environment}`;
|
|
88648
88815
|
const cached = this.gateways.get(entryId);
|
|
88649
88816
|
if (cached !== void 0 && cached.key === key) return cached.gateway;
|
|
88650
88817
|
cached?.gateway.close();
|
|
88651
88818
|
const gateway = new ModalSdkGateway({
|
|
88652
|
-
tokenId
|
|
88653
|
-
tokenSecret
|
|
88654
|
-
environment
|
|
88819
|
+
tokenId,
|
|
88820
|
+
tokenSecret,
|
|
88821
|
+
environment
|
|
88655
88822
|
});
|
|
88656
88823
|
this.gateways.set(entryId, {
|
|
88657
88824
|
key,
|
|
@@ -88665,6 +88832,19 @@ var TrainingModalAddon = class extends require_dist.BaseAddon {
|
|
|
88665
88832
|
cached.gateway.close();
|
|
88666
88833
|
this.gateways.delete(entryId);
|
|
88667
88834
|
}
|
|
88835
|
+
/**
|
|
88836
|
+
* Keychain views for the Providers edit form. Addon-facing reads answer
|
|
88837
|
+
* VALUES (D798), so we cannot recover markers from `readStoredGlobalKey`.
|
|
88838
|
+
* When a secret is present on the resolved entry we emit the deterministic
|
|
88839
|
+
* keychain ref (`ctx.secrets.ref`) so `SecretFieldControl` can reveal.
|
|
88840
|
+
*/
|
|
88841
|
+
async readEntrySecretViews() {
|
|
88842
|
+
const map = /* @__PURE__ */ new Map();
|
|
88843
|
+
const secrets = this.ctx.secrets;
|
|
88844
|
+
for (const entry of effectiveModalEntries(this.config)) map.set(entry.id, entryTokenSecretView(entry.tokenSecret, secrets, entry.id));
|
|
88845
|
+
map.set("legacy-default", flatTokenSecretView(this.config.tokenSecret, secrets));
|
|
88846
|
+
return map;
|
|
88847
|
+
}
|
|
88668
88848
|
ledger() {
|
|
88669
88849
|
const state = () => {
|
|
88670
88850
|
if (this.ledgerState === null) throw new Error("training-modal ledger not initialised");
|