@camstack/addon-training 0.1.21 → 0.1.23
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-BokARvOj.mjs +13806 -0
- package/dist/MotionZonesSettings-CwGjtvsX.mjs +310 -0
- package/dist/{PrivacyMaskSettings-Bo1S23wt.mjs → PrivacyMaskSettings-CM_WsrKB.mjs} +70 -45
- package/dist/{SceneMonitorEditor-DnQJ7Hx3.mjs → SceneMonitorEditor-B-sAJ--C.mjs} +311 -311
- package/dist/_stub.js +7372 -16803
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-DQi_LrZZ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-DKblQaAP.mjs} +2 -2
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-ff7X-Xlf.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BSOdwqcC.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-B3rryujf.mjs +25 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-nL4MGFRP.mjs +26 -0
- package/dist/{_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs → _virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs} +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-CK-LlgOt.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-gTIQrhKs.mjs +25 -0
- package/dist/{dist-BSYBh1ZO.mjs → dist-CVDWIKl7.mjs} +52 -2
- package/dist/{dist-BCLkrWJc.js → dist-DwF1P1v7.js} +87 -1
- package/dist/{hostInit-Bx2a8M7w.mjs → hostInit-Di0tDODX.mjs} +1 -1
- package/dist/index.js +8 -1
- package/dist/index.mjs +7 -0
- package/dist/orchestrator/training.addon.js +8 -1
- package/dist/orchestrator/training.addon.mjs +8 -1
- package/dist/{player-overlays-BR2_H0wZ.mjs → player-overlays-BFAqW2L1.mjs} +10 -32
- package/dist/providers/modal/training-modal.addon.js +196 -123
- package/dist/providers/modal/training-modal.addon.mjs +196 -123
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-emJo3EdF.mjs → responsive-BBlQWFFi.mjs} +38 -42
- package/dist/{scene-monitor-copy-CcQxbRXa.mjs → scene-monitor-copy-D5mKGqt0.mjs} +4 -4
- package/dist/{square-CErp1WgN.mjs → square-D0FYSm8b.mjs} +4 -29
- package/dist/{trash-2-Drz0fMgI.mjs → trash-2-DdjGvgDw.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-C-uqIKLg.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-Dw400Y0a.mjs} +390 -399
- package/package.json +1 -1
- package/dist/MaskShapeCanvas-Kfg9dl6B.mjs +0 -686
- package/dist/MotionZonesSettings-DflIL9ss.mjs +0 -292
- package/dist/ReactKonva-DGuYUN0L.mjs +0 -5416
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C7dks3FG.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DpjirGmB.mjs +0 -89
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-CFCVuRAs.mjs +0 -58
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-BkvDudqY.mjs +0 -62
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs +0 -34
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-DAZkHxxU.mjs +0 -45
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-CHqN9NLt.mjs +0 -34
- package/dist/grid-2x2-D9syAI6z.mjs +0 -21
- package/dist/lib-CVGFTwe0.mjs +0 -7770
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as trainingProviderCapability, d as
|
|
1
|
+
import { _ as number, b as string, c as trainingProviderCapability, d as arrayItemFieldPath, f as globalSecretScope, g as boolean, h as toSecretFieldView, l as BaseAddon, m as isSecretMarker, p as isSecretClear, u as SECRET_CLEAR, v as object, y as record } from "../../dist-CVDWIKl7.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import path, { dirname, posix } from "node:path";
|
|
4
4
|
import { createHash, createPrivateKey, createPublicKey, createSign, randomBytes, randomUUID } from "node:crypto";
|
|
@@ -39,14 +39,43 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
39
39
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
40
40
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
41
41
|
//#endregion
|
|
42
|
-
//#region src/providers/modal/
|
|
42
|
+
//#region src/providers/modal/entry-secret-view.ts
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
44
|
+
* Build the {@link SecretFieldView} the Providers edit form needs for an
|
|
45
|
+
* entry's token secret.
|
|
46
46
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
47
|
+
* `readStoredGlobalKey` / `this.config` answer VALUES (D798), never markers —
|
|
48
|
+
* so `toSecretFieldView(plaintext)` alone yields an inline view (`$secret:
|
|
49
|
+
* null`) and `SecretFieldControl` cannot reveal. When the secret is set we
|
|
50
|
+
* prefer the deterministic keychain ref (`ctx.secrets.ref`) so the eye can
|
|
51
|
+
* call `keychain-admin.reveal` (D789).
|
|
49
52
|
*/
|
|
53
|
+
/** View for one entry row, or `null` when nothing is stored. */
|
|
54
|
+
function entryTokenSecretView(tokenSecret, secrets, entryId) {
|
|
55
|
+
if (isSecretMarker(tokenSecret)) return toSecretFieldView(tokenSecret);
|
|
56
|
+
const plain = typeof tokenSecret === "string" ? tokenSecret.trim() : "";
|
|
57
|
+
if (plain === "") return null;
|
|
58
|
+
if (secrets === void 0) return toSecretFieldView(plain);
|
|
59
|
+
return {
|
|
60
|
+
$secret: secrets.ref(globalSecretScope(), arrayItemFieldPath("entries", entryId, "tokenSecret")),
|
|
61
|
+
v: 1,
|
|
62
|
+
set: true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** View for the legacy flat `tokenSecret` (pre-multi-entry Default). */
|
|
66
|
+
function flatTokenSecretView(tokenSecret, secrets) {
|
|
67
|
+
if (isSecretMarker(tokenSecret)) return toSecretFieldView(tokenSecret);
|
|
68
|
+
const plain = typeof tokenSecret === "string" ? tokenSecret.trim() : "";
|
|
69
|
+
if (plain === "") return null;
|
|
70
|
+
if (secrets === void 0) return toSecretFieldView(plain);
|
|
71
|
+
return {
|
|
72
|
+
$secret: secrets.ref(globalSecretScope(), "tokenSecret"),
|
|
73
|
+
v: 1,
|
|
74
|
+
set: true
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/providers/modal/modal-entries.ts
|
|
50
79
|
var MODAL_TYPE_ID = "modal";
|
|
51
80
|
var DEFAULT_MODAL_ENTRY_NAME = "Default";
|
|
52
81
|
var MODAL_ICON_ASSET = "assets/training-modal/icon.svg";
|
|
@@ -57,22 +86,44 @@ var DEFAULT_GRACE = 24;
|
|
|
57
86
|
function legacyConfigured(config) {
|
|
58
87
|
return (config.tokenId ?? "").trim() !== "" || (config.tokenSecret ?? "").trim() !== "";
|
|
59
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Keychain / secretStatePaths may omit an empty `tokenSecret` from a stored
|
|
91
|
+
* row (writing `''` is KEEP, not "store empty"). Readers must never see
|
|
92
|
+
* `undefined` and then call `.trim()`.
|
|
93
|
+
*/
|
|
94
|
+
function secretAsString(value) {
|
|
95
|
+
return typeof value === "string" ? value : "";
|
|
96
|
+
}
|
|
97
|
+
function normalizeModalEntry(entry) {
|
|
98
|
+
return {
|
|
99
|
+
id: entry.id,
|
|
100
|
+
name: entry.name ?? "Default",
|
|
101
|
+
tokenId: entry.tokenId ?? "",
|
|
102
|
+
tokenSecret: secretAsString(entry.tokenSecret),
|
|
103
|
+
environment: entry.environment ?? "",
|
|
104
|
+
gpuType: entry.gpuType ?? DEFAULT_GPU,
|
|
105
|
+
region: entry.region ?? "",
|
|
106
|
+
costCapUsd: entry.costCapUsd ?? DEFAULT_COST,
|
|
107
|
+
maxRuntimeHours: entry.maxRuntimeHours ?? DEFAULT_HOURS,
|
|
108
|
+
failedDatasetGraceHours: entry.failedDatasetGraceHours ?? DEFAULT_GRACE
|
|
109
|
+
};
|
|
110
|
+
}
|
|
60
111
|
/** Entries the operator sees — synthesises Default from legacy flat fields. */
|
|
61
112
|
function effectiveModalEntries(config) {
|
|
62
|
-
if (config.entries.length > 0) return config.entries;
|
|
113
|
+
if (config.entries.length > 0) return config.entries.map((e) => normalizeModalEntry(e));
|
|
63
114
|
if (!legacyConfigured(config)) return [];
|
|
64
|
-
return [{
|
|
115
|
+
return [normalizeModalEntry({
|
|
65
116
|
id: "legacy-default",
|
|
66
117
|
name: DEFAULT_MODAL_ENTRY_NAME,
|
|
67
|
-
tokenId: config.tokenId
|
|
68
|
-
tokenSecret: config.tokenSecret
|
|
69
|
-
environment: config.environment
|
|
70
|
-
gpuType: config.gpuType
|
|
71
|
-
region: config.region
|
|
72
|
-
costCapUsd: config.costCapUsd
|
|
73
|
-
maxRuntimeHours: config.maxRuntimeHours
|
|
74
|
-
failedDatasetGraceHours: config.failedDatasetGraceHours
|
|
75
|
-
}];
|
|
118
|
+
tokenId: config.tokenId,
|
|
119
|
+
tokenSecret: config.tokenSecret,
|
|
120
|
+
environment: config.environment,
|
|
121
|
+
gpuType: config.gpuType,
|
|
122
|
+
region: config.region,
|
|
123
|
+
costCapUsd: config.costCapUsd,
|
|
124
|
+
maxRuntimeHours: config.maxRuntimeHours,
|
|
125
|
+
failedDatasetGraceHours: config.failedDatasetGraceHours
|
|
126
|
+
})];
|
|
76
127
|
}
|
|
77
128
|
function findModalEntry(config, entryId) {
|
|
78
129
|
return effectiveModalEntries(config).find((e) => e.id === entryId) ?? null;
|
|
@@ -156,6 +207,43 @@ function deleteModalEntry(config, entryId) {
|
|
|
156
207
|
}
|
|
157
208
|
};
|
|
158
209
|
}
|
|
210
|
+
function updateModalEntry(config, entryId, patch) {
|
|
211
|
+
const current = [...effectiveModalEntries(config)];
|
|
212
|
+
const index = current.findIndex((e) => e.id === entryId);
|
|
213
|
+
if (index < 0) return {
|
|
214
|
+
ok: false,
|
|
215
|
+
reason: "unknown-entry"
|
|
216
|
+
};
|
|
217
|
+
const prev = current[index];
|
|
218
|
+
const secret = patch.tokenSecret !== void 0 && patch.tokenSecret !== "" ? patch.tokenSecret : prev.tokenSecret;
|
|
219
|
+
current[index] = {
|
|
220
|
+
id: prev.id,
|
|
221
|
+
name: patch.name !== void 0 ? patch.name : prev.name,
|
|
222
|
+
tokenId: patch.tokenId !== void 0 ? patch.tokenId : prev.tokenId,
|
|
223
|
+
tokenSecret: secret,
|
|
224
|
+
environment: patch.environment !== void 0 ? patch.environment : prev.environment,
|
|
225
|
+
gpuType: patch.gpuType !== void 0 ? patch.gpuType : prev.gpuType,
|
|
226
|
+
region: patch.region !== void 0 ? patch.region : prev.region,
|
|
227
|
+
costCapUsd: patch.costCapUsd !== void 0 ? patch.costCapUsd : prev.costCapUsd,
|
|
228
|
+
maxRuntimeHours: patch.maxRuntimeHours !== void 0 ? patch.maxRuntimeHours : prev.maxRuntimeHours,
|
|
229
|
+
failedDatasetGraceHours: patch.failedDatasetGraceHours !== void 0 ? patch.failedDatasetGraceHours : prev.failedDatasetGraceHours
|
|
230
|
+
};
|
|
231
|
+
return {
|
|
232
|
+
ok: true,
|
|
233
|
+
entryId,
|
|
234
|
+
config: {
|
|
235
|
+
entries: current,
|
|
236
|
+
tokenId: "",
|
|
237
|
+
tokenSecret: "",
|
|
238
|
+
environment: config.environment ?? "",
|
|
239
|
+
gpuType: config.gpuType ?? DEFAULT_GPU,
|
|
240
|
+
region: config.region ?? "",
|
|
241
|
+
costCapUsd: config.costCapUsd ?? DEFAULT_COST,
|
|
242
|
+
maxRuntimeHours: config.maxRuntimeHours ?? DEFAULT_HOURS,
|
|
243
|
+
failedDatasetGraceHours: config.failedDatasetGraceHours ?? DEFAULT_GRACE
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
159
247
|
/**
|
|
160
248
|
* Mint a stable id for every persisted entry that lacks one. Operator-typed
|
|
161
249
|
* empty ids (legacy settings UI) must never stay empty — createEntry always
|
|
@@ -372,7 +460,10 @@ var ModalTrainingProvider = class {
|
|
|
372
460
|
constructor(deps) {
|
|
373
461
|
this.deps = deps;
|
|
374
462
|
}
|
|
375
|
-
describe = async () =>
|
|
463
|
+
describe = async () => {
|
|
464
|
+
const views = await this.deps.secretViews();
|
|
465
|
+
return this.deps.listEntries().map((entry) => this.descriptorOf(entry, views.get(entry.id) ?? null));
|
|
466
|
+
};
|
|
376
467
|
describeTypes = async () => [{
|
|
377
468
|
typeId: MODAL_TYPE_ID,
|
|
378
469
|
label: "Modal",
|
|
@@ -387,6 +478,21 @@ var ModalTrainingProvider = class {
|
|
|
387
478
|
configured: this.entryConfigured(entry)
|
|
388
479
|
}));
|
|
389
480
|
createEntry = async (input) => this.deps.createEntry(input);
|
|
481
|
+
updateEntry = async (input) => {
|
|
482
|
+
const secret = input.tokenSecret === void 0 ? {} : isSecretClear(input.tokenSecret) ? { clearTokenSecret: true } : input.tokenSecret === "" ? {} : { tokenSecret: input.tokenSecret };
|
|
483
|
+
await this.deps.updateEntry(input.entryId, {
|
|
484
|
+
name: input.name,
|
|
485
|
+
...input.tokenId !== void 0 ? { tokenId: input.tokenId } : {},
|
|
486
|
+
...secret,
|
|
487
|
+
...input.environment !== void 0 ? { environment: input.environment } : {},
|
|
488
|
+
...input.gpuType !== void 0 ? { gpuType: input.gpuType } : {},
|
|
489
|
+
...input.region !== void 0 ? { region: input.region } : {},
|
|
490
|
+
...input.costCapUsd !== void 0 ? { costCapUsd: input.costCapUsd } : {},
|
|
491
|
+
...input.maxRuntimeSec !== void 0 ? { maxRuntimeHours: input.maxRuntimeSec / 3600 } : {},
|
|
492
|
+
...input.failedDatasetGraceHours !== void 0 ? { failedDatasetGraceHours: input.failedDatasetGraceHours } : {}
|
|
493
|
+
});
|
|
494
|
+
return { ok: true };
|
|
495
|
+
};
|
|
390
496
|
deleteEntry = async (input) => {
|
|
391
497
|
await this.deps.deleteEntry(input.entryId);
|
|
392
498
|
return { ok: true };
|
|
@@ -664,9 +770,12 @@ var ModalTrainingProvider = class {
|
|
|
664
770
|
}))];
|
|
665
771
|
};
|
|
666
772
|
entryConfigured(entry) {
|
|
667
|
-
|
|
773
|
+
const secret = typeof entry.tokenSecret === "string" ? entry.tokenSecret : "";
|
|
774
|
+
return (entry.tokenId ?? "").trim() !== "" && secret.trim() !== "";
|
|
668
775
|
}
|
|
669
|
-
descriptorOf(entry) {
|
|
776
|
+
descriptorOf(entry, tokenSecretView) {
|
|
777
|
+
const tokenId = entry.tokenId ?? "";
|
|
778
|
+
const environment = entry.environment ?? "";
|
|
670
779
|
return {
|
|
671
780
|
addonId: this.deps.addonId,
|
|
672
781
|
entryId: entry.id,
|
|
@@ -683,12 +792,16 @@ var ModalTrainingProvider = class {
|
|
|
683
792
|
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.",
|
|
684
793
|
configured: this.entryConfigured(entry),
|
|
685
794
|
defaults: {
|
|
686
|
-
gpuType: entry.gpuType,
|
|
687
|
-
region: entry.region,
|
|
688
|
-
costCapUsd: entry.costCapUsd,
|
|
689
|
-
maxRuntimeSec: Math.round(entry.maxRuntimeHours * 3600),
|
|
690
|
-
failedDatasetGraceHours: entry.failedDatasetGraceHours
|
|
691
|
-
}
|
|
795
|
+
gpuType: entry.gpuType ?? "L4",
|
|
796
|
+
region: entry.region ?? "",
|
|
797
|
+
costCapUsd: entry.costCapUsd ?? 5,
|
|
798
|
+
maxRuntimeSec: Math.round((entry.maxRuntimeHours ?? 4) * 3600),
|
|
799
|
+
failedDatasetGraceHours: entry.failedDatasetGraceHours ?? 24
|
|
800
|
+
},
|
|
801
|
+
tokenId,
|
|
802
|
+
environment,
|
|
803
|
+
hasTokenSecret: tokenSecretView !== null,
|
|
804
|
+
tokenSecretView
|
|
692
805
|
};
|
|
693
806
|
}
|
|
694
807
|
requireGateway(entryId) {
|
|
@@ -88541,6 +88654,12 @@ async function fetchText(url) {
|
|
|
88541
88654
|
var TrainingModalAddon = class extends BaseAddon {
|
|
88542
88655
|
ledgerState = null;
|
|
88543
88656
|
gateways = /* @__PURE__ */ new Map();
|
|
88657
|
+
/**
|
|
88658
|
+
* Entry secrets live on `entries[id].tokenSecret` (and legacy flat
|
|
88659
|
+
* `tokenSecret`). Declared here — not via an editable-array form — so the
|
|
88660
|
+
* Training → Providers page is the only UI that edits entries.
|
|
88661
|
+
*/
|
|
88662
|
+
secretStatePaths = ["entries[id].tokenSecret", "tokenSecret"];
|
|
88544
88663
|
constructor() {
|
|
88545
88664
|
super({
|
|
88546
88665
|
entries: [],
|
|
@@ -88556,9 +88675,15 @@ var TrainingModalAddon = class extends BaseAddon {
|
|
|
88556
88675
|
}
|
|
88557
88676
|
async onInitialize() {
|
|
88558
88677
|
let next = this.config;
|
|
88559
|
-
|
|
88678
|
+
let migratedLegacy = false;
|
|
88679
|
+
if (next.entries.length === 0) {
|
|
88680
|
+
const migrated = migrateLegacyModalConfig(next, () => randomUUID());
|
|
88681
|
+
migratedLegacy = migrated !== next;
|
|
88682
|
+
next = migrated;
|
|
88683
|
+
}
|
|
88560
88684
|
next = ensureModalEntryIds(next, () => randomUUID());
|
|
88561
88685
|
if (next !== this.config) await this.updateGlobalSettings(next);
|
|
88686
|
+
if (migratedLegacy) await this.clearSecrets(["tokenSecret"]);
|
|
88562
88687
|
this.ledgerState = this.state(LEDGER_KEY, LedgerSchema, {});
|
|
88563
88688
|
const peer = this.ctx.peerBytes;
|
|
88564
88689
|
if (peer === void 0) throw new Error("training-modal needs the peer-bytes facility");
|
|
@@ -88573,12 +88698,28 @@ var TrainingModalAddon = class extends BaseAddon {
|
|
|
88573
88698
|
await this.updateGlobalSettings(result.config);
|
|
88574
88699
|
return { entryId: result.entryId };
|
|
88575
88700
|
},
|
|
88701
|
+
updateEntry: async (entryId, patch) => {
|
|
88702
|
+
const { clearTokenSecret, ...rest } = patch;
|
|
88703
|
+
const result = updateModalEntry(this.config, entryId, rest);
|
|
88704
|
+
if (!result.ok) throw new Error(`cannot update entry: ${result.reason}`);
|
|
88705
|
+
if (clearTokenSecret === true) await this.updateGlobalSettings({
|
|
88706
|
+
...result.config,
|
|
88707
|
+
entries: result.config.entries.map((entry) => entry.id === entryId ? {
|
|
88708
|
+
...entry,
|
|
88709
|
+
tokenSecret: SECRET_CLEAR
|
|
88710
|
+
} : entry)
|
|
88711
|
+
});
|
|
88712
|
+
else await this.updateGlobalSettings(result.config);
|
|
88713
|
+
this.closeGateway(entryId);
|
|
88714
|
+
},
|
|
88576
88715
|
deleteEntry: async (entryId) => {
|
|
88577
88716
|
const result = deleteModalEntry(this.config, entryId);
|
|
88578
88717
|
if (!result.ok) throw new Error(`cannot delete entry: ${result.reason}`);
|
|
88579
88718
|
await this.updateGlobalSettings(result.config);
|
|
88719
|
+
await this.clearSecrets(["tokenSecret"]);
|
|
88580
88720
|
this.closeGateway(entryId);
|
|
88581
88721
|
},
|
|
88722
|
+
secretViews: () => this.readEntrySecretViews(),
|
|
88582
88723
|
ledger: this.ledger(),
|
|
88583
88724
|
peer,
|
|
88584
88725
|
fetchText,
|
|
@@ -88587,7 +88728,10 @@ var TrainingModalAddon = class extends BaseAddon {
|
|
|
88587
88728
|
});
|
|
88588
88729
|
this.ctx.logger.info("Modal training provider ready", { meta: {
|
|
88589
88730
|
entries: effectiveModalEntries(this.config).length,
|
|
88590
|
-
configured: effectiveModalEntries(this.config).some((e) =>
|
|
88731
|
+
configured: effectiveModalEntries(this.config).some((e) => {
|
|
88732
|
+
const secret = typeof e.tokenSecret === "string" ? e.tokenSecret : "";
|
|
88733
|
+
return (e.tokenId ?? "").trim() !== "" && secret.trim() !== "";
|
|
88734
|
+
})
|
|
88591
88735
|
} });
|
|
88592
88736
|
return { providers: [{
|
|
88593
88737
|
capability: trainingProviderCapability,
|
|
@@ -88605,15 +88749,18 @@ var TrainingModalAddon = class extends BaseAddon {
|
|
|
88605
88749
|
gatewayFor(entryId) {
|
|
88606
88750
|
const entry = findModalEntry(this.config, entryId);
|
|
88607
88751
|
if (entry === null) return null;
|
|
88608
|
-
|
|
88609
|
-
const
|
|
88752
|
+
const tokenId = (entry.tokenId ?? "").trim();
|
|
88753
|
+
const tokenSecret = (typeof entry.tokenSecret === "string" ? entry.tokenSecret : "").trim();
|
|
88754
|
+
if (tokenId === "" || tokenSecret === "") return null;
|
|
88755
|
+
const environment = (entry.environment ?? "").trim();
|
|
88756
|
+
const key = `${tokenId}\u0000${environment}`;
|
|
88610
88757
|
const cached = this.gateways.get(entryId);
|
|
88611
88758
|
if (cached !== void 0 && cached.key === key) return cached.gateway;
|
|
88612
88759
|
cached?.gateway.close();
|
|
88613
88760
|
const gateway = new ModalSdkGateway({
|
|
88614
|
-
tokenId
|
|
88615
|
-
tokenSecret
|
|
88616
|
-
environment
|
|
88761
|
+
tokenId,
|
|
88762
|
+
tokenSecret,
|
|
88763
|
+
environment
|
|
88617
88764
|
});
|
|
88618
88765
|
this.gateways.set(entryId, {
|
|
88619
88766
|
key,
|
|
@@ -88627,6 +88774,19 @@ var TrainingModalAddon = class extends BaseAddon {
|
|
|
88627
88774
|
cached.gateway.close();
|
|
88628
88775
|
this.gateways.delete(entryId);
|
|
88629
88776
|
}
|
|
88777
|
+
/**
|
|
88778
|
+
* Keychain views for the Providers edit form. Addon-facing reads answer
|
|
88779
|
+
* VALUES (D798), so we cannot recover markers from `readStoredGlobalKey`.
|
|
88780
|
+
* When a secret is present on the resolved entry we emit the deterministic
|
|
88781
|
+
* keychain ref (`ctx.secrets.ref`) so `SecretFieldControl` can reveal.
|
|
88782
|
+
*/
|
|
88783
|
+
async readEntrySecretViews() {
|
|
88784
|
+
const map = /* @__PURE__ */ new Map();
|
|
88785
|
+
const secrets = this.ctx.secrets;
|
|
88786
|
+
for (const entry of effectiveModalEntries(this.config)) map.set(entry.id, entryTokenSecretView(entry.tokenSecret, secrets, entry.id));
|
|
88787
|
+
map.set("legacy-default", flatTokenSecretView(this.config.tokenSecret, secrets));
|
|
88788
|
+
return map;
|
|
88789
|
+
}
|
|
88630
88790
|
ledger() {
|
|
88631
88791
|
const state = () => {
|
|
88632
88792
|
if (this.ledgerState === null) throw new Error("training-modal ledger not initialised");
|
|
@@ -88651,97 +88811,10 @@ var TrainingModalAddon = class extends BaseAddon {
|
|
|
88651
88811
|
}
|
|
88652
88812
|
globalSettingsSchema() {
|
|
88653
88813
|
return this.schema({ sections: [{
|
|
88654
|
-
id: "
|
|
88814
|
+
id: "providers",
|
|
88655
88815
|
title: "Modal accounts",
|
|
88656
|
-
description: "
|
|
88657
|
-
fields: [
|
|
88658
|
-
type: "editable-array",
|
|
88659
|
-
key: "entries",
|
|
88660
|
-
label: "Entries",
|
|
88661
|
-
itemIdKey: "id",
|
|
88662
|
-
/** Create only via trainingProvider.createEntry (auto id). */
|
|
88663
|
-
maxRows: 0,
|
|
88664
|
-
emptyMessage: "No Modal entries yet — add one from Training → Providers.",
|
|
88665
|
-
rowTitleTemplate: "{name}",
|
|
88666
|
-
defaultItem: {
|
|
88667
|
-
id: "",
|
|
88668
|
-
name: "Default",
|
|
88669
|
-
tokenId: "",
|
|
88670
|
-
tokenSecret: "",
|
|
88671
|
-
environment: "",
|
|
88672
|
-
gpuType: "L4",
|
|
88673
|
-
region: "",
|
|
88674
|
-
costCapUsd: 5,
|
|
88675
|
-
maxRuntimeHours: 4,
|
|
88676
|
-
failedDatasetGraceHours: 24
|
|
88677
|
-
},
|
|
88678
|
-
itemFields: [
|
|
88679
|
-
{
|
|
88680
|
-
type: "text",
|
|
88681
|
-
key: "name",
|
|
88682
|
-
label: "Name"
|
|
88683
|
-
},
|
|
88684
|
-
{
|
|
88685
|
-
type: "text",
|
|
88686
|
-
key: "tokenId",
|
|
88687
|
-
label: "Token id",
|
|
88688
|
-
placeholder: "ak-…"
|
|
88689
|
-
},
|
|
88690
|
-
{
|
|
88691
|
-
type: "password",
|
|
88692
|
-
key: "tokenSecret",
|
|
88693
|
-
label: "Token secret",
|
|
88694
|
-
showToggle: true
|
|
88695
|
-
},
|
|
88696
|
-
{
|
|
88697
|
-
type: "text",
|
|
88698
|
-
key: "environment",
|
|
88699
|
-
label: "Environment",
|
|
88700
|
-
description: "Leave empty for the workspace default."
|
|
88701
|
-
},
|
|
88702
|
-
{
|
|
88703
|
-
type: "select",
|
|
88704
|
-
key: "gpuType",
|
|
88705
|
-
label: "GPU",
|
|
88706
|
-
options: MODAL_GPUS.map((g) => ({
|
|
88707
|
-
value: g.id,
|
|
88708
|
-
label: `${g.label} — $${g.usdPerHour.toFixed(2)}/h`
|
|
88709
|
-
}))
|
|
88710
|
-
},
|
|
88711
|
-
{
|
|
88712
|
-
type: "select",
|
|
88713
|
-
key: "region",
|
|
88714
|
-
label: "Region",
|
|
88715
|
-
options: MODAL_REGIONS.map((r) => ({
|
|
88716
|
-
value: r.id,
|
|
88717
|
-
label: r.label
|
|
88718
|
-
}))
|
|
88719
|
-
},
|
|
88720
|
-
{
|
|
88721
|
-
type: "number",
|
|
88722
|
-
key: "costCapUsd",
|
|
88723
|
-
label: "Cost cap per job (USD)",
|
|
88724
|
-
min: .5,
|
|
88725
|
-
step: .5
|
|
88726
|
-
},
|
|
88727
|
-
{
|
|
88728
|
-
type: "number",
|
|
88729
|
-
key: "maxRuntimeHours",
|
|
88730
|
-
label: "Maximum runtime (hours)",
|
|
88731
|
-
min: .5,
|
|
88732
|
-
max: 24,
|
|
88733
|
-
step: .5
|
|
88734
|
-
},
|
|
88735
|
-
{
|
|
88736
|
-
type: "number",
|
|
88737
|
-
key: "failedDatasetGraceHours",
|
|
88738
|
-
label: "Keep a failed job’s dataset (hours)",
|
|
88739
|
-
min: 0,
|
|
88740
|
-
max: 168,
|
|
88741
|
-
step: 1
|
|
88742
|
-
}
|
|
88743
|
-
]
|
|
88744
|
-
}]
|
|
88816
|
+
description: "Create and edit Modal workspace entries under Training → Providers. Credentials stay in the CamStack keychain.",
|
|
88817
|
+
fields: []
|
|
88745
88818
|
}] });
|
|
88746
88819
|
}
|
|
88747
88820
|
};
|
package/dist/remoteEntry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-
|
|
1
|
+
import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-Dw400Y0a.mjs";
|
|
2
2
|
export { t as get, e as init };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-
|
|
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_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs";
|
|
2
|
+
import { a as u } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-ff7X-Xlf.mjs";
|
|
3
|
+
import "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.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) => {
|
|
7
7
|
let t = p(e);
|
|
8
8
|
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
@@ -19,7 +19,7 @@ var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
|
|
|
19
19
|
}, g = (e) => {
|
|
20
20
|
for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
|
|
21
21
|
return !1;
|
|
22
|
-
}, _ =
|
|
22
|
+
}, _ = s(({ color: e = "currentColor", size: t = 24, strokeWidth: n = 2, absoluteStrokeWidth: r, className: i = "", children: a, iconNode: s, ...c }, l) => o("svg", {
|
|
23
23
|
ref: l,
|
|
24
24
|
...h,
|
|
25
25
|
width: t,
|
|
@@ -27,14 +27,14 @@ var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
|
|
|
27
27
|
stroke: e,
|
|
28
28
|
strokeWidth: r ? Number(n) * 24 / Number(t) : n,
|
|
29
29
|
className: d("lucide", i),
|
|
30
|
-
...!
|
|
30
|
+
...!a && !g(c) && { "aria-hidden": "true" },
|
|
31
31
|
...c
|
|
32
|
-
}, [...s.map(([e, t]) =>
|
|
32
|
+
}, [...s.map(([e, t]) => o(e, t)), ...Array.isArray(a) ? a : [a]]));
|
|
33
33
|
//#endregion
|
|
34
34
|
//#region ../../node_modules/lucide-react/dist/esm/createLucideIcon.js
|
|
35
|
-
|
|
35
|
+
t();
|
|
36
36
|
var v = (e, t) => {
|
|
37
|
-
let n =
|
|
37
|
+
let n = s(({ className: n, ...r }, i) => o(_, {
|
|
38
38
|
ref: i,
|
|
39
39
|
iconNode: t,
|
|
40
40
|
className: d(`lucide-${f(m(e))}`, `lucide-${e}`, n),
|
|
@@ -44,69 +44,65 @@ var v = (e, t) => {
|
|
|
44
44
|
};
|
|
45
45
|
//#endregion
|
|
46
46
|
//#region ../ui-library/src/lib/shared-context.ts
|
|
47
|
-
|
|
47
|
+
t();
|
|
48
48
|
function y(e, t) {
|
|
49
|
-
if (typeof globalThis > "u") return
|
|
49
|
+
if (typeof globalThis > "u") return c(t);
|
|
50
50
|
let n = globalThis.__camstackSharedContexts, r = n ?? /* @__PURE__ */ new Map();
|
|
51
51
|
n || (globalThis.__camstackSharedContexts = r);
|
|
52
52
|
let i = r.get(e);
|
|
53
53
|
if (i) return i;
|
|
54
|
-
let a =
|
|
54
|
+
let a = c(t);
|
|
55
55
|
return r.set(e, a), a;
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
58
|
//#region ../ui-library/src/contexts/system-context.tsx
|
|
59
|
-
|
|
59
|
+
t();
|
|
60
60
|
var b = y("camstack:system", null);
|
|
61
61
|
function x() {
|
|
62
|
-
let e =
|
|
62
|
+
let e = i(b);
|
|
63
63
|
if (!e) throw Error("useSystem(): no <SystemProvider> in tree");
|
|
64
64
|
return e;
|
|
65
65
|
}
|
|
66
66
|
//#endregion
|
|
67
67
|
//#region ../ui-library/src/hooks/use-device-proxy.ts
|
|
68
|
-
|
|
68
|
+
t();
|
|
69
69
|
var S = "capability.binding-changed";
|
|
70
|
-
function C(e,
|
|
71
|
-
let [
|
|
72
|
-
return
|
|
73
|
-
if (
|
|
74
|
-
|
|
70
|
+
function C(e, t) {
|
|
71
|
+
let [n, i] = r(null);
|
|
72
|
+
return l(() => {
|
|
73
|
+
if (t === null) {
|
|
74
|
+
i(null);
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
|
-
let
|
|
77
|
+
let n = !1, r = async () => {
|
|
78
78
|
try {
|
|
79
|
-
let r = await e.deviceManager.getBindings.query({ deviceId:
|
|
80
|
-
|
|
79
|
+
let r = await e.deviceManager.getBindings.query({ deviceId: t });
|
|
80
|
+
n || i(r);
|
|
81
81
|
} catch {
|
|
82
|
-
|
|
82
|
+
n || i((e) => e);
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
85
|
r();
|
|
86
|
-
let
|
|
87
|
-
let
|
|
88
|
-
if (!
|
|
86
|
+
let a = e.live?.onEvent.subscribe({ category: S }, { onData: (e) => {
|
|
87
|
+
let n = e.data?.source;
|
|
88
|
+
if (!n) {
|
|
89
89
|
r();
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
n.type === "device" && n.id === t && r();
|
|
93
93
|
} });
|
|
94
94
|
return () => {
|
|
95
|
-
|
|
95
|
+
n = !0, a?.unsubscribe();
|
|
96
96
|
};
|
|
97
|
-
}, [e,
|
|
97
|
+
}, [e, t]), a(() => n ? u(e, n) : null, [e, n]);
|
|
98
98
|
}
|
|
99
|
-
function w(
|
|
100
|
-
let
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
function T(e, t, n) {
|
|
104
|
-
let r = C(e, t);
|
|
105
|
-
return w(r ? n(r.state) : void 0);
|
|
99
|
+
function w(t) {
|
|
100
|
+
let r = n((e) => t ? t.subscribe(() => e()) : () => void 0, [t]), i = n(() => t?.value, [t]);
|
|
101
|
+
return e(r, i, i);
|
|
106
102
|
}
|
|
107
103
|
//#endregion
|
|
108
104
|
//#region ../ui-library/src/lib/cap-error.ts
|
|
109
|
-
function
|
|
105
|
+
function T(e) {
|
|
110
106
|
if (typeof e != "object" || !e) return null;
|
|
111
107
|
let t = Reflect.get(e, "data");
|
|
112
108
|
if (typeof t == "object" && t) {
|
|
@@ -115,12 +111,12 @@ function E(e) {
|
|
|
115
111
|
}
|
|
116
112
|
return null;
|
|
117
113
|
}
|
|
118
|
-
function
|
|
119
|
-
let t =
|
|
114
|
+
function E(e) {
|
|
115
|
+
let t = T(e);
|
|
120
116
|
return t === null ? (e instanceof Error ? e.message : String(e)).includes("provider not available") : t === "no-provider" || t === "node-offline";
|
|
121
117
|
}
|
|
122
118
|
//#endregion
|
|
123
119
|
//#region ../ui-library/src/lib/responsive.ts
|
|
124
|
-
var
|
|
120
|
+
var D = "rounded-lg border border-border bg-surface overflow-hidden", O = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2", k = "p-2 sm:p-3 lg:p-4", A = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4", j = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center", M = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2", N = "flex w-full min-w-0 items-center gap-1 sm:flex-1", P = "min-w-0 break-all text-xs text-foreground sm:truncate", F = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider", I = "text-[10px] text-foreground-subtle", L = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors", R = "border-primary/50 bg-primary/15 text-primary", z = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
|
|
125
121
|
//#endregion
|
|
126
|
-
export {
|
|
122
|
+
export { x as _, k as a, j as c, P as d, I as f, w as g, C as h, A as i, M as l, E as m, L as n, D as o, F as p, z as r, O as s, R as t, N as u, y as v, v as y };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { b as e, c as t, g as n, m as r } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs";
|
|
2
|
+
import { y as i } from "./responsive-BBlQWFFi.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"
|
|
@@ -89,7 +89,7 @@ function g(e) {
|
|
|
89
89
|
//#region ../ui-library/src/hooks/use-device-snapshot.ts
|
|
90
90
|
var _ = "/addon/snapshot/media";
|
|
91
91
|
function v(e, i = {}) {
|
|
92
|
-
let { width: a, baseUrl: o } = i, [s, c] =
|
|
92
|
+
let { width: a, baseUrl: o } = i, [s, c] = n(0);
|
|
93
93
|
return {
|
|
94
94
|
src: r(() => {
|
|
95
95
|
if (e === null || e <= 0) return null;
|
|
@@ -104,7 +104,7 @@ function v(e, i = {}) {
|
|
|
104
104
|
s
|
|
105
105
|
]),
|
|
106
106
|
loading: !1,
|
|
107
|
-
refresh:
|
|
107
|
+
refresh: t(() => {
|
|
108
108
|
c((e) => e + 1);
|
|
109
109
|
}, [])
|
|
110
110
|
};
|