pi-mega-compact 0.20.49 → 0.20.51
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/config/vector-cortex-enc1a.js +39 -0
- package/dist/config/vector-cortex-enc1b.js +46 -0
- package/dist/config/vector-cortex.js +2 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +2 -0
- package/dist/extensions/dashboard-server/routes-setup-enc1a.js +157 -0
- package/dist/extensions/dashboard-server/routes-setup-enc1b.js +297 -0
- package/dist/extensions/dashboard-server/routes-setup-env-upsert.js +79 -0
- package/dist/extensions/dashboard-server/routes-setup.js +47 -25
- package/dist/src/config/vector-cortex-enc1a.js +39 -0
- package/dist/src/config/vector-cortex-enc1b.js +46 -0
- package/dist/src/config/vector-cortex.js +2 -0
- package/dist/src/config.js +1 -1
- package/extensions/dashboard-client/dist/assets/{AreaChart-COnj8FHi.js → AreaChart-BFTUTmmW.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-COnj8FHi.js.map → AreaChart-BFTUTmmW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-BYqt8c5-.js → BarChart-DfFurESR.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-BYqt8c5-.js.map → BarChart-DfFurESR.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-PLRjMrZV.js → CacheTab-FpCJSmy8.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-PLRjMrZV.js.map → CacheTab-FpCJSmy8.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-DXKSft6w.js → EventsTab--9lJFJtc.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-DXKSft6w.js.map → EventsTab--9lJFJtc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-BgVIsrde.js → HealthTab-CkgtF1qa.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-BgVIsrde.js.map → HealthTab-CkgtF1qa.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DNgFC8KZ.js → MaintenanceTab-ChXGq1or.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DNgFC8KZ.js.map → MaintenanceTab-ChXGq1or.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-B6yY47sz.js → MemoryMapTab-CPpRR4MV.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-B6yY47sz.js.map → MemoryMapTab-CPpRR4MV.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-BrhJ6rkx.js → MetricsTab-Db1wkykf.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-BrhJ6rkx.js.map → MetricsTab-Db1wkykf.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-RFHU9L4x.js → OverviewTab-LanDECrz.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-RFHU9L4x.js.map → OverviewTab-LanDECrz.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-UFIWKkJM.js → ReposTab-I2umKduk.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-UFIWKkJM.js.map → ReposTab-I2umKduk.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-BHFYsmK8.js → SessionsTab-D_IxuEt5.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-BHFYsmK8.js.map → SessionsTab-D_IxuEt5.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-BZ7Jn5MR.js +3 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-BZ7Jn5MR.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-aPG5Knqn.js → TimeSavedCard-BTdcO1E2.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-aPG5Knqn.js.map → TimeSavedCard-BTdcO1E2.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-fGm9n-Tk.js → TurnsTab-BXC8IL_B.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-fGm9n-Tk.js.map → TurnsTab-BXC8IL_B.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-BtmSNH8X.js → VcStatusBadge-CNJnFtJo.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-BtmSNH8X.js.map → VcStatusBadge-CNJnFtJo.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-meALMMOZ.js → VectorCortexTab-fsuWgA6e.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-meALMMOZ.js.map → VectorCortexTab-fsuWgA6e.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-0TK6q6g1.js → WikiTab-Cn1BScDU.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-0TK6q6g1.js.map → WikiTab-Cn1BScDU.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-CKEnMZ98.js → button-B4_9rsul.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-CKEnMZ98.js.map → button-B4_9rsul.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-BVVhm3sL.js → card-DUvC_geI.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-BVVhm3sL.js.map → card-DUvC_geI.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{client-extra-BvGxKZpm.js → client-extra-HaH97bzp.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{client-extra-BvGxKZpm.js.map → client-extra-HaH97bzp.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-B1PeCct1.js → generateCategoricalChart-BxFWU2Mt.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-B1PeCct1.js.map → generateCategoricalChart-BxFWU2Mt.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/index-C_aDd9kk.css +1 -0
- package/extensions/dashboard-client/dist/assets/{index-DuThOA-d.js → index-xPdbZ73U.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-DuThOA-d.js.map → index-xPdbZ73U.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-7qLS7ajc.js → switch-Bv3_1R_j.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-7qLS7ajc.js.map → switch-Bv3_1R_j.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-D7mgOVxz.js → toggle-DHXrB3Aw.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-D7mgOVxz.js.map → toggle-DHXrB3Aw.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-ChpyZVeX.js → useSSE-NigHeFyT.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-ChpyZVeX.js.map → useSSE-NigHeFyT.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +2 -2
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexRuntimeCard.tsx +103 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexRuntimeCardStyles.ts +49 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetup.tsx +2 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CustomEndpointSection.tsx +178 -2
- package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +61 -113
- package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetupHelpers.tsx +125 -0
- package/extensions/dashboard-server/api-contracts/setup.ts +47 -0
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +12 -0
- package/extensions/dashboard-server/routes-setup-enc1a.ts +184 -0
- package/extensions/dashboard-server/routes-setup-enc1b.ts +336 -0
- package/extensions/dashboard-server/routes-setup-env-upsert.ts +93 -0
- package/extensions/dashboard-server/routes-setup.ts +46 -23
- package/package.json +1 -1
- package/src/config/vector-cortex-enc1a.ts +41 -0
- package/src/config/vector-cortex-enc1b.ts +50 -0
- package/src/config/vector-cortex.ts +9 -0
- package/src/config.ts +2 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-C3dnKa8y.js +0 -3
- package/extensions/dashboard-client/dist/assets/SetupTab-C3dnKa8y.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/index-DbuGwYD7.css +0 -1
|
@@ -2,15 +2,46 @@
|
|
|
2
2
|
* SetupTab/CustomEndpointSection.tsx — custom remote embedder endpoint section.
|
|
3
3
|
*
|
|
4
4
|
* Extracted from EmbedderSetup.tsx to respect the extensions/ 400-line soft limit.
|
|
5
|
+
*
|
|
6
|
+
* ENC-1a: an additive "API key (optional Bearer)" password input sits beside the
|
|
7
|
+
* existing custom-URL input. The key is NEVER prefilled (the setup-status GET does
|
|
8
|
+
* not echo it — only an "is set" boolean, embeddingApiKeySet) and it is only ever
|
|
9
|
+
* sent up via the POST /api/setup-configure body. When the ENC-1a surface is
|
|
10
|
+
* inactive (flag off, the server omits the new GET fields) the key input is hidden
|
|
11
|
+
* and only the pre-existing URL row remains — byte-identical to the predecessor.
|
|
5
12
|
*/
|
|
6
13
|
import type React from "react";
|
|
14
|
+
import { useState } from "react";
|
|
15
|
+
import type { SetupConfigureResponse } from "@contracts";
|
|
7
16
|
import { styles } from "./EmbedderSetupStyles";
|
|
8
17
|
|
|
18
|
+
/** ENC-1a surfaced a successful custom-endpoint persistence on the card. */
|
|
19
|
+
const SAVED_NOTICE = "Saved; takes effect on next session start";
|
|
20
|
+
|
|
9
21
|
interface CustomEndpointSectionProps {
|
|
10
22
|
customUrl: string;
|
|
11
23
|
setCustomUrl: (v: string) => void;
|
|
12
|
-
applyEmbedder: (
|
|
24
|
+
applyEmbedder: (
|
|
25
|
+
embedder: "ollama" | "llama" | "trigram" | "custom" | "onnx",
|
|
26
|
+
url?: string,
|
|
27
|
+
apiKey?: string,
|
|
28
|
+
dim?: string,
|
|
29
|
+
headers?: string,
|
|
30
|
+
allowRemote?: boolean,
|
|
31
|
+
) => void;
|
|
13
32
|
configuring: string | null;
|
|
33
|
+
/** ENC-1a surface active — true when the new setup-status fields are present. */
|
|
34
|
+
inputEnabled: boolean;
|
|
35
|
+
/** Server-reported "key is set" marker (the key itself is never returned). */
|
|
36
|
+
apiKeySet: boolean;
|
|
37
|
+
/** ENC-1b: the persisted `embeddingDim` value (numeric string), or undefined. One-shot seed. */
|
|
38
|
+
embeddingDim: string | undefined;
|
|
39
|
+
/** ENC-1b: server-reported "headers are set" marker (the raw JSON is never returned). */
|
|
40
|
+
embeddingHeadersSet: boolean;
|
|
41
|
+
/** ENC-1b: the persisted allow-remote flag, or undefined. One-shot seed. */
|
|
42
|
+
allowRemoteEmbedder: boolean | undefined;
|
|
43
|
+
configureResult: SetupConfigureResponse | null;
|
|
44
|
+
configureError: string | null;
|
|
14
45
|
}
|
|
15
46
|
|
|
16
47
|
export default function CustomEndpointSection({
|
|
@@ -18,7 +49,38 @@ export default function CustomEndpointSection({
|
|
|
18
49
|
setCustomUrl,
|
|
19
50
|
applyEmbedder,
|
|
20
51
|
configuring,
|
|
52
|
+
inputEnabled,
|
|
53
|
+
apiKeySet,
|
|
54
|
+
embeddingDim,
|
|
55
|
+
embeddingHeadersSet,
|
|
56
|
+
allowRemoteEmbedder,
|
|
57
|
+
configureResult,
|
|
58
|
+
configureError,
|
|
21
59
|
}: CustomEndpointSectionProps): React.ReactElement {
|
|
60
|
+
// The API key is intentionally local-only state: it always renders blank and
|
|
61
|
+
// is never seeded from the persisted value (the server never returns it).
|
|
62
|
+
const [customApiKey, setCustomApiKey] = useState("");
|
|
63
|
+
// ENC-1b: the embedding dim, seeded once from the persisted value (never
|
|
64
|
+
// re-seeded after a poll so the user's in-flight edits survive the 5s poll).
|
|
65
|
+
const [dim, setDim] = useState("");
|
|
66
|
+
const [dimSeeded, setDimSeeded] = useState(false);
|
|
67
|
+
// ENC-1b: the headers JSON is local-only, write-only state: NEVER prefilled,
|
|
68
|
+
// never seeded, never shown back — the server persists it verbatim and only
|
|
69
|
+
// ever reports its presence via `embeddingHeadersSet`.
|
|
70
|
+
const [headers, setHeaders] = useState("");
|
|
71
|
+
// ENC-1b: allow-remote toggle, seeded once from the persisted flag.
|
|
72
|
+
const [allowRemote, setAllowRemote] = useState(false);
|
|
73
|
+
const [allowRemoteSeeded, setAllowRemoteSeeded] = useState(false);
|
|
74
|
+
|
|
75
|
+
if (inputEnabled && !dimSeeded && typeof embeddingDim === "string") {
|
|
76
|
+
setDim(embeddingDim);
|
|
77
|
+
setDimSeeded(true);
|
|
78
|
+
}
|
|
79
|
+
if (inputEnabled && !allowRemoteSeeded && typeof allowRemoteEmbedder === "boolean") {
|
|
80
|
+
setAllowRemote(allowRemoteEmbedder);
|
|
81
|
+
setAllowRemoteSeeded(true);
|
|
82
|
+
}
|
|
83
|
+
|
|
22
84
|
return (
|
|
23
85
|
<div style={styles.section}>
|
|
24
86
|
<h3 style={styles.sectionTitle}>Custom Endpoint (remote / third-party)</h3>
|
|
@@ -46,14 +108,128 @@ export default function CustomEndpointSection({
|
|
|
46
108
|
fontFamily: "monospace",
|
|
47
109
|
}}
|
|
48
110
|
/>
|
|
111
|
+
{inputEnabled && (
|
|
112
|
+
<input
|
|
113
|
+
type="password"
|
|
114
|
+
autoComplete="new-password"
|
|
115
|
+
aria-label="API key (optional Bearer)"
|
|
116
|
+
placeholder="API key (optional Bearer)"
|
|
117
|
+
value={customApiKey}
|
|
118
|
+
onChange={(e) => setCustomApiKey(e.target.value)}
|
|
119
|
+
style={{
|
|
120
|
+
flex: "1 1 300px",
|
|
121
|
+
background: "#12122a",
|
|
122
|
+
color: "#e0e0e0",
|
|
123
|
+
border: "1px solid #2a2a4e",
|
|
124
|
+
borderRadius: "6px",
|
|
125
|
+
padding: "0.4rem 0.6rem",
|
|
126
|
+
fontSize: "0.85rem",
|
|
127
|
+
fontFamily: "monospace",
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
)}
|
|
131
|
+
{inputEnabled && apiKeySet && (
|
|
132
|
+
<span
|
|
133
|
+
style={{
|
|
134
|
+
fontSize: "0.75rem",
|
|
135
|
+
color: "#81c784",
|
|
136
|
+
border: "1px solid #2a4e2a",
|
|
137
|
+
borderRadius: "4px",
|
|
138
|
+
padding: "0.15rem 0.45rem",
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
API key saved
|
|
142
|
+
</span>
|
|
143
|
+
)}
|
|
144
|
+
{inputEnabled && embeddingHeadersSet && (
|
|
145
|
+
<span
|
|
146
|
+
style={{
|
|
147
|
+
fontSize: "0.75rem",
|
|
148
|
+
color: "#81c784",
|
|
149
|
+
border: "1px solid #2a4e2a",
|
|
150
|
+
borderRadius: "4px",
|
|
151
|
+
padding: "0.15rem 0.45rem",
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
Headers saved
|
|
155
|
+
</span>
|
|
156
|
+
)}
|
|
49
157
|
<button
|
|
50
158
|
style={{ ...styles.button, opacity: customUrl ? 1 : 0.4 }}
|
|
51
|
-
onClick={() =>
|
|
159
|
+
onClick={() =>
|
|
160
|
+
applyEmbedder("custom", customUrl, customApiKey, dim, headers, allowRemote)
|
|
161
|
+
}
|
|
52
162
|
disabled={!customUrl || configuring !== null}
|
|
53
163
|
>
|
|
54
164
|
{configuring === "custom" ? "Writing..." : "Use Custom URL"}
|
|
55
165
|
</button>
|
|
56
166
|
</div>
|
|
167
|
+
{inputEnabled && (
|
|
168
|
+
<div style={{ marginTop: "0.75rem" }}>
|
|
169
|
+
<div style={{ marginBottom: "0.5rem" }}>
|
|
170
|
+
<label style={{ ...styles.label, display: "block", marginBottom: "0.25rem" }}>
|
|
171
|
+
Embedding dim (optional)
|
|
172
|
+
</label>
|
|
173
|
+
<input
|
|
174
|
+
type="number"
|
|
175
|
+
min={1}
|
|
176
|
+
placeholder="e.g. 384"
|
|
177
|
+
value={dim}
|
|
178
|
+
onChange={(e) => setDim(e.target.value)}
|
|
179
|
+
style={{
|
|
180
|
+
width: "200px",
|
|
181
|
+
background: "#12122a",
|
|
182
|
+
color: "#e0e0e0",
|
|
183
|
+
border: "1px solid #2a2a4e",
|
|
184
|
+
borderRadius: "6px",
|
|
185
|
+
padding: "0.4rem 0.6rem",
|
|
186
|
+
fontSize: "0.85rem",
|
|
187
|
+
fontFamily: "monospace",
|
|
188
|
+
}}
|
|
189
|
+
/>
|
|
190
|
+
</div>
|
|
191
|
+
<div style={{ marginBottom: "0.5rem" }}>
|
|
192
|
+
<label style={{ ...styles.label, display: "block", marginBottom: "0.25rem" }}>
|
|
193
|
+
Embedding headers (JSON, write-only — never re-displayed)
|
|
194
|
+
</label>
|
|
195
|
+
<textarea
|
|
196
|
+
placeholder={'{"Authorization": "Bearer ..."}'}
|
|
197
|
+
value={headers}
|
|
198
|
+
onChange={(e) => setHeaders(e.target.value)}
|
|
199
|
+
aria-label="Embedding headers JSON (write-only — never re-displayed)"
|
|
200
|
+
rows={2}
|
|
201
|
+
style={{
|
|
202
|
+
width: "100%",
|
|
203
|
+
background: "#12122a",
|
|
204
|
+
color: "#e0e0e0",
|
|
205
|
+
border: "1px solid #2a2a4e",
|
|
206
|
+
borderRadius: "6px",
|
|
207
|
+
padding: "0.4rem 0.6rem",
|
|
208
|
+
fontSize: "0.85rem",
|
|
209
|
+
fontFamily: "monospace",
|
|
210
|
+
resize: "vertical",
|
|
211
|
+
}}
|
|
212
|
+
/>
|
|
213
|
+
</div>
|
|
214
|
+
<label style={{ display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.85rem" }}>
|
|
215
|
+
<input
|
|
216
|
+
type="checkbox"
|
|
217
|
+
checked={allowRemote}
|
|
218
|
+
onChange={(e) => setAllowRemote(e.target.checked)}
|
|
219
|
+
aria-label="Allow remote embedder (skips loopback-only check)"
|
|
220
|
+
/>
|
|
221
|
+
Allow remote embedder (skips loopback-only check)
|
|
222
|
+
</label>
|
|
223
|
+
</div>
|
|
224
|
+
)}
|
|
225
|
+
{configureError !== null && (
|
|
226
|
+
<p style={{ color: "#f44336", fontSize: "0.85rem", marginTop: "0.5rem" }}>
|
|
227
|
+
Configure error: {configureError}
|
|
228
|
+
</p>
|
|
229
|
+
)}
|
|
230
|
+
{configureResult !== null && configureResult.embedder === "custom" && (
|
|
231
|
+
<div style={styles.warning}>{SAVED_NOTICE}</div>
|
|
232
|
+
)}
|
|
57
233
|
<div style={styles.warning}>
|
|
58
234
|
<strong>Heads up:</strong> a remote endpoint receives the text you embed
|
|
59
235
|
(it does NOT receive your full conversation — only the strings passed to
|
|
@@ -16,6 +16,7 @@ import EmbedderHealthCard from "./EmbedderHealthCard";
|
|
|
16
16
|
import SettingsPanel from "./SettingsPanel";
|
|
17
17
|
import CustomEndpointSection from "./CustomEndpointSection";
|
|
18
18
|
import { styles } from "./EmbedderSetupStyles";
|
|
19
|
+
import { detectBadge, CurrentConfigSection } from "./EmbedderSetupHelpers";
|
|
19
20
|
|
|
20
21
|
export default function EmbedderSetup(): React.ReactElement {
|
|
21
22
|
const [status, setStatus] = useState<SetupStatusResponse | null>(null);
|
|
@@ -27,6 +28,10 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
27
28
|
const [configResult, setConfigResult] = useState<SetupConfigureResponse | null>(null);
|
|
28
29
|
const [configError, setConfigError] = useState<string | null>(null);
|
|
29
30
|
const [customUrl, setCustomUrl] = useState("");
|
|
31
|
+
// True once the URL field has been seeded from the persisted endpoint URL —
|
|
32
|
+
// seeding runs only on the first status load that carries the field so the
|
|
33
|
+
// user's in-flight edits are never clobbered by a poll refresh.
|
|
34
|
+
const [customUrlSeeded, setCustomUrlSeeded] = useState(false);
|
|
30
35
|
|
|
31
36
|
const loadStatus = useCallback(() => {
|
|
32
37
|
fetchSetupStatus()
|
|
@@ -36,21 +41,43 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
36
41
|
);
|
|
37
42
|
}, []);
|
|
38
43
|
|
|
39
|
-
const applyEmbedder = useCallback(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
const applyEmbedder = useCallback(
|
|
45
|
+
(
|
|
46
|
+
embedder: "ollama" | "llama" | "trigram" | "custom" | "onnx",
|
|
47
|
+
url?: string,
|
|
48
|
+
apiKey?: string,
|
|
49
|
+
dim?: string,
|
|
50
|
+
headers?: string,
|
|
51
|
+
allowRemote?: boolean,
|
|
52
|
+
) => {
|
|
53
|
+
setConfiguring(embedder);
|
|
54
|
+
setConfigError(null);
|
|
55
|
+
setConfigResult(null);
|
|
56
|
+
// ENC-1a: optional custom-endpoint URL + bearer key ride on the setup-configure POST (additive; flag-off ignores them).
|
|
57
|
+
// ENC-1b: the dim / headers / allow-remote fields are forwarded additively, gated on the same
|
|
58
|
+
// `embeddingHeadersSet` presence marker the aggregator/server uses (no separate client env read).
|
|
59
|
+
const enc1bOn = "embeddingHeadersSet" in (status ?? {});
|
|
60
|
+
configureEmbedder({
|
|
61
|
+
embedder,
|
|
62
|
+
url,
|
|
63
|
+
embeddingEndpointUrl: url,
|
|
64
|
+
embeddingApiKey: apiKey,
|
|
65
|
+
...(enc1bOn
|
|
66
|
+
? { embeddingDim: dim, embeddingHeaders: headers, allowRemoteEmbedder: allowRemote }
|
|
67
|
+
: {}),
|
|
48
68
|
})
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
69
|
+
.then((r) => {
|
|
70
|
+
setConfigResult(r);
|
|
71
|
+
setConfiguring(null);
|
|
72
|
+
loadStatus();
|
|
73
|
+
})
|
|
74
|
+
.catch((e: unknown) => {
|
|
75
|
+
setConfigError(e instanceof Error ? e.message : String(e));
|
|
76
|
+
setConfiguring(null);
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
[loadStatus, status],
|
|
80
|
+
);
|
|
54
81
|
|
|
55
82
|
const runDetect = useCallback(() => {
|
|
56
83
|
setRunningDetect(true);
|
|
@@ -70,6 +97,17 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
70
97
|
loadStatus();
|
|
71
98
|
}, [loadStatus]);
|
|
72
99
|
|
|
100
|
+
// Seed the custom-endpoint URL field once from the persisted
|
|
101
|
+
// `embeddingEndpointUrl` (ENC-1a). Later poll refreshes do NOT re-seed —
|
|
102
|
+
// only the first load, so typed edits survive the 5s status poll.
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (customUrlSeeded) return;
|
|
105
|
+
if (status && typeof status.embeddingEndpointUrl === "string" && status.embeddingEndpointUrl.length > 0) {
|
|
106
|
+
setCustomUrl(status.embeddingEndpointUrl);
|
|
107
|
+
setCustomUrlSeeded(true);
|
|
108
|
+
}
|
|
109
|
+
}, [status, customUrlSeeded]);
|
|
110
|
+
|
|
73
111
|
// Poll status every 5s — the same cadence the Setup Cortex sub-tab uses
|
|
74
112
|
// (see useSetupCortexPoll) so the embedder + cortex sub-tabs share one poll
|
|
75
113
|
// contract (VC9D consolidation). Detection is memoized server-side, so the
|
|
@@ -88,41 +126,6 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
88
126
|
return () => clearInterval(id);
|
|
89
127
|
}, [runDetect]);
|
|
90
128
|
|
|
91
|
-
const embedderLabel = (e: string): string => {
|
|
92
|
-
switch (e) {
|
|
93
|
-
case "trigram":
|
|
94
|
-
return "TrigramEmbedder (heuristic, default)";
|
|
95
|
-
case "http":
|
|
96
|
-
return "HTTP Embedder (BYO localhost)";
|
|
97
|
-
case "minilm":
|
|
98
|
-
return "MiniLM (experimental)";
|
|
99
|
-
default:
|
|
100
|
-
return "Unknown";
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const trigramWarning = status?.currentEmbedder === "trigram" && (
|
|
105
|
-
<div style={styles.warning}>
|
|
106
|
-
<strong>Note:</strong> TrigramEmbedder is a heuristic-strength default
|
|
107
|
-
embedder. It works without any setup but recall quality may be lower
|
|
108
|
-
than a dedicated embedding backend. If you notice poor recall results,
|
|
109
|
-
consider installing Ollama and running the{" "}
|
|
110
|
-
<code>/megasetup</code> command, or set{" "}
|
|
111
|
-
<code>MEGACOMPACT_EMBEDDING_URL</code> to point at your own localhost
|
|
112
|
-
embedding server.
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
const detectBadge = (installed: boolean): React.ReactElement => {
|
|
117
|
-
const bg = installed ? "#1a5a1a" : "#3a1a1a";
|
|
118
|
-
const color = installed ? "#4caf50" : "#f44336";
|
|
119
|
-
return (
|
|
120
|
-
<span style={{ ...styles.badge, background: bg, color }}>
|
|
121
|
-
{installed ? "Detected" : "Not found"}
|
|
122
|
-
</span>
|
|
123
|
-
);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
129
|
return (
|
|
127
130
|
<div style={styles.container}>
|
|
128
131
|
<h2 style={{ fontSize: "1.3rem", marginTop: 0, marginBottom: "1rem" }}>
|
|
@@ -132,69 +135,7 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
132
135
|
<EmbedderHealthCard />
|
|
133
136
|
|
|
134
137
|
{/* Current Config Section */}
|
|
135
|
-
<
|
|
136
|
-
<h3 style={styles.sectionTitle}>Current Embedder Configuration</h3>
|
|
137
|
-
{statusError && (
|
|
138
|
-
<p style={{ color: "#f44336", fontSize: "0.85rem" }}>
|
|
139
|
-
Error: {statusError}
|
|
140
|
-
</p>
|
|
141
|
-
)}
|
|
142
|
-
{status && (
|
|
143
|
-
<>
|
|
144
|
-
<div style={styles.row}>
|
|
145
|
-
<span style={styles.label}>Active Embedder:</span>
|
|
146
|
-
<span style={styles.value}>
|
|
147
|
-
{embedderLabel(status.currentEmbedder)}
|
|
148
|
-
</span>
|
|
149
|
-
</div>
|
|
150
|
-
{"configuredEmbedder" in status && status.configuredEmbedder !== status.currentEmbedder && (
|
|
151
|
-
<div style={styles.warning}>
|
|
152
|
-
<strong>Configured but not active:</strong>{" "}
|
|
153
|
-
{embedderLabel(status.configuredEmbedder)} is configured in
|
|
154
|
-
.mega-compact.env but not yet loaded.{" "}
|
|
155
|
-
<strong>Restart pi</strong> to activate it.
|
|
156
|
-
{status.configuredUrl && (
|
|
157
|
-
<> ({status.configuredUrl})</>
|
|
158
|
-
)}
|
|
159
|
-
</div>
|
|
160
|
-
)}
|
|
161
|
-
{"restartRequired" in status && status.restartRequired && (
|
|
162
|
-
<div style={{ ...styles.row, color: "#ff9800" }}>
|
|
163
|
-
<span style={styles.label}>Status:</span>
|
|
164
|
-
<span style={styles.value}>
|
|
165
|
-
Restart required to activate the configured embedder
|
|
166
|
-
</span>
|
|
167
|
-
</div>
|
|
168
|
-
)}
|
|
169
|
-
<div style={styles.row}>
|
|
170
|
-
<span style={styles.label}>Embedding URL:</span>
|
|
171
|
-
<span style={styles.value}>
|
|
172
|
-
{status.embeddingUrl ?? (
|
|
173
|
-
<span style={{ color: "#888" }}>not set</span>
|
|
174
|
-
)}
|
|
175
|
-
</span>
|
|
176
|
-
</div>
|
|
177
|
-
<div style={styles.row}>
|
|
178
|
-
<span style={styles.label}>Embed Cache:</span>
|
|
179
|
-
<span style={styles.value}>
|
|
180
|
-
{status.embedCache ?? (
|
|
181
|
-
<span style={{ color: "#888" }}>not set</span>
|
|
182
|
-
)}
|
|
183
|
-
</span>
|
|
184
|
-
</div>
|
|
185
|
-
<div style={styles.row}>
|
|
186
|
-
<span style={styles.label}>MiniLM:</span>
|
|
187
|
-
<span style={styles.value}>{status.minilm ? "enabled" : "disabled"}</span>
|
|
188
|
-
</div>
|
|
189
|
-
{trigramWarning}
|
|
190
|
-
</>
|
|
191
|
-
)}
|
|
192
|
-
{!status && !statusError && (
|
|
193
|
-
<p style={{ color: "#888", fontSize: "0.85rem" }}>
|
|
194
|
-
Loading configuration...
|
|
195
|
-
</p>
|
|
196
|
-
)}
|
|
197
|
-
</div>
|
|
138
|
+
<CurrentConfigSection status={status} statusError={statusError} />
|
|
198
139
|
|
|
199
140
|
{/* Detection Section */}
|
|
200
141
|
<div style={styles.section}>
|
|
@@ -334,7 +275,7 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
334
275
|
{configuring === "trigram" ? "Writing..." : "Use Trigram (default)"}
|
|
335
276
|
</button>
|
|
336
277
|
</div>
|
|
337
|
-
{configResult && (
|
|
278
|
+
{configResult && configResult.embedder !== "custom" && (
|
|
338
279
|
<div style={styles.warning}>
|
|
339
280
|
{configResult.alreadyActive
|
|
340
281
|
? "Already active — no restart needed."
|
|
@@ -356,6 +297,13 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
356
297
|
setCustomUrl={setCustomUrl}
|
|
357
298
|
applyEmbedder={applyEmbedder}
|
|
358
299
|
configuring={configuring}
|
|
300
|
+
inputEnabled={status !== null && "embeddingApiKeySet" in status}
|
|
301
|
+
apiKeySet={status?.embeddingApiKeySet === true}
|
|
302
|
+
embeddingDim={status?.embeddingDim}
|
|
303
|
+
embeddingHeadersSet={status?.embeddingHeadersSet === true}
|
|
304
|
+
allowRemoteEmbedder={status?.allowRemoteEmbedder}
|
|
305
|
+
configureResult={configResult}
|
|
306
|
+
configureError={configError}
|
|
359
307
|
/>
|
|
360
308
|
|
|
361
309
|
{/* Help Section */}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SetupTab/EmbedderSetupHelpers.tsx — extracted render helpers for EmbedderSetup.
|
|
3
|
+
*
|
|
4
|
+
* Split from EmbedderSetup.tsx to respect the extensions/ 400-line soft limit
|
|
5
|
+
* (ENC-1a pushed the embedder card over its cap, so the helpers were extracted).
|
|
6
|
+
*/
|
|
7
|
+
import type React from "react";
|
|
8
|
+
import type { SetupStatusResponse } from "@contracts";
|
|
9
|
+
import { styles } from "./EmbedderSetupStyles";
|
|
10
|
+
|
|
11
|
+
/** Human label for an embedder identifier. */
|
|
12
|
+
export function embedderLabel(e: string): string {
|
|
13
|
+
switch (e) {
|
|
14
|
+
case "trigram":
|
|
15
|
+
return "TrigramEmbedder (heuristic, default)";
|
|
16
|
+
case "http":
|
|
17
|
+
return "HTTP Embedder (BYO localhost)";
|
|
18
|
+
case "minilm":
|
|
19
|
+
return "MiniLM (experimental)";
|
|
20
|
+
default:
|
|
21
|
+
return "Unknown";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Warn when the active embedder is the heuristic trigram default. */
|
|
26
|
+
export function trigramWarning(status: SetupStatusResponse | null): React.ReactElement | null {
|
|
27
|
+
if (status?.currentEmbedder !== "trigram") return null;
|
|
28
|
+
return (
|
|
29
|
+
<div style={styles.warning}>
|
|
30
|
+
<strong>Note:</strong> TrigramEmbedder is a heuristic-strength default
|
|
31
|
+
embedder. It works without any setup but recall quality may be lower
|
|
32
|
+
than a dedicated embedding backend. If you notice poor recall results,
|
|
33
|
+
consider installing Ollama and running the{" "}
|
|
34
|
+
<code>/megasetup</code> command, or set{" "}
|
|
35
|
+
<code>MEGACOMPACT_EMBEDDING_URL</code> to point at your own localhost
|
|
36
|
+
embedding server.
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Installed / not-found badge dot for a detection row. */
|
|
42
|
+
export function detectBadge(installed: boolean): React.ReactElement {
|
|
43
|
+
const bg = installed ? "#1a5a1a" : "#3a1a1a";
|
|
44
|
+
const color = installed ? "#4caf50" : "#f44336";
|
|
45
|
+
return (
|
|
46
|
+
<span style={{ ...styles.badge, background: bg, color }}>
|
|
47
|
+
{installed ? "Detected" : "Not found"}
|
|
48
|
+
</span>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The "Current Embedder Configuration" readout block. */
|
|
53
|
+
export function CurrentConfigSection({
|
|
54
|
+
status,
|
|
55
|
+
statusError,
|
|
56
|
+
}: {
|
|
57
|
+
status: SetupStatusResponse | null;
|
|
58
|
+
statusError: string | null;
|
|
59
|
+
}): React.ReactElement {
|
|
60
|
+
return (
|
|
61
|
+
<div style={styles.section}>
|
|
62
|
+
<h3 style={styles.sectionTitle}>Current Embedder Configuration</h3>
|
|
63
|
+
{statusError && (
|
|
64
|
+
<p style={{ color: "#f44336", fontSize: "0.85rem" }}>
|
|
65
|
+
Error: {statusError}
|
|
66
|
+
</p>
|
|
67
|
+
)}
|
|
68
|
+
{status && (
|
|
69
|
+
<>
|
|
70
|
+
<div style={styles.row}>
|
|
71
|
+
<span style={styles.label}>Active Embedder:</span>
|
|
72
|
+
<span style={styles.value}>
|
|
73
|
+
{embedderLabel(status.currentEmbedder)}
|
|
74
|
+
</span>
|
|
75
|
+
</div>
|
|
76
|
+
{"configuredEmbedder" in status && status.configuredEmbedder !== status.currentEmbedder && (
|
|
77
|
+
<div style={styles.warning}>
|
|
78
|
+
<strong>Configured but not active:</strong>{" "}
|
|
79
|
+
{embedderLabel(status.configuredEmbedder)} is configured in
|
|
80
|
+
.mega-compact.env but not yet loaded.{" "}
|
|
81
|
+
<strong>Restart pi</strong> to activate it.
|
|
82
|
+
{status.configuredUrl && (
|
|
83
|
+
<> ({status.configuredUrl})</>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
{"restartRequired" in status && status.restartRequired && (
|
|
88
|
+
<div style={{ ...styles.row, color: "#ff9800" }}>
|
|
89
|
+
<span style={styles.label}>Status:</span>
|
|
90
|
+
<span style={styles.value}>
|
|
91
|
+
Restart required to activate the configured embedder
|
|
92
|
+
</span>
|
|
93
|
+
</div>
|
|
94
|
+
)}
|
|
95
|
+
<div style={styles.row}>
|
|
96
|
+
<span style={styles.label}>Embedding URL:</span>
|
|
97
|
+
<span style={styles.value}>
|
|
98
|
+
{status.embeddingUrl ?? (
|
|
99
|
+
<span style={{ color: "#888" }}>not set</span>
|
|
100
|
+
)}
|
|
101
|
+
</span>
|
|
102
|
+
</div>
|
|
103
|
+
<div style={styles.row}>
|
|
104
|
+
<span style={styles.label}>Embed Cache:</span>
|
|
105
|
+
<span style={styles.value}>
|
|
106
|
+
{status.embedCache ?? (
|
|
107
|
+
<span style={{ color: "#888" }}>not set</span>
|
|
108
|
+
)}
|
|
109
|
+
</span>
|
|
110
|
+
</div>
|
|
111
|
+
<div style={styles.row}>
|
|
112
|
+
<span style={styles.label}>MiniLM:</span>
|
|
113
|
+
<span style={styles.value}>{status.minilm ? "enabled" : "disabled"}</span>
|
|
114
|
+
</div>
|
|
115
|
+
{trigramWarning(status)}
|
|
116
|
+
</>
|
|
117
|
+
)}
|
|
118
|
+
{!status && !statusError && (
|
|
119
|
+
<p style={{ color: "#888", fontSize: "0.85rem" }}>
|
|
120
|
+
Loading configuration...
|
|
121
|
+
</p>
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
@@ -27,6 +27,34 @@ export interface SetupStatusResponse {
|
|
|
27
27
|
readonly embedCache: string | null;
|
|
28
28
|
/** Whether MEGACOMPACT_MINILM is set to a truthy value. */
|
|
29
29
|
readonly minilm: boolean;
|
|
30
|
+
/** ENC-1a: the external embedder endpoint URL persisted in the per-repo
|
|
31
|
+
* `.mega-compact.env`, when one is configured (additive, flag-gated). */
|
|
32
|
+
readonly embeddingEndpointUrl?: string;
|
|
33
|
+
/** ENC-1a: whether an external embedder API key is configured. The raw key is
|
|
34
|
+
* NEVER returned — only this boolean presence marker (additive, flag-gated). */
|
|
35
|
+
readonly embeddingApiKeySet?: boolean;
|
|
36
|
+
/** ENC-1b: the persisted `MEGACOMPACT_EMBEDDING_DIM` value as its numeric
|
|
37
|
+
* string, when one is configured (additive, flag-gated). */
|
|
38
|
+
readonly embeddingDim?: string;
|
|
39
|
+
/** ENC-1b: whether `MEGACOMPACT_EMBEDDING_HEADERS` is configured. The raw
|
|
40
|
+
* headers JSON is NEVER returned — only this boolean presence marker
|
|
41
|
+
* (additive, flag-gated, redaction mirrors embeddingApiKeySet). */
|
|
42
|
+
readonly embeddingHeadersSet?: boolean;
|
|
43
|
+
/** ENC-1b: whether `MEGACOMPACT_ALLOW_REMOTE_EMBEDDER` is set (default off —
|
|
44
|
+
* a deliberate escape hatch that skips the loopback-only check; additive,
|
|
45
|
+
* flag-gated). */
|
|
46
|
+
readonly allowRemoteEmbedder?: boolean;
|
|
47
|
+
/** ENC-1b: whether `MEGACOMPACT_ENCODER_NATIVE=1` is set, i.e. the operator
|
|
48
|
+
* opted into the onnxruntime-node native backend (additive, flag-gated). */
|
|
49
|
+
readonly encoderNativeOptIn?: boolean;
|
|
50
|
+
/** ENC-1b: the current effective ONNX runtime backend, computed live through
|
|
51
|
+
* the existing `selectRuntimeBackend`. `modeB` (flag-off / no runtime) is
|
|
52
|
+
* projected to `wasm` for display (additive, flag-gated). */
|
|
53
|
+
readonly encoderBackend?: "wasm" | "native";
|
|
54
|
+
/** ENC-1b: the runtime's own demotion reason when the effective backend
|
|
55
|
+
* falls back (e.g. native selected but onnxruntime-node absent / darwin-x64
|
|
56
|
+
* demoted), surfaced verbatim; null when no demotion (additive, flag-gated). */
|
|
57
|
+
readonly encoderDemotionReason?: string | null;
|
|
30
58
|
}
|
|
31
59
|
|
|
32
60
|
/**
|
|
@@ -72,6 +100,25 @@ export interface SetupConfigureRequest {
|
|
|
72
100
|
readonly embedder: "ollama" | "llama" | "trigram" | "custom" | "onnx";
|
|
73
101
|
/** Override URL (required for "custom"; optional defaults for ollama/llama/onnx). */
|
|
74
102
|
readonly url?: string;
|
|
103
|
+
/** ENC-1a: external embedder endpoint URL, persisted to the per-repo
|
|
104
|
+
* `.mega-compact.env` (additive, flag-gated). */
|
|
105
|
+
readonly embeddingEndpointUrl?: string;
|
|
106
|
+
/** ENC-1a: external embedder API key, persisted to the per-repo
|
|
107
|
+
* `.mega-compact.env` only — never returned by any GET (additive, flag-gated). */
|
|
108
|
+
readonly embeddingApiKey?: string;
|
|
109
|
+
/** ENC-1b: persisted `MEGACOMPACT_EMBEDDING_DIM` as a positive integer string
|
|
110
|
+
* within `ENC_1B_MAX_EMBEDDING_DIM` (validated; additive, flag-gated). */
|
|
111
|
+
readonly embeddingDim?: string;
|
|
112
|
+
/** ENC-1b: persisted `MEGACOMPACT_EMBEDDING_HEADERS` JSON object string
|
|
113
|
+
* (secret-bearing — written verbatim, NEVER echoed back; validated to parse
|
|
114
|
+
* as a JSON object; additive, flag-gated). */
|
|
115
|
+
readonly embeddingHeaders?: string;
|
|
116
|
+
/** ENC-1b: opt in to `MEGACOMPACT_ALLOW_REMOTE_EMBEDDER` (default off — a
|
|
117
|
+
* deliberate escape hatch; additive, flag-gated). */
|
|
118
|
+
readonly allowRemoteEmbedder?: boolean;
|
|
119
|
+
/** ENC-1b: opt in to `MEGACOMPACT_ENCODER_NATIVE` (onnxruntime-node native
|
|
120
|
+
* backend; additive, flag-gated). */
|
|
121
|
+
readonly encoderNativeOptIn?: boolean;
|
|
75
122
|
}
|
|
76
123
|
|
|
77
124
|
/** Response for POST /api/setup-configure. */
|
|
@@ -294,5 +294,17 @@ export const VECTOR_CORTEX_SETTINGS: SettingGroup = {
|
|
|
294
294
|
"ENC-0g makes the Setup Cortex status route honest: reads the ENC-0f QualificationV1 record (when ENC_0F is ON and a record exists) and lets its verdict override the structural verify for the qualification field; computes the blocker list from (platform, record, manifest head-count) with corrected HG statuses/wording; re-derives VC9B action gating from live blockers. OFF = verdict from verifyEncoderAsset alone, static SETUP_CORTEX_BLOCKERS, static action gating (byte-identical ENC-0f predecessor).",
|
|
295
295
|
true,
|
|
296
296
|
),
|
|
297
|
+
boolDirect(
|
|
298
|
+
"MEGACOMPACT_ENC_1A",
|
|
299
|
+
"ENC-1a external embedder API key + endpoint Settings fields",
|
|
300
|
+
"ENC-1a adds a Settings-visible field pair for the external embedder endpoint URL + optional Bearer API key, persisted by the setup-configure writer branch to the per-repo .mega-compact.env (MEGACOMPACT_EMBEDDING_URL / MEGACOMPACT_EMBEDDING_KEY). The GET status route echoes the endpoint URL and reports embeddingApiKeySet as a boolean ONLY — the raw key is never returned. OFF = no new GET fields, no writer branch, no new Settings text rows (byte-identical ENC-0g predecessor).",
|
|
301
|
+
true,
|
|
302
|
+
),
|
|
303
|
+
boolDirect(
|
|
304
|
+
"MEGACOMPACT_ENC_1B",
|
|
305
|
+
"ENC-1b ONNX runtime backend + embedder API settings",
|
|
306
|
+
"ENC-1b completes the embedder API Settings surface (dim / headers / allow-remote persisted to the per-repo .mega-compact.env) and surfaces the ONNX runtime selection knob (MEGACOMPACT_ENCODER_NATIVE) as a toggle plus the current effective backend + demotion reason. OFF = no new GET fields, no writer branch, no new Settings rows or toggle (byte-identical ENC-1a predecessor).",
|
|
307
|
+
true,
|
|
308
|
+
),
|
|
297
309
|
],
|
|
298
310
|
};
|