@prettier-ai/dsh-client-ui-settings-models 0.1.2-alpha.1 → 0.1.2-alpha.3
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/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/client.js +345 -309
- package/lib/types/client/CustomProviderCard.d.ts +3 -3
- package/lib/types/client/DeepSeekOnboardingDialog.d.ts +4 -3
- package/lib/types/client/ModelListEditor.d.ts +3 -3
- package/lib/types/client/ModelsSection.d.ts +6 -5
- package/lib/types/client/ProviderEditor.d.ts +3 -3
- package/lib/types/client/index.d.ts +2 -1
- package/lib/types/client/operations.d.ts +86 -0
- package/lib/types/client/store.d.ts +10 -28
- package/package.json +13 -17
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-settings-models/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 920780b2193d6165a10967cc49afcb5b7e193105
|
|
6
|
+
README.zh.md: 4ec9ae43eef9a13ffde22e2a3de0e44d3b6cb51d
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ A typed API key is judged on its own field: after trimming, it must be non-empty
|
|
|
63
63
|
|
|
64
64
|
### Concurrency and credentials
|
|
65
65
|
|
|
66
|
-
Each settings write carries the card's current `revision`, so a concurrent write from another tab or an external `settings.yaml` edit is refused as `settings
|
|
66
|
+
Each settings write carries the card's current `revision`, so a concurrent write from another tab or an external `settings.yaml` edit is refused as `settings/conflict`. After settings commit, the card adopts the returned redacted user subtree and revision before storing the credential, so a failed credential stage retries only that stage. Deletion removes a configured, writable credential only when the profile names the page's derived `<ROUTE>_API_KEY` target, then unsets the profile; both operations are idempotent. Once loaded, the page subscribes to forwarded `settings/document-updated`, `credentials/reference-updated`, and `llm/adapters-updated` owner events, plus local `connection/reset`, so external edits converge without polling.
|
|
67
67
|
|
|
68
68
|
### Onboarding coordinator
|
|
69
69
|
|
package/README.zh.md
CHANGED
|
@@ -63,7 +63,7 @@ kind: "package-reference"
|
|
|
63
63
|
|
|
64
64
|
### 并发与凭据
|
|
65
65
|
|
|
66
|
-
每次 settings 写入都携带卡片当前的 `revision`,因此来自另一个标签页或外部 `settings.yaml` 编辑的并发写入会以 `settings
|
|
66
|
+
每次 settings 写入都携带卡片当前的 `revision`,因此来自另一个标签页或外部 `settings.yaml` 编辑的并发写入会以 `settings/conflict` 被拒绝。settings 提交后,卡片会在存储凭据前采纳返回的脱敏用户子树与 revision,因此失败的凭据阶段只重试该阶段。删除只会在 profile 指名本页派生的 `<ROUTE>_API_KEY` 目标时移除已配置且可写的凭据,然后 unset 该 profile;两个操作都幂等。加载完成后,页面订阅转发的 `settings/document-updated`、`credentials/reference-updated` 与 `llm/adapters-updated` 属主事件,以及本地 `connection/reset`,因此外部编辑无需轮询即可收敛。
|
|
67
67
|
|
|
68
68
|
### 引导协调器
|
|
69
69
|
|
package/lib/client.js
CHANGED
|
@@ -443,252 +443,6 @@ window.__ModuleLoader__.load({
|
|
|
443
443
|
});
|
|
444
444
|
}
|
|
445
445
|
//#endregion
|
|
446
|
-
//#region lib/types/client/store.js
|
|
447
|
-
/**
|
|
448
|
-
* Models settings page store: one snapshot joining the configurable-provider
|
|
449
|
-
* directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),
|
|
450
|
-
* the settings namespaces (shared settings mirror),
|
|
451
|
-
* and the referenced credentials (`credentials/describe`). The host stays the
|
|
452
|
-
* single fact source — every mutation writes through the wire and the page
|
|
453
|
-
* re-renders from the next describe, pushed or refetched.
|
|
454
|
-
*/
|
|
455
|
-
/**
|
|
456
|
-
* Any route key walks a dict schema to the same profile node, so the lookup
|
|
457
|
-
* names one that cannot collide with a configured route.
|
|
458
|
-
*/
|
|
459
|
-
const PROBE_ROUTE = "\0probe";
|
|
460
|
-
/**
|
|
461
|
-
* Join declared configurable providers with the currently registered routes.
|
|
462
|
-
* @param registered - live provider routes in registration order.
|
|
463
|
-
* @param directory - declared configurable providers in declaration order.
|
|
464
|
-
* @returns declared rows followed by live routes with no declaration.
|
|
465
|
-
*/
|
|
466
|
-
function joinProviderDirectory(registered, directory) {
|
|
467
|
-
const active = new Set(registered.map((provider) => provider.id));
|
|
468
|
-
const declared = new Set(directory.map((entry) => entry.provider));
|
|
469
|
-
const rows = directory.map((entry) => ({
|
|
470
|
-
provider: entry.provider,
|
|
471
|
-
displayName: entry.displayName,
|
|
472
|
-
settingsNs: entry.settingsNs,
|
|
473
|
-
settingsPath: [...entry.settingsPath],
|
|
474
|
-
active: active.has(entry.provider),
|
|
475
|
-
...entry.declared === void 0 ? {} : { declared: entry.declared }
|
|
476
|
-
}));
|
|
477
|
-
for (const provider of registered) {
|
|
478
|
-
if (declared.has(provider.id)) continue;
|
|
479
|
-
rows.push({
|
|
480
|
-
provider: provider.id,
|
|
481
|
-
displayName: provider.name,
|
|
482
|
-
settingsNs: "",
|
|
483
|
-
settingsPath: [],
|
|
484
|
-
active: true
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
return rows;
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Human text for a rejected wire call. A transport failure rejects with an
|
|
491
|
-
* Error; a host or a runtime can reject with anything, and the page still has
|
|
492
|
-
* to say something.
|
|
493
|
-
* @param error - the rejection value.
|
|
494
|
-
* @returns the message to show.
|
|
495
|
-
*/
|
|
496
|
-
function messageOf(error) {
|
|
497
|
-
return error instanceof Error ? error.message : String(error);
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
* Derive the conventional credential reference for a provider route: the v1
|
|
501
|
-
* page never asks for an environment-variable name, so a typed key stores
|
|
502
|
-
* under this derived reference and the profile records it as `apiKeyEnv`.
|
|
503
|
-
* @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
|
|
504
|
-
* @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
|
|
505
|
-
*/
|
|
506
|
-
function deriveKeyRef(provider) {
|
|
507
|
-
return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* The wire protocols a hand-declared route may name, read out of the owning
|
|
511
|
-
* namespace's own schema. This stays a schema read rather than a wire field so
|
|
512
|
-
* the choices the page offers cannot drift from the ones the adapter accepts:
|
|
513
|
-
* both come from the same `Config`.
|
|
514
|
-
* @param namespace - the namespace view whose schema declares the profile shape.
|
|
515
|
-
* @param schema - settings schema operations.
|
|
516
|
-
* @returns the protocol identifiers, or an empty list when the schema has none.
|
|
517
|
-
*/
|
|
518
|
-
function protocolChoices(namespace, schema) {
|
|
519
|
-
if (namespace === void 0) return [];
|
|
520
|
-
const list = schema.nodeAtPath(schema.rehydrate(namespace.schema), [
|
|
521
|
-
"providers",
|
|
522
|
-
PROBE_ROUTE,
|
|
523
|
-
"api"
|
|
524
|
-
]);
|
|
525
|
-
if (list?.type !== "union" || list.list === void 0) return [];
|
|
526
|
-
return list.list.map((entry) => entry.value).filter((value) => typeof value === "string");
|
|
527
|
-
}
|
|
528
|
-
/** The credential reference a resolved profile names (its `apiKeyEnv` field). */
|
|
529
|
-
function apiKeyEnvOf(namespace, path, schema) {
|
|
530
|
-
if (namespace === void 0) return void 0;
|
|
531
|
-
const profile = schema.getPath(namespace.value, path);
|
|
532
|
-
if (typeof profile !== "object" || profile === null) return void 0;
|
|
533
|
-
const ref = profile.apiKeyEnv;
|
|
534
|
-
return typeof ref === "string" && ref.length > 0 ? ref : void 0;
|
|
535
|
-
}
|
|
536
|
-
/** The models settings page controller (one per settings surface). */
|
|
537
|
-
var ModelsSettingsStore = class {
|
|
538
|
-
api;
|
|
539
|
-
schema;
|
|
540
|
-
describeFace;
|
|
541
|
-
/** The snapshot the section renders from (uSES-safe store). */
|
|
542
|
-
store = (0, _prettier_ai_dsh_client_store.createSnapshotStore)({
|
|
543
|
-
status: "idle",
|
|
544
|
-
error: null,
|
|
545
|
-
credentialError: null,
|
|
546
|
-
writable: false,
|
|
547
|
-
rows: [],
|
|
548
|
-
namespaces: /* @__PURE__ */ new Map()
|
|
549
|
-
});
|
|
550
|
-
/** Latest load wins; an older response never overwrites a newer one. */
|
|
551
|
-
generation = 0;
|
|
552
|
-
/**
|
|
553
|
-
* @param api - the page's credentials Remote and LLM wire faces.
|
|
554
|
-
* @param describeFace - the shared mirror's describe face (namespace views and writability).
|
|
555
|
-
*/
|
|
556
|
-
constructor(api, schema, describeFace) {
|
|
557
|
-
this.api = api;
|
|
558
|
-
this.schema = schema;
|
|
559
|
-
this.describeFace = describeFace;
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Refresh the whole page snapshot: the provider directory and the mirror's
|
|
563
|
-
* settings answer in parallel, then one batched credential describe over
|
|
564
|
-
* every referenced ref. Provider failure or absence of an initial settings
|
|
565
|
-
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
566
|
-
* refresh reuses the mirror's held view.
|
|
567
|
-
* @returns nothing; the snapshot carries the outcome.
|
|
568
|
-
*/
|
|
569
|
-
async load() {
|
|
570
|
-
const generation = ++this.generation;
|
|
571
|
-
this.store.update((s) => {
|
|
572
|
-
s.status = "loading";
|
|
573
|
-
s.error = null;
|
|
574
|
-
});
|
|
575
|
-
let providers;
|
|
576
|
-
let writable;
|
|
577
|
-
let views;
|
|
578
|
-
try {
|
|
579
|
-
const [registered, declared] = await Promise.all([
|
|
580
|
-
this.api.llm.listProviders(),
|
|
581
|
-
this.api.llm.listConfigurableProviders(),
|
|
582
|
-
this.describeFace.ensure()
|
|
583
|
-
]);
|
|
584
|
-
if (!registered.ok) throw new Error(registered.error.message);
|
|
585
|
-
if (!declared.ok) throw new Error(declared.error.message);
|
|
586
|
-
const mirrored = this.describeFace.getSnapshot();
|
|
587
|
-
if (mirrored.view === void 0) throw new Error(mirrored.error ?? "settings are unavailable in this browser");
|
|
588
|
-
providers = joinProviderDirectory(registered.value, declared.value);
|
|
589
|
-
writable = mirrored.view.writable;
|
|
590
|
-
views = mirrored.view.namespaces;
|
|
591
|
-
} catch (error) {
|
|
592
|
-
if (generation !== this.generation) return;
|
|
593
|
-
this.store.update((s) => {
|
|
594
|
-
s.status = "error";
|
|
595
|
-
s.error = error instanceof Error ? error.message : String(error);
|
|
596
|
-
});
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
const namespaces = new Map(views.map((view) => [view.ns, view]));
|
|
600
|
-
const rows = providers.map((entry) => {
|
|
601
|
-
const namespace = namespaces.get(entry.settingsNs);
|
|
602
|
-
return {
|
|
603
|
-
entry,
|
|
604
|
-
configured: namespace !== void 0 && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== void 0),
|
|
605
|
-
removable: namespace !== void 0 && entry.settingsPath.length > 0 && this.schema.hasPath(namespace.user, entry.settingsPath) && !this.schema.hasPath(namespace.base, entry.settingsPath),
|
|
606
|
-
apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),
|
|
607
|
-
credential: void 0
|
|
608
|
-
};
|
|
609
|
-
});
|
|
610
|
-
const refs = [...new Set(rows.map((row) => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))];
|
|
611
|
-
let credentials = {};
|
|
612
|
-
let credentialError = null;
|
|
613
|
-
if (refs.length > 0) try {
|
|
614
|
-
const response = await this.api.credentials.describe(refs);
|
|
615
|
-
if (response.ok) credentials = response.value;
|
|
616
|
-
else credentialError = response.error.message;
|
|
617
|
-
} catch (error) {
|
|
618
|
-
credentialError = messageOf(error);
|
|
619
|
-
}
|
|
620
|
-
if (generation !== this.generation) return;
|
|
621
|
-
this.store.update((s) => {
|
|
622
|
-
s.status = "ready";
|
|
623
|
-
s.error = null;
|
|
624
|
-
s.credentialError = credentialError;
|
|
625
|
-
s.writable = writable;
|
|
626
|
-
s.rows = rows.map((row) => {
|
|
627
|
-
const named = row.apiKeyEnv === void 0 ? void 0 : credentials[row.apiKeyEnv];
|
|
628
|
-
const derived = row.apiKeyEnv !== void 0 ? void 0 : credentials[deriveKeyRef(row.entry.provider)];
|
|
629
|
-
return {
|
|
630
|
-
...row,
|
|
631
|
-
...named === void 0 ? {} : { credential: named },
|
|
632
|
-
...derived === void 0 ? {} : { derivedCredential: derived }
|
|
633
|
-
};
|
|
634
|
-
});
|
|
635
|
-
s.namespaces = namespaces;
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
};
|
|
639
|
-
/**
|
|
640
|
-
* Whether a joined row can serve model requests as it stands: the route is
|
|
641
|
-
* registered with the adapter registry, and whatever credential its resolved
|
|
642
|
-
* profile names is stored. A profile naming no reference authenticates through
|
|
643
|
-
* the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
|
|
644
|
-
* nothing), as does a live route with no settings address at all, so neither
|
|
645
|
-
* owes this page a key.
|
|
646
|
-
* @param row - one joined provider row.
|
|
647
|
-
* @returns whether the user already has this provider to talk to.
|
|
648
|
-
*/
|
|
649
|
-
function providerUsable(row) {
|
|
650
|
-
if (!row.entry.active) return false;
|
|
651
|
-
if (row.apiKeyEnv === void 0) return true;
|
|
652
|
-
return row.credential?.configured === true;
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* Project first-run readiness from the provider/settings/credential join used
|
|
656
|
-
* by the Models page. The step exists to leave the user with a model to talk
|
|
657
|
-
* to, so ANY usable provider ends it; only when none exists does the official
|
|
658
|
-
* DeepSeek route — the one route the prompt can offer a key field for — decide
|
|
659
|
-
* whether prompting can help. A missing official configurable-provider
|
|
660
|
-
* declaration means the adapter is not repairable by navigating to Models.
|
|
661
|
-
* @param state - current shared Models join snapshot.
|
|
662
|
-
* @returns the onboarding state without reading a parallel fact source.
|
|
663
|
-
*/
|
|
664
|
-
function onboardingReadiness(state) {
|
|
665
|
-
if ((state.status === "idle" || state.status === "loading") && state.rows.length === 0) return { kind: "loading" };
|
|
666
|
-
if (state.status === "error") return {
|
|
667
|
-
kind: "unavailable",
|
|
668
|
-
reason: "load-failed"
|
|
669
|
-
};
|
|
670
|
-
if (state.rows.some(providerUsable)) return { kind: "provider-ready" };
|
|
671
|
-
const row = state.rows.find((candidate) => candidate.entry.provider === "deepseek-official" && candidate.entry.settingsNs === "llm-deepseek" && candidate.entry.settingsPath.length === 0);
|
|
672
|
-
if (row === void 0) return { kind: "adapter-absent" };
|
|
673
|
-
if (!row.entry.active) return {
|
|
674
|
-
kind: "unavailable",
|
|
675
|
-
reason: "provider-inactive"
|
|
676
|
-
};
|
|
677
|
-
if (state.credentialError !== null || row.credential === void 0) return {
|
|
678
|
-
kind: "unavailable",
|
|
679
|
-
reason: "credentials-unavailable"
|
|
680
|
-
};
|
|
681
|
-
if (!state.writable) return {
|
|
682
|
-
kind: "unavailable",
|
|
683
|
-
reason: "settings-read-only"
|
|
684
|
-
};
|
|
685
|
-
if (!row.credential.writable) return {
|
|
686
|
-
kind: "unavailable",
|
|
687
|
-
reason: "credential-read-only"
|
|
688
|
-
};
|
|
689
|
-
return { kind: "credential-missing" };
|
|
690
|
-
}
|
|
691
|
-
//#endregion
|
|
692
446
|
//#region lib/types/client/ModelListEditor.js
|
|
693
447
|
/**
|
|
694
448
|
* The model list of one pi-ai provider profile, plus the action that asks the
|
|
@@ -793,7 +547,7 @@ window.__ModuleLoader__.load({
|
|
|
793
547
|
* @returns the model-list editor.
|
|
794
548
|
*/
|
|
795
549
|
function ModelListEditor(props) {
|
|
796
|
-
const { models, onChange, probe,
|
|
550
|
+
const { models, onChange, probe, operations, t, disabled } = props;
|
|
797
551
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
798
552
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
799
553
|
const [candidates, setCandidates] = (0, react.useState)(void 0);
|
|
@@ -839,17 +593,17 @@ window.__ModuleLoader__.load({
|
|
|
839
593
|
setBusy(true);
|
|
840
594
|
setFailure(void 0);
|
|
841
595
|
try {
|
|
842
|
-
const
|
|
596
|
+
const answer = await operations.discoverModels(probe.settingsNs, {
|
|
843
597
|
...probe.provider === void 0 ? {} : { provider: probe.provider },
|
|
844
598
|
...probe.baseURL === void 0 || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },
|
|
845
599
|
...probe.api === void 0 ? {} : { api: probe.api },
|
|
846
600
|
...probe.apiKey === void 0 ? {} : { apiKey: probe.apiKey }
|
|
847
601
|
});
|
|
848
|
-
if (
|
|
849
|
-
setFailure(
|
|
602
|
+
if (answer.kind === "refused") {
|
|
603
|
+
setFailure(answer.message);
|
|
850
604
|
return;
|
|
851
605
|
}
|
|
852
|
-
const found =
|
|
606
|
+
const found = answer.models;
|
|
853
607
|
if (found.length === 0) {
|
|
854
608
|
setFailure(t("fetchEmpty"));
|
|
855
609
|
return;
|
|
@@ -857,8 +611,6 @@ window.__ModuleLoader__.load({
|
|
|
857
611
|
const known = new Set(models.map((model) => textOf(model, "id")));
|
|
858
612
|
setCandidates(found);
|
|
859
613
|
setPicked(new Set(found.filter((model) => !known.has(model.id)).map((model) => model.id)));
|
|
860
|
-
} catch (error) {
|
|
861
|
-
setFailure(messageOf(error));
|
|
862
614
|
} finally {
|
|
863
615
|
setBusy(false);
|
|
864
616
|
}
|
|
@@ -1090,6 +842,247 @@ window.__ModuleLoader__.load({
|
|
|
1090
842
|
});
|
|
1091
843
|
}
|
|
1092
844
|
//#endregion
|
|
845
|
+
//#region lib/types/client/store.js
|
|
846
|
+
/**
|
|
847
|
+
* Models settings page store: one snapshot joining the configurable-provider
|
|
848
|
+
* directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),
|
|
849
|
+
* the settings namespaces (shared settings mirror),
|
|
850
|
+
* and the referenced credentials (`credentials/describe`). The host stays the
|
|
851
|
+
* single fact source — every mutation writes through the wire and the page
|
|
852
|
+
* re-renders from the next describe, pushed or refetched.
|
|
853
|
+
*/
|
|
854
|
+
/**
|
|
855
|
+
* Any route key walks a dict schema to the same profile node, so the lookup
|
|
856
|
+
* names one that cannot collide with a configured route.
|
|
857
|
+
*/
|
|
858
|
+
const PROBE_ROUTE = "\0probe";
|
|
859
|
+
/**
|
|
860
|
+
* Join declared configurable providers with the currently registered routes.
|
|
861
|
+
* @param registered - live provider routes in registration order.
|
|
862
|
+
* @param directory - declared configurable providers in declaration order.
|
|
863
|
+
* @returns declared rows followed by live routes with no declaration.
|
|
864
|
+
*/
|
|
865
|
+
function joinProviderDirectory(registered, directory) {
|
|
866
|
+
const active = new Set(registered.map((provider) => provider.id));
|
|
867
|
+
const declared = new Set(directory.map((entry) => entry.provider));
|
|
868
|
+
const rows = directory.map((entry) => ({
|
|
869
|
+
provider: entry.provider,
|
|
870
|
+
displayName: entry.displayName,
|
|
871
|
+
settingsNs: entry.settingsNs,
|
|
872
|
+
settingsPath: [...entry.settingsPath],
|
|
873
|
+
active: active.has(entry.provider),
|
|
874
|
+
...entry.declared === void 0 ? {} : { declared: entry.declared }
|
|
875
|
+
}));
|
|
876
|
+
for (const provider of registered) {
|
|
877
|
+
if (declared.has(provider.id)) continue;
|
|
878
|
+
rows.push({
|
|
879
|
+
provider: provider.id,
|
|
880
|
+
displayName: provider.name,
|
|
881
|
+
settingsNs: "",
|
|
882
|
+
settingsPath: [],
|
|
883
|
+
active: true
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
return rows;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Derive the conventional credential reference for a provider route: the v1
|
|
890
|
+
* page never asks for an environment-variable name, so a typed key stores
|
|
891
|
+
* under this derived reference and the profile records it as `apiKeyEnv`.
|
|
892
|
+
* @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
|
|
893
|
+
* @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
|
|
894
|
+
*/
|
|
895
|
+
function deriveKeyRef(provider) {
|
|
896
|
+
return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* The wire protocols a hand-declared route may name, read out of the owning
|
|
900
|
+
* namespace's own schema. This stays a schema read rather than a wire field so
|
|
901
|
+
* the choices the page offers cannot drift from the ones the adapter accepts:
|
|
902
|
+
* both come from the same `Config`.
|
|
903
|
+
* @param namespace - the namespace view whose schema declares the profile shape.
|
|
904
|
+
* @param schema - settings schema operations.
|
|
905
|
+
* @returns the protocol identifiers, or an empty list when the schema has none.
|
|
906
|
+
*/
|
|
907
|
+
function protocolChoices(namespace, schema) {
|
|
908
|
+
if (namespace === void 0) return [];
|
|
909
|
+
const list = schema.nodeAtPath(schema.rehydrate(namespace.schema), [
|
|
910
|
+
"providers",
|
|
911
|
+
PROBE_ROUTE,
|
|
912
|
+
"api"
|
|
913
|
+
]);
|
|
914
|
+
if (list?.type !== "union" || list.list === void 0) return [];
|
|
915
|
+
return list.list.map((entry) => entry.value).filter((value) => typeof value === "string");
|
|
916
|
+
}
|
|
917
|
+
/** The credential reference a resolved profile names (its `apiKeyEnv` field). */
|
|
918
|
+
function apiKeyEnvOf(namespace, path, schema) {
|
|
919
|
+
if (namespace === void 0) return void 0;
|
|
920
|
+
const profile = schema.getPath(namespace.value, path);
|
|
921
|
+
if (typeof profile !== "object" || profile === null) return void 0;
|
|
922
|
+
const ref = profile.apiKeyEnv;
|
|
923
|
+
return typeof ref === "string" && ref.length > 0 ? ref : void 0;
|
|
924
|
+
}
|
|
925
|
+
/** The models settings page controller (one per settings surface). */
|
|
926
|
+
var ModelsSettingsStore = class {
|
|
927
|
+
ctx;
|
|
928
|
+
schema;
|
|
929
|
+
describeFace;
|
|
930
|
+
/** The snapshot the section renders from (uSES-safe store). */
|
|
931
|
+
store = (0, _prettier_ai_dsh_client_store.createSnapshotStore)({
|
|
932
|
+
status: "idle",
|
|
933
|
+
error: null,
|
|
934
|
+
credentialError: null,
|
|
935
|
+
writable: false,
|
|
936
|
+
rows: [],
|
|
937
|
+
namespaces: /* @__PURE__ */ new Map()
|
|
938
|
+
});
|
|
939
|
+
/** Latest load wins; an older response never overwrites a newer one. */
|
|
940
|
+
generation = 0;
|
|
941
|
+
/**
|
|
942
|
+
* @param ctx - the page plugin's context, whose `remote.llm` and
|
|
943
|
+
* `remote.credentials` namespaces carry the directory and credential reads.
|
|
944
|
+
* @param schema - settings-owned schema and immutable path operations.
|
|
945
|
+
* @param describeFace - the shared mirror's describe face (namespace views and writability).
|
|
946
|
+
*/
|
|
947
|
+
constructor(ctx, schema, describeFace) {
|
|
948
|
+
this.ctx = ctx;
|
|
949
|
+
this.schema = schema;
|
|
950
|
+
this.describeFace = describeFace;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Refresh the whole page snapshot: the provider directory and the mirror's
|
|
954
|
+
* settings answer in parallel, then one batched credential describe over
|
|
955
|
+
* every referenced ref. Provider failure or absence of an initial settings
|
|
956
|
+
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
957
|
+
* refresh reuses the mirror's held view.
|
|
958
|
+
* @returns nothing; the snapshot carries the outcome.
|
|
959
|
+
*/
|
|
960
|
+
async load() {
|
|
961
|
+
const generation = ++this.generation;
|
|
962
|
+
this.store.update((s) => {
|
|
963
|
+
s.status = "loading";
|
|
964
|
+
s.error = null;
|
|
965
|
+
});
|
|
966
|
+
const [registered, declared] = await Promise.all([
|
|
967
|
+
this.ctx.remote.llm.listProviders(),
|
|
968
|
+
this.ctx.remote.llm.listConfigurableProviders(),
|
|
969
|
+
this.describeFace.ensure()
|
|
970
|
+
]);
|
|
971
|
+
if (!registered.ok) {
|
|
972
|
+
this.failLoad(generation, registered.error.message);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
if (!declared.ok) {
|
|
976
|
+
this.failLoad(generation, declared.error.message);
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
const mirrored = this.describeFace.getSnapshot();
|
|
980
|
+
if (mirrored.view === void 0) {
|
|
981
|
+
this.failLoad(generation, mirrored.error ?? "settings are unavailable in this browser");
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
const providers = joinProviderDirectory(registered.value, declared.value);
|
|
985
|
+
const writable = mirrored.view.writable;
|
|
986
|
+
const views = mirrored.view.namespaces;
|
|
987
|
+
const namespaces = new Map(views.map((view) => [view.ns, view]));
|
|
988
|
+
const rows = providers.map((entry) => {
|
|
989
|
+
const namespace = namespaces.get(entry.settingsNs);
|
|
990
|
+
return {
|
|
991
|
+
entry,
|
|
992
|
+
configured: namespace !== void 0 && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== void 0),
|
|
993
|
+
removable: namespace !== void 0 && entry.settingsPath.length > 0 && this.schema.hasPath(namespace.user, entry.settingsPath) && !this.schema.hasPath(namespace.base, entry.settingsPath),
|
|
994
|
+
apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),
|
|
995
|
+
credential: void 0
|
|
996
|
+
};
|
|
997
|
+
});
|
|
998
|
+
const refs = [...new Set(rows.map((row) => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))];
|
|
999
|
+
let credentials = {};
|
|
1000
|
+
let credentialError = null;
|
|
1001
|
+
if (refs.length > 0) {
|
|
1002
|
+
const response = await this.ctx.remote.credentials.describe(refs);
|
|
1003
|
+
if (response.ok) credentials = response.value;
|
|
1004
|
+
else credentialError = response.error.message;
|
|
1005
|
+
}
|
|
1006
|
+
if (generation !== this.generation) return;
|
|
1007
|
+
this.store.update((s) => {
|
|
1008
|
+
s.status = "ready";
|
|
1009
|
+
s.error = null;
|
|
1010
|
+
s.credentialError = credentialError;
|
|
1011
|
+
s.writable = writable;
|
|
1012
|
+
s.rows = rows.map((row) => {
|
|
1013
|
+
const named = row.apiKeyEnv === void 0 ? void 0 : credentials[row.apiKeyEnv];
|
|
1014
|
+
const derived = row.apiKeyEnv !== void 0 ? void 0 : credentials[deriveKeyRef(row.entry.provider)];
|
|
1015
|
+
return {
|
|
1016
|
+
...row,
|
|
1017
|
+
...named === void 0 ? {} : { credential: named },
|
|
1018
|
+
...derived === void 0 ? {} : { derivedCredential: derived }
|
|
1019
|
+
};
|
|
1020
|
+
});
|
|
1021
|
+
s.namespaces = namespaces;
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
/** Publish one load's failure text, unless a newer load already took over. */
|
|
1025
|
+
failLoad(generation, message) {
|
|
1026
|
+
if (generation !== this.generation) return;
|
|
1027
|
+
this.store.update((s) => {
|
|
1028
|
+
s.status = "error";
|
|
1029
|
+
s.error = message;
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
/**
|
|
1034
|
+
* Whether a joined row can serve model requests as it stands: the route is
|
|
1035
|
+
* registered with the adapter registry, and whatever credential its resolved
|
|
1036
|
+
* profile names is stored. A profile naming no reference authenticates through
|
|
1037
|
+
* the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
|
|
1038
|
+
* nothing), as does a live route with no settings address at all, so neither
|
|
1039
|
+
* owes this page a key.
|
|
1040
|
+
* @param row - one joined provider row.
|
|
1041
|
+
* @returns whether the user already has this provider to talk to.
|
|
1042
|
+
*/
|
|
1043
|
+
function providerUsable(row) {
|
|
1044
|
+
if (!row.entry.active) return false;
|
|
1045
|
+
if (row.apiKeyEnv === void 0) return true;
|
|
1046
|
+
return row.credential?.configured === true;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Project first-run readiness from the provider/settings/credential join used
|
|
1050
|
+
* by the Models page. The step exists to leave the user with a model to talk
|
|
1051
|
+
* to, so ANY usable provider ends it; only when none exists does the official
|
|
1052
|
+
* DeepSeek route — the one route the prompt can offer a key field for — decide
|
|
1053
|
+
* whether prompting can help. A missing official configurable-provider
|
|
1054
|
+
* declaration means the adapter is not repairable by navigating to Models.
|
|
1055
|
+
* @param state - current shared Models join snapshot.
|
|
1056
|
+
* @returns the onboarding state without reading a parallel fact source.
|
|
1057
|
+
*/
|
|
1058
|
+
function onboardingReadiness(state) {
|
|
1059
|
+
if ((state.status === "idle" || state.status === "loading") && state.rows.length === 0) return { kind: "loading" };
|
|
1060
|
+
if (state.status === "error") return {
|
|
1061
|
+
kind: "unavailable",
|
|
1062
|
+
reason: "load-failed"
|
|
1063
|
+
};
|
|
1064
|
+
if (state.rows.some(providerUsable)) return { kind: "provider-ready" };
|
|
1065
|
+
const row = state.rows.find((candidate) => candidate.entry.provider === "deepseek-official" && candidate.entry.settingsNs === "llm-deepseek" && candidate.entry.settingsPath.length === 0);
|
|
1066
|
+
if (row === void 0) return { kind: "adapter-absent" };
|
|
1067
|
+
if (!row.entry.active) return {
|
|
1068
|
+
kind: "unavailable",
|
|
1069
|
+
reason: "provider-inactive"
|
|
1070
|
+
};
|
|
1071
|
+
if (state.credentialError !== null || row.credential === void 0) return {
|
|
1072
|
+
kind: "unavailable",
|
|
1073
|
+
reason: "credentials-unavailable"
|
|
1074
|
+
};
|
|
1075
|
+
if (!state.writable) return {
|
|
1076
|
+
kind: "unavailable",
|
|
1077
|
+
reason: "settings-read-only"
|
|
1078
|
+
};
|
|
1079
|
+
if (!row.credential.writable) return {
|
|
1080
|
+
kind: "unavailable",
|
|
1081
|
+
reason: "credential-read-only"
|
|
1082
|
+
};
|
|
1083
|
+
return { kind: "credential-missing" };
|
|
1084
|
+
}
|
|
1085
|
+
//#endregion
|
|
1093
1086
|
//#region lib/types/client/CustomProviderCard.js
|
|
1094
1087
|
/**
|
|
1095
1088
|
* The card that declares a provider pi-ai does not ship — an OpenAI-compatible
|
|
@@ -1130,7 +1123,7 @@ window.__ModuleLoader__.load({
|
|
|
1130
1123
|
* @returns the creation card.
|
|
1131
1124
|
*/
|
|
1132
1125
|
function CustomProviderCard(props) {
|
|
1133
|
-
const { taken, protocols,
|
|
1126
|
+
const { taken, protocols, operations, t } = props;
|
|
1134
1127
|
const [openedAt] = (0, react.useState)(() => props.revision);
|
|
1135
1128
|
const [route, setRoute] = (0, react.useState)("");
|
|
1136
1129
|
const [displayName, setDisplayName] = (0, react.useState)("");
|
|
@@ -1168,17 +1161,17 @@ window.__ModuleLoader__.load({
|
|
|
1168
1161
|
baseURL,
|
|
1169
1162
|
models: models.map((model) => ({ ...model }))
|
|
1170
1163
|
};
|
|
1171
|
-
const
|
|
1164
|
+
const written = await operations.writeSettings(NS$1, [{
|
|
1172
1165
|
op: "set",
|
|
1173
1166
|
path: ["providers", route],
|
|
1174
1167
|
value: profile
|
|
1175
1168
|
}], openedAt);
|
|
1176
|
-
if (
|
|
1169
|
+
if (written.kind !== "written") return written.kind === "conflict" ? t("conflict") : written.message;
|
|
1177
1170
|
setCommitted(true);
|
|
1178
1171
|
}
|
|
1179
1172
|
if (storesKey) {
|
|
1180
|
-
const stored = await
|
|
1181
|
-
if (
|
|
1173
|
+
const stored = await operations.storeCredential(keyRef, keyValue);
|
|
1174
|
+
if (stored !== void 0) return stored;
|
|
1182
1175
|
}
|
|
1183
1176
|
};
|
|
1184
1177
|
const create = async () => {
|
|
@@ -1191,8 +1184,6 @@ window.__ModuleLoader__.load({
|
|
|
1191
1184
|
return;
|
|
1192
1185
|
}
|
|
1193
1186
|
props.onClose(true);
|
|
1194
|
-
} catch (error) {
|
|
1195
|
-
setFailure(messageOf(error));
|
|
1196
1187
|
} finally {
|
|
1197
1188
|
setBusy(false);
|
|
1198
1189
|
}
|
|
@@ -1319,7 +1310,7 @@ window.__ModuleLoader__.load({
|
|
|
1319
1310
|
...keyValue.length === 0 ? {} : { apiKey: keyValue }
|
|
1320
1311
|
},
|
|
1321
1312
|
probeBlocked: keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
|
|
1322
|
-
|
|
1313
|
+
operations,
|
|
1323
1314
|
t,
|
|
1324
1315
|
disabled: profileDisabled
|
|
1325
1316
|
}),
|
|
@@ -1424,7 +1415,7 @@ window.__ModuleLoader__.load({
|
|
|
1424
1415
|
* @returns the editor card.
|
|
1425
1416
|
*/
|
|
1426
1417
|
function ProviderEditor(props) {
|
|
1427
|
-
const { namespace, schema, settingsPath,
|
|
1418
|
+
const { namespace, schema, settingsPath, operations, t } = props;
|
|
1428
1419
|
const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
|
|
1429
1420
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1430
1421
|
const [keyState, setKeyState] = (0, react.useState)(void 0);
|
|
@@ -1450,14 +1441,14 @@ window.__ModuleLoader__.load({
|
|
|
1450
1441
|
(0, react.useEffect)(() => {
|
|
1451
1442
|
let stale = false;
|
|
1452
1443
|
setKeyState(void 0);
|
|
1453
|
-
|
|
1454
|
-
if (stale
|
|
1455
|
-
setKeyState(
|
|
1456
|
-
}
|
|
1444
|
+
operations.describeCredential(keyRef).then((described) => {
|
|
1445
|
+
if (stale) return;
|
|
1446
|
+
setKeyState(described);
|
|
1447
|
+
});
|
|
1457
1448
|
return () => {
|
|
1458
1449
|
stale = true;
|
|
1459
1450
|
};
|
|
1460
|
-
}, [
|
|
1451
|
+
}, [operations, keyRef]);
|
|
1461
1452
|
const stringAt = (source, key) => {
|
|
1462
1453
|
const value = schema.getPath(source, [key]);
|
|
1463
1454
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -1505,15 +1496,15 @@ window.__ModuleLoader__.load({
|
|
|
1505
1496
|
value: {}
|
|
1506
1497
|
}] : pathOps(settingsPath, committedOriginal, next);
|
|
1507
1498
|
if (ops.length > 0) {
|
|
1508
|
-
const
|
|
1509
|
-
if (
|
|
1510
|
-
setCommittedOriginal(schema.getPath(
|
|
1511
|
-
setExpectedRevision(
|
|
1499
|
+
const written = await operations.writeSettings(ns, ops, expectedRevision);
|
|
1500
|
+
if (written.kind !== "written") return written.kind === "conflict" ? t("conflict") : written.message;
|
|
1501
|
+
setCommittedOriginal(schema.getPath(written.view.user, settingsPath));
|
|
1502
|
+
setExpectedRevision(written.view.revision);
|
|
1512
1503
|
setDraft(next);
|
|
1513
1504
|
}
|
|
1514
1505
|
if (keyValue.length > 0) {
|
|
1515
|
-
const stored = await
|
|
1516
|
-
if (
|
|
1506
|
+
const stored = await operations.storeCredential(keyRef, keyValue);
|
|
1507
|
+
if (stored !== void 0) return stored;
|
|
1517
1508
|
}
|
|
1518
1509
|
setKeyDraft("");
|
|
1519
1510
|
};
|
|
@@ -1527,8 +1518,6 @@ window.__ModuleLoader__.load({
|
|
|
1527
1518
|
return;
|
|
1528
1519
|
}
|
|
1529
1520
|
props.onClose(true);
|
|
1530
|
-
} catch (error) {
|
|
1531
|
-
setFailure(messageOf(error));
|
|
1532
1521
|
} finally {
|
|
1533
1522
|
setBusy(false);
|
|
1534
1523
|
}
|
|
@@ -1677,7 +1666,7 @@ window.__ModuleLoader__.load({
|
|
|
1677
1666
|
...catalogProps,
|
|
1678
1667
|
probe,
|
|
1679
1668
|
probeBlocked: keyFailure,
|
|
1680
|
-
|
|
1669
|
+
operations
|
|
1681
1670
|
})
|
|
1682
1671
|
]
|
|
1683
1672
|
})]
|
|
@@ -1756,25 +1745,21 @@ window.__ModuleLoader__.load({
|
|
|
1756
1745
|
* and the whole operation safely retryable; both unsets are idempotent.
|
|
1757
1746
|
* The settings removal names the profile rather than rebuilding its whole
|
|
1758
1747
|
* namespace from a partial view.
|
|
1759
|
-
* @param
|
|
1748
|
+
* @param operations - the page's Host operations.
|
|
1760
1749
|
* @param controller - the page store to refresh.
|
|
1761
1750
|
* @param target - the provider's settings address and optional managed credential.
|
|
1762
1751
|
* @returns the failure message, or undefined once the write and reload landed.
|
|
1763
1752
|
*/
|
|
1764
|
-
async function removeProviderProfile(
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
if (!credential.ok) return credential.error.message;
|
|
1769
|
-
}
|
|
1770
|
-
const response = await api.settings.mutate(target.settingsNs, [{
|
|
1771
|
-
op: "unset",
|
|
1772
|
-
path: [...target.settingsPath]
|
|
1773
|
-
}], void 0);
|
|
1774
|
-
if (!response.ok) return response.error.message;
|
|
1775
|
-
} catch (error) {
|
|
1776
|
-
return messageOf(error);
|
|
1753
|
+
async function removeProviderProfile(operations, controller, target) {
|
|
1754
|
+
if (target.credentialRef !== void 0) {
|
|
1755
|
+
const credential = await operations.removeCredential(target.credentialRef);
|
|
1756
|
+
if (credential !== void 0) return credential;
|
|
1777
1757
|
}
|
|
1758
|
+
const written = await operations.writeSettings(target.settingsNs, [{
|
|
1759
|
+
op: "unset",
|
|
1760
|
+
path: [...target.settingsPath]
|
|
1761
|
+
}], void 0);
|
|
1762
|
+
if (written.kind !== "written") return written.message;
|
|
1778
1763
|
await controller.load();
|
|
1779
1764
|
}
|
|
1780
1765
|
/**
|
|
@@ -1827,13 +1812,13 @@ window.__ModuleLoader__.load({
|
|
|
1827
1812
|
* @returns the section, or null while the shell has not injected yet.
|
|
1828
1813
|
*/
|
|
1829
1814
|
function ModelsSection(props) {
|
|
1830
|
-
const { controller, useSnapshot,
|
|
1831
|
-
if (controller === void 0 || useSnapshot === void 0 ||
|
|
1815
|
+
const { controller, useSnapshot, operations, schema, t, renderSlot } = props;
|
|
1816
|
+
if (controller === void 0 || useSnapshot === void 0 || operations === void 0 || schema === void 0 || t === void 0) return null;
|
|
1832
1817
|
return (0, react_jsx_runtime.jsx)(Loaded, {
|
|
1833
1818
|
injected: {
|
|
1834
1819
|
controller,
|
|
1835
1820
|
useSnapshot,
|
|
1836
|
-
|
|
1821
|
+
operations,
|
|
1837
1822
|
schema,
|
|
1838
1823
|
t
|
|
1839
1824
|
},
|
|
@@ -1841,7 +1826,7 @@ window.__ModuleLoader__.load({
|
|
|
1841
1826
|
});
|
|
1842
1827
|
}
|
|
1843
1828
|
function Loaded({ injected, renderSlot }) {
|
|
1844
|
-
const { controller,
|
|
1829
|
+
const { controller, operations, schema, t } = injected;
|
|
1845
1830
|
const state = injected.useSnapshot((snapshot) => snapshot);
|
|
1846
1831
|
const [editing, setEditing] = (0, react.useState)(void 0);
|
|
1847
1832
|
const [adding, setAdding] = (0, react.useState)(false);
|
|
@@ -1883,7 +1868,7 @@ window.__ModuleLoader__.load({
|
|
|
1883
1868
|
if (deleteTarget === void 0 || deleting) return;
|
|
1884
1869
|
setDeleting(true);
|
|
1885
1870
|
setDeleteFailure(void 0);
|
|
1886
|
-
removeProviderProfile(
|
|
1871
|
+
removeProviderProfile(operations, controller, deleteTarget).then((failure) => {
|
|
1887
1872
|
if (failure !== void 0) {
|
|
1888
1873
|
setDeleteFailure(failure);
|
|
1889
1874
|
return;
|
|
@@ -1958,7 +1943,7 @@ window.__ModuleLoader__.load({
|
|
|
1958
1943
|
target,
|
|
1959
1944
|
namespace,
|
|
1960
1945
|
schema,
|
|
1961
|
-
|
|
1946
|
+
operations,
|
|
1962
1947
|
t,
|
|
1963
1948
|
readOnly: !state.writable,
|
|
1964
1949
|
onClose: (changed) => {
|
|
@@ -2037,7 +2022,7 @@ window.__ModuleLoader__.load({
|
|
|
2037
2022
|
target,
|
|
2038
2023
|
namespace,
|
|
2039
2024
|
schema,
|
|
2040
|
-
|
|
2025
|
+
operations,
|
|
2041
2026
|
t,
|
|
2042
2027
|
readOnly: !state.writable,
|
|
2043
2028
|
onClose: (changed) => {
|
|
@@ -2081,7 +2066,7 @@ window.__ModuleLoader__.load({
|
|
|
2081
2066
|
namespace: addNamespace,
|
|
2082
2067
|
schema,
|
|
2083
2068
|
settingsPath: addTarget.settingsPath,
|
|
2084
|
-
|
|
2069
|
+
operations,
|
|
2085
2070
|
t,
|
|
2086
2071
|
readOnly: !state.writable,
|
|
2087
2072
|
onClose: (changed) => {
|
|
@@ -2101,7 +2086,7 @@ window.__ModuleLoader__.load({
|
|
|
2101
2086
|
protocols,
|
|
2102
2087
|
/* v8 ignore next -- the card only opens from a button disabled without this namespace */
|
|
2103
2088
|
revision: state.namespaces.get("llm-pi-ai")?.revision ?? 0,
|
|
2104
|
-
|
|
2089
|
+
operations,
|
|
2105
2090
|
t,
|
|
2106
2091
|
readOnly: !state.writable,
|
|
2107
2092
|
onClose: (changed) => {
|
|
@@ -2265,7 +2250,7 @@ window.__ModuleLoader__.load({
|
|
|
2265
2250
|
* @returns the onboarding modal or null when onboarding needs no intervention.
|
|
2266
2251
|
*/
|
|
2267
2252
|
function DeepSeekOnboardingDialog(props) {
|
|
2268
|
-
const { complete, controller, useModels,
|
|
2253
|
+
const { complete, controller, useModels, operations, schema, t } = props;
|
|
2269
2254
|
const state = useModels((snapshot) => snapshot);
|
|
2270
2255
|
const readiness = onboardingReadiness(state);
|
|
2271
2256
|
(0, react.useEffect)(() => {
|
|
@@ -2307,7 +2292,7 @@ window.__ModuleLoader__.load({
|
|
|
2307
2292
|
namespace,
|
|
2308
2293
|
schema,
|
|
2309
2294
|
settingsPath: row.entry.settingsPath,
|
|
2310
|
-
|
|
2295
|
+
operations,
|
|
2311
2296
|
t,
|
|
2312
2297
|
readOnly: false,
|
|
2313
2298
|
hideTitle: true,
|
|
@@ -2533,6 +2518,61 @@ window.__ModuleLoader__.load({
|
|
|
2533
2518
|
}
|
|
2534
2519
|
};
|
|
2535
2520
|
//#endregion
|
|
2521
|
+
//#region lib/types/client/operations.js
|
|
2522
|
+
/**
|
|
2523
|
+
* The Host reads and writes the Models cards perform, as callbacks built in the
|
|
2524
|
+
* plugin body. Cards receive these instead of a context: the outcomes name what
|
|
2525
|
+
* a card renders — a stored view, a stale revision, a refusal message — so the
|
|
2526
|
+
* failure codes and Remote namespaces stay in the apply world.
|
|
2527
|
+
*/
|
|
2528
|
+
/**
|
|
2529
|
+
* Bind the page's Host operations to the plugin's own Remote namespaces.
|
|
2530
|
+
* @param ctx - the page plugin's context, which declares `remote.credentials`,
|
|
2531
|
+
* `remote.llm`, and `remote.settings` in its own `inject`.
|
|
2532
|
+
* @returns the callbacks the section and its cards are injected with.
|
|
2533
|
+
*/
|
|
2534
|
+
function createModelsOperations(ctx) {
|
|
2535
|
+
return {
|
|
2536
|
+
describeCredential: async (ref) => {
|
|
2537
|
+
const response = await ctx.remote.credentials.describe([ref]);
|
|
2538
|
+
return response.ok ? response.value[ref] : void 0;
|
|
2539
|
+
},
|
|
2540
|
+
storeCredential: async (ref, value) => {
|
|
2541
|
+
const response = await ctx.remote.credentials.set(ref, value);
|
|
2542
|
+
return response.ok ? void 0 : response.error.message;
|
|
2543
|
+
},
|
|
2544
|
+
removeCredential: async (ref) => {
|
|
2545
|
+
const response = await ctx.remote.credentials.unset(ref);
|
|
2546
|
+
return response.ok ? void 0 : response.error.message;
|
|
2547
|
+
},
|
|
2548
|
+
writeSettings: async (ns, ops, expectedRevision) => {
|
|
2549
|
+
const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision);
|
|
2550
|
+
if (response.ok) return {
|
|
2551
|
+
kind: "written",
|
|
2552
|
+
view: response.value
|
|
2553
|
+
};
|
|
2554
|
+
const { code, message } = response.error;
|
|
2555
|
+
return code === "settings/conflict" ? {
|
|
2556
|
+
kind: "conflict",
|
|
2557
|
+
message
|
|
2558
|
+
} : {
|
|
2559
|
+
kind: "refused",
|
|
2560
|
+
message
|
|
2561
|
+
};
|
|
2562
|
+
},
|
|
2563
|
+
discoverModels: async (settingsNs, request) => {
|
|
2564
|
+
const response = await ctx.remote.llm.discoverModels(settingsNs, request);
|
|
2565
|
+
return response.ok ? {
|
|
2566
|
+
kind: "found",
|
|
2567
|
+
models: response.value
|
|
2568
|
+
} : {
|
|
2569
|
+
kind: "refused",
|
|
2570
|
+
message: response.error.message
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
//#endregion
|
|
2536
2576
|
//#region lib/types/client/schema-operations.js
|
|
2537
2577
|
/**
|
|
2538
2578
|
* Hide the Cordis service identity behind bound schema callbacks.
|
|
@@ -2793,24 +2833,20 @@ window.__ModuleLoader__.load({
|
|
|
2793
2833
|
en
|
|
2794
2834
|
}), "ui-settings-models: copy dictionaries");
|
|
2795
2835
|
const schema = createSettingsSchemaOperations(ctx.settingsSchema);
|
|
2796
|
-
const
|
|
2797
|
-
|
|
2798
|
-
llm: ctx.remote.llm,
|
|
2799
|
-
settings: ctx.remote.settings
|
|
2800
|
-
};
|
|
2801
|
-
const controller = new ModelsSettingsStore(wire, schema, ctx.settingsScope.describe());
|
|
2836
|
+
const operations = createModelsOperations(ctx);
|
|
2837
|
+
const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe());
|
|
2802
2838
|
const t = ctx.locale.bind(NS);
|
|
2803
2839
|
const injected = () => ({
|
|
2804
2840
|
controller,
|
|
2805
2841
|
hooks: { snapshot: controller.store },
|
|
2806
|
-
|
|
2842
|
+
operations,
|
|
2807
2843
|
schema,
|
|
2808
2844
|
t
|
|
2809
2845
|
});
|
|
2810
2846
|
const deepSeekOnboardingInjected = () => ({
|
|
2811
2847
|
controller,
|
|
2812
2848
|
hooks: { models: controller.store },
|
|
2813
|
-
|
|
2849
|
+
operations,
|
|
2814
2850
|
schema,
|
|
2815
2851
|
t
|
|
2816
2852
|
});
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* levels instead.
|
|
22
22
|
*/
|
|
23
23
|
import type { ReactNode } from 'react';
|
|
24
|
-
import type {
|
|
24
|
+
import type { ModelsOperations } from './operations.ts';
|
|
25
25
|
import type { en } from './locales.ts';
|
|
26
26
|
/** Props of {@link CustomProviderCard}. */
|
|
27
27
|
export interface CustomProviderCardProps {
|
|
@@ -35,8 +35,8 @@ export interface CustomProviderCardProps {
|
|
|
35
35
|
* than a silent overwrite of its whole profile.
|
|
36
36
|
*/
|
|
37
37
|
revision: number;
|
|
38
|
-
/**
|
|
39
|
-
|
|
38
|
+
/** The Host operations this card writes and interrogates through. */
|
|
39
|
+
operations: ModelsOperations;
|
|
40
40
|
/** Section copy. */
|
|
41
41
|
t: (key: keyof typeof en) => string;
|
|
42
42
|
/** Disable writes (read-only settings provider). */
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
import type { ReactNode } from 'react';
|
|
9
9
|
import type { SnapshotStore } from '@prettier-ai/dsh-client-store';
|
|
10
10
|
import type { InjectFace, PropsRuntime } from '@prettier-ai/dsh-client-ui-slots';
|
|
11
|
-
import type { ModelsSettingsState, ModelsSettingsStore
|
|
11
|
+
import type { ModelsSettingsState, ModelsSettingsStore } from './store.ts';
|
|
12
|
+
import type { ModelsOperations } from './operations.ts';
|
|
12
13
|
import type { SettingsSchemaOperations } from './schema-operations.ts';
|
|
13
14
|
import type { en } from './locales.ts';
|
|
14
15
|
/** Registration-side dependencies of {@link DeepSeekOnboardingDialog}. */
|
|
@@ -19,8 +20,8 @@ export interface DeepSeekOnboardingInjected {
|
|
|
19
20
|
};
|
|
20
21
|
/** Shared Models-page join controller. */
|
|
21
22
|
controller: ModelsSettingsStore;
|
|
22
|
-
/**
|
|
23
|
-
|
|
23
|
+
/** The Host operations the reused Models credential editor writes through. */
|
|
24
|
+
operations: ModelsOperations;
|
|
24
25
|
/** Settings schema and immutable path callbacks. */
|
|
25
26
|
schema: SettingsSchemaOperations;
|
|
26
27
|
/** Feature copy. */
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* rows the user can still fill in by hand.
|
|
15
15
|
*/
|
|
16
16
|
import type { ReactNode } from 'react';
|
|
17
|
+
import type { ModelsOperations } from './operations.ts';
|
|
17
18
|
import type { DeepSeekModelDraft } from './DeepSeekModelsEditor.tsx';
|
|
18
|
-
import { type ModelsWire } from './store.ts';
|
|
19
19
|
import type { en } from './locales.ts';
|
|
20
20
|
/**
|
|
21
21
|
* One configured model row. Fields this card does not edit must survive an
|
|
@@ -58,8 +58,8 @@ export interface ModelListEditorProps {
|
|
|
58
58
|
* told what the field already says.
|
|
59
59
|
*/
|
|
60
60
|
probeBlocked?: keyof typeof en | undefined;
|
|
61
|
-
/**
|
|
62
|
-
|
|
61
|
+
/** The Host operations whose interrogation answers the fetch action. */
|
|
62
|
+
operations: ModelsOperations;
|
|
63
63
|
/** Section copy. */
|
|
64
64
|
t: (key: keyof typeof en) => string;
|
|
65
65
|
/** Disable every control (read-only deployment or a pending write). */
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { ReactNode } from 'react';
|
|
15
15
|
import type { InjectFace, PropsRenderSlots } from '@prettier-ai/dsh-client-ui-slots';
|
|
16
|
-
import type { ModelsSettingsStore,
|
|
16
|
+
import type { ModelsSettingsStore, ProviderRow } from './store.ts';
|
|
17
|
+
import type { ModelsOperations } from './operations.ts';
|
|
17
18
|
import type { SettingsSchemaOperations } from './schema-operations.ts';
|
|
18
19
|
import type { en } from './locales.ts';
|
|
19
20
|
/** Injected dependencies of {@link ModelsSection} (slot `inject`). */
|
|
@@ -24,8 +25,8 @@ export interface ModelsSectionInjected {
|
|
|
24
25
|
/** Page snapshot bound by the UI renderer as useSnapshot. */
|
|
25
26
|
snapshot: ModelsSettingsStore['store'];
|
|
26
27
|
};
|
|
27
|
-
/**
|
|
28
|
-
|
|
28
|
+
/** The Host operations the section and its cards invoke. */
|
|
29
|
+
operations: ModelsOperations;
|
|
29
30
|
/** Settings schema and immutable path callbacks. */
|
|
30
31
|
schema: SettingsSchemaOperations;
|
|
31
32
|
/** Section copy. */
|
|
@@ -54,12 +55,12 @@ export interface ProviderIdentity {
|
|
|
54
55
|
* and the whole operation safely retryable; both unsets are idempotent.
|
|
55
56
|
* The settings removal names the profile rather than rebuilding its whole
|
|
56
57
|
* namespace from a partial view.
|
|
57
|
-
* @param
|
|
58
|
+
* @param operations - the page's Host operations.
|
|
58
59
|
* @param controller - the page store to refresh.
|
|
59
60
|
* @param target - the provider's settings address and optional managed credential.
|
|
60
61
|
* @returns the failure message, or undefined once the write and reload landed.
|
|
61
62
|
*/
|
|
62
|
-
export declare function removeProviderProfile(
|
|
63
|
+
export declare function removeProviderProfile(operations: ModelsOperations, controller: ModelsSettingsStore, target: {
|
|
63
64
|
settingsNs: string;
|
|
64
65
|
settingsPath: readonly string[];
|
|
65
66
|
credentialRef?: string;
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import type { ReactNode } from 'react';
|
|
24
24
|
import type { SettingsNamespaceView, SettingsPathOpView } from '@prettier-ai/dsh-api-remotes/client';
|
|
25
|
-
import type {
|
|
25
|
+
import type { ModelsOperations } from './operations.ts';
|
|
26
26
|
import type { SettingsSchemaOperations } from './schema-operations.ts';
|
|
27
27
|
import type { en } from './locales.ts';
|
|
28
28
|
/** Props of {@link ProviderEditor}. */
|
|
@@ -47,8 +47,8 @@ export interface ProviderEditorProps {
|
|
|
47
47
|
schema: SettingsSchemaOperations;
|
|
48
48
|
/** Path from the section root to this provider's profile. */
|
|
49
49
|
settingsPath: readonly string[];
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/** The Host operations this card writes and interrogates through. */
|
|
51
|
+
operations: ModelsOperations;
|
|
52
52
|
/** Section copy. */
|
|
53
53
|
t: (key: keyof typeof en) => string;
|
|
54
54
|
/** Disable writes (read-only settings provider). */
|
|
@@ -18,7 +18,8 @@ declare module '@prettier-ai/dsh-client-ui-slots' {
|
|
|
18
18
|
'settings.models': ModelsKey;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
export type {
|
|
21
|
+
export type { ModelsSettingsState, ProviderDirectoryEntry, ProviderRow, } from './store.ts';
|
|
22
|
+
export type { ModelDiscoveryOutcome, ModelsOperations, SettingsWriteOutcome } from './operations.ts';
|
|
22
23
|
/**
|
|
23
24
|
* Refetch the page snapshot only after its first load: an unopened Models
|
|
24
25
|
* page must not fetch on background invalidations.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Host reads and writes the Models cards perform, as callbacks built in the
|
|
3
|
+
* plugin body. Cards receive these instead of a context: the outcomes name what
|
|
4
|
+
* a card renders — a stored view, a stale revision, a refusal message — so the
|
|
5
|
+
* failure codes and Remote namespaces stay in the apply world.
|
|
6
|
+
*/
|
|
7
|
+
import type { Context as ClientContext } from '@prettier-ai/cordis';
|
|
8
|
+
import type { CredentialInfo, LlmDiscoveredModel, LlmModelDiscoveryRequest, SettingsNamespaceView, SettingsPathOpView } from '@prettier-ai/dsh-api-remotes/client';
|
|
9
|
+
/** What one namespace write answered. */
|
|
10
|
+
export type SettingsWriteOutcome =
|
|
11
|
+
/** Committed; the view carries the stored user subtree and the new revision. */
|
|
12
|
+
{
|
|
13
|
+
readonly kind: 'written';
|
|
14
|
+
readonly view: SettingsNamespaceView;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The stored revision moved after the card read it, so the draft is stale.
|
|
18
|
+
* The message stays for callers that report the Host diagnostic as it is.
|
|
19
|
+
*/
|
|
20
|
+
| {
|
|
21
|
+
readonly kind: 'conflict';
|
|
22
|
+
readonly message: string;
|
|
23
|
+
}
|
|
24
|
+
/** Any other refusal, with the Host's own diagnostic. */
|
|
25
|
+
| {
|
|
26
|
+
readonly kind: 'refused';
|
|
27
|
+
readonly message: string;
|
|
28
|
+
};
|
|
29
|
+
/** What one endpoint interrogation answered. */
|
|
30
|
+
export type ModelDiscoveryOutcome =
|
|
31
|
+
/** The candidates the provider disclosed, in its own order. */
|
|
32
|
+
{
|
|
33
|
+
readonly kind: 'found';
|
|
34
|
+
readonly models: readonly LlmDiscoveredModel[];
|
|
35
|
+
}
|
|
36
|
+
/** The interrogation was refused, with the Host's own diagnostic. */
|
|
37
|
+
| {
|
|
38
|
+
readonly kind: 'refused';
|
|
39
|
+
readonly message: string;
|
|
40
|
+
};
|
|
41
|
+
/** The Host operations the Models page and its cards invoke. */
|
|
42
|
+
export interface ModelsOperations {
|
|
43
|
+
/**
|
|
44
|
+
* Read one credential reference's state.
|
|
45
|
+
* @param ref - credential reference name.
|
|
46
|
+
* @returns the state, or undefined when the reference is unknown or the read was refused.
|
|
47
|
+
*/
|
|
48
|
+
describeCredential(ref: string): Promise<CredentialInfo | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Store one credential literal under its reference.
|
|
51
|
+
* @param ref - credential reference name.
|
|
52
|
+
* @param value - the literal to store.
|
|
53
|
+
* @returns the refusal message, or undefined once stored.
|
|
54
|
+
*/
|
|
55
|
+
storeCredential(ref: string, value: string): Promise<string | undefined>;
|
|
56
|
+
/**
|
|
57
|
+
* Remove one credential reference (idempotent).
|
|
58
|
+
* @param ref - credential reference name.
|
|
59
|
+
* @returns the refusal message, or undefined once removed.
|
|
60
|
+
*/
|
|
61
|
+
removeCredential(ref: string): Promise<string | undefined>;
|
|
62
|
+
/**
|
|
63
|
+
* Apply path operations to one settings namespace.
|
|
64
|
+
* @param ns - settings namespace identity.
|
|
65
|
+
* @param ops - ordered path operations against the stored section, as the
|
|
66
|
+
* wire takes them (the Remote signature owns the array).
|
|
67
|
+
* @param expectedRevision - revision the draft was opened at, or undefined to write unfenced.
|
|
68
|
+
* @returns the write outcome the card renders from.
|
|
69
|
+
*/
|
|
70
|
+
writeSettings(ns: string, ops: SettingsPathOpView[], expectedRevision: number | undefined): Promise<SettingsWriteOutcome>;
|
|
71
|
+
/**
|
|
72
|
+
* Ask a provider endpoint what models it serves.
|
|
73
|
+
* @param settingsNs - namespace whose adapter family answers.
|
|
74
|
+
* @param request - endpoint facts as the form currently shows them.
|
|
75
|
+
* @returns the candidates, or the refusal.
|
|
76
|
+
*/
|
|
77
|
+
discoverModels(settingsNs: string, request: LlmModelDiscoveryRequest): Promise<ModelDiscoveryOutcome>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Bind the page's Host operations to the plugin's own Remote namespaces.
|
|
81
|
+
* @param ctx - the page plugin's context, which declares `remote.credentials`,
|
|
82
|
+
* `remote.llm`, and `remote.settings` in its own `inject`.
|
|
83
|
+
* @returns the callbacks the section and its cards are injected with.
|
|
84
|
+
*/
|
|
85
|
+
export declare function createModelsOperations(ctx: ClientContext): ModelsOperations;
|
|
86
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -6,14 +6,11 @@
|
|
|
6
6
|
* single fact source — every mutation writes through the wire and the page
|
|
7
7
|
* re-renders from the next describe, pushed or refetched.
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { Context as ClientContext } from '@prettier-ai/cordis';
|
|
10
|
+
import type { CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView } from '@prettier-ai/dsh-api-remotes/client';
|
|
10
11
|
import type { SnapshotStore } from '@prettier-ai/dsh-client-store';
|
|
11
|
-
import type { SettingsDescribeFace
|
|
12
|
+
import type { SettingsDescribeFace } from '@prettier-ai/dsh-client-ui-settings/client';
|
|
12
13
|
import type { SettingsSchemaOperations } from './schema-operations.ts';
|
|
13
|
-
/** The credentials Remote methods the Models page reads and writes through. */
|
|
14
|
-
export type ModelsCredentials = Pick<ClientRemote['credentials'], 'describe' | 'set' | 'unset'>;
|
|
15
|
-
/** LLM Remote methods used by the Models page. */
|
|
16
|
-
export type ModelsLlm = Pick<ClientRemote['llm'], 'discoverModels' | 'listConfigurableProviders' | 'listProviders'>;
|
|
17
14
|
/** One provider row after joining the configurable directory with live routes. */
|
|
18
15
|
export interface ProviderDirectoryEntry {
|
|
19
16
|
readonly provider: string;
|
|
@@ -30,17 +27,6 @@ export interface ProviderDirectoryEntry {
|
|
|
30
27
|
* @returns declared rows followed by live routes with no declaration.
|
|
31
28
|
*/
|
|
32
29
|
export declare function joinProviderDirectory(registered: readonly LlmProviderInfo[], directory: readonly LlmConfigurableProvider[]): ProviderDirectoryEntry[];
|
|
33
|
-
/**
|
|
34
|
-
* Every Remote wire face the Models page reaches.
|
|
35
|
-
*/
|
|
36
|
-
export interface ModelsWire {
|
|
37
|
-
/** The settings Remote namespace: the redacted read and the profile writes. */
|
|
38
|
-
settings: SettingsRemote;
|
|
39
|
-
/** Credential state and writes for the references provider profiles name. */
|
|
40
|
-
credentials: ModelsCredentials;
|
|
41
|
-
/** Provider directory reads and draft endpoint discovery. */
|
|
42
|
-
llm: ModelsLlm;
|
|
43
|
-
}
|
|
44
30
|
/** One provider row the page renders. */
|
|
45
31
|
export interface ProviderRow {
|
|
46
32
|
/** The directory entry (route id, display name, settings address, live state). */
|
|
@@ -75,14 +61,6 @@ export interface ModelsSettingsState {
|
|
|
75
61
|
/** Namespace views by ns, for the editor's schema/layers/secrets. */
|
|
76
62
|
namespaces: ReadonlyMap<string, SettingsNamespaceView>;
|
|
77
63
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Human text for a rejected wire call. A transport failure rejects with an
|
|
80
|
-
* Error; a host or a runtime can reject with anything, and the page still has
|
|
81
|
-
* to say something.
|
|
82
|
-
* @param error - the rejection value.
|
|
83
|
-
* @returns the message to show.
|
|
84
|
-
*/
|
|
85
|
-
export declare function messageOf(error: unknown): string;
|
|
86
64
|
/**
|
|
87
65
|
* Derive the conventional credential reference for a provider route: the v1
|
|
88
66
|
* page never asks for an environment-variable name, so a typed key stores
|
|
@@ -103,7 +81,7 @@ export declare function deriveKeyRef(provider: string): string;
|
|
|
103
81
|
export declare function protocolChoices(namespace: SettingsNamespaceView | undefined, schema: SettingsSchemaOperations): string[];
|
|
104
82
|
/** The models settings page controller (one per settings surface). */
|
|
105
83
|
export declare class ModelsSettingsStore {
|
|
106
|
-
private readonly
|
|
84
|
+
private readonly ctx;
|
|
107
85
|
private readonly schema;
|
|
108
86
|
private readonly describeFace;
|
|
109
87
|
/** The snapshot the section renders from (uSES-safe store). */
|
|
@@ -111,10 +89,12 @@ export declare class ModelsSettingsStore {
|
|
|
111
89
|
/** Latest load wins; an older response never overwrites a newer one. */
|
|
112
90
|
private generation;
|
|
113
91
|
/**
|
|
114
|
-
* @param
|
|
92
|
+
* @param ctx - the page plugin's context, whose `remote.llm` and
|
|
93
|
+
* `remote.credentials` namespaces carry the directory and credential reads.
|
|
94
|
+
* @param schema - settings-owned schema and immutable path operations.
|
|
115
95
|
* @param describeFace - the shared mirror's describe face (namespace views and writability).
|
|
116
96
|
*/
|
|
117
|
-
constructor(
|
|
97
|
+
constructor(ctx: ClientContext, schema: SettingsSchemaOperations, describeFace: SettingsDescribeFace);
|
|
118
98
|
/**
|
|
119
99
|
* Refresh the whole page snapshot: the provider directory and the mirror's
|
|
120
100
|
* settings answer in parallel, then one batched credential describe over
|
|
@@ -124,6 +104,8 @@ export declare class ModelsSettingsStore {
|
|
|
124
104
|
* @returns nothing; the snapshot carries the outcome.
|
|
125
105
|
*/
|
|
126
106
|
load(): Promise<void>;
|
|
107
|
+
/** Publish one load's failure text, unless a newer load already took over. */
|
|
108
|
+
private failLoad;
|
|
127
109
|
}
|
|
128
110
|
/**
|
|
129
111
|
* Whether a joined row can serve model requests as it stands: the route is
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prettier-ai/dsh-client-ui-settings-models",
|
|
3
3
|
"description": "Models settings and shared product-onboarding dialogs over existing settings and credential joins",
|
|
4
|
-
"version": "0.1.2-alpha.
|
|
4
|
+
"version": "0.1.2-alpha.3",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -41,26 +41,22 @@
|
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT",
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@prettier-ai/
|
|
45
|
-
"@prettier-ai/cordis": "^4.0.1",
|
|
46
|
-
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.1",
|
|
47
|
-
"@prettier-ai/dsh-client-ui-settings": "^0.1.2-alpha.1",
|
|
48
|
-
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.1",
|
|
49
|
-
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.1"
|
|
44
|
+
"@prettier-ai/cordis": "^4.0.2"
|
|
50
45
|
},
|
|
51
46
|
"devDependencies": {
|
|
52
47
|
"@types/react": "~18.3.1",
|
|
53
48
|
"react": "^18.2.0",
|
|
54
|
-
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.
|
|
55
|
-
"@prettier-ai/dsh-client-
|
|
56
|
-
"@prettier-ai/dsh-client-
|
|
57
|
-
"@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.
|
|
58
|
-
"@prettier-ai/dsh-client-ui-
|
|
59
|
-
"@prettier-ai/dsh-client-
|
|
60
|
-
"@prettier-ai/dsh-client-ui-
|
|
61
|
-
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.
|
|
62
|
-
"@prettier-ai/cordis": "^4.0.
|
|
63
|
-
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.
|
|
49
|
+
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.3",
|
|
50
|
+
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.3",
|
|
51
|
+
"@prettier-ai/dsh-client-ui-settings": "^0.1.2-alpha.3",
|
|
52
|
+
"@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.3",
|
|
53
|
+
"@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.3",
|
|
54
|
+
"@prettier-ai/dsh-client-store": "^0.1.2-alpha.3",
|
|
55
|
+
"@prettier-ai/dsh-client-ui-primitives": "^0.1.2-alpha.3",
|
|
56
|
+
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.3",
|
|
57
|
+
"@prettier-ai/cordis": "^4.0.2",
|
|
58
|
+
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.3",
|
|
59
|
+
"@prettier-ai/dsh-util-values": "^0.1.2-alpha.3"
|
|
64
60
|
},
|
|
65
61
|
"files": [
|
|
66
62
|
"lib/index.js",
|