pi-mega-compact 0.20.3 → 0.20.5
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.js +12 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-helpers.js +1 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex-render.js +40 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex.js +1 -0
- package/dist/extensions/dashboard-server/routes.js +1 -1
- package/dist/extensions/dashboard-server/server.js +29 -22
- package/dist/extensions/mega-context/vector-cortex.js +128 -0
- package/dist/src/config/vector-cortex.js +12 -0
- package/dist/src/config.js +1 -1
- package/dist/src/store/sqlite/global-sessions.js +16 -4
- package/dist/src/vector-cortex/provider/registry.js +112 -0
- package/dist/src/vector-cortex/provider/types.js +30 -0
- package/dist/src/vector-cortex/render/_acceptance-fixture.js +58 -0
- package/dist/src/vector-cortex/render/_acceptance-helpers.js +17 -0
- package/dist/src/vector-cortex/render/_acceptance-provider.js +29 -0
- package/dist/src/vector-cortex/render/_acceptance-scenario.js +259 -0
- package/dist/src/vector-cortex/render/renderer.js +119 -0
- package/dist/src/vector-cortex/render/types.js +29 -0
- package/dist/src/vector-cortex/render/validator.js +90 -0
- package/dist/vector-cortex/provider/registry.js +112 -0
- package/dist/vector-cortex/provider/types.js +30 -0
- package/dist/vector-cortex/render/_acceptance-fixture.js +58 -0
- package/dist/vector-cortex/render/_acceptance-helpers.js +17 -0
- package/dist/vector-cortex/render/_acceptance-provider.js +29 -0
- package/dist/vector-cortex/render/_acceptance-scenario.js +259 -0
- package/dist/vector-cortex/render/renderer.js +119 -0
- package/dist/vector-cortex/render/types.js +29 -0
- package/dist/vector-cortex/render/validator.js +90 -0
- package/extensions/dashboard-client/dist/assets/{AreaChart-Cam9-nhT.js → AreaChart-CGL29Tcl.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-Cam9-nhT.js.map → AreaChart-CGL29Tcl.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-DzIY8aM1.js → BarChart-OxhalIZa.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-DzIY8aM1.js.map → BarChart-OxhalIZa.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-CKIiYsG_.js → CacheTab-VcMFwL-6.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-CKIiYsG_.js.map → CacheTab-VcMFwL-6.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-xaaBJLiK.js → EventsTab-DePofXDM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-xaaBJLiK.js.map → EventsTab-DePofXDM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-BGtUKOqG.js → HealthTab-nQd1tjSF.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-BGtUKOqG.js.map → HealthTab-nQd1tjSF.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-ABgQnTZ9.js → MaintenanceTab-CzvA8-F6.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-ABgQnTZ9.js.map → MaintenanceTab-CzvA8-F6.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-ChR2GAN-.js → MemoryMapTab-3lxgWBvU.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-ChR2GAN-.js.map → MemoryMapTab-3lxgWBvU.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DdCLAgcR.js → MetricsTab-D_FcA6kN.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DdCLAgcR.js.map → MetricsTab-D_FcA6kN.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-DtemzJt6.js → OverviewTab-BU6R4aEs.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-DtemzJt6.js.map → OverviewTab-BU6R4aEs.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-B9mvD9Ep.js → ReposTab-DFjy1isz.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-B9mvD9Ep.js.map → ReposTab-DFjy1isz.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-BcO38XLS.js → SessionsTab-UGIzIH25.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-BcO38XLS.js.map → SessionsTab-UGIzIH25.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-D_TBNP09.js → SetupTab-CECrgMKI.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SetupTab-D_TBNP09.js.map → SetupTab-CECrgMKI.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-TjHpbUOo.js → TimeSavedCard-Dyy4SCDk.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-TjHpbUOo.js.map → TimeSavedCard-Dyy4SCDk.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DprxndCF.js → TurnsTab-B0LPcVs1.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DprxndCF.js.map → TurnsTab-B0LPcVs1.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-BWi3u_gp.js +2 -0
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-BWi3u_gp.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{WikiTab-OKgSo15G.js → WikiTab-DWk9Qvut.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-OKgSo15G.js.map → WikiTab-DWk9Qvut.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-D_Qz4q7L.js → button-O59wPr5H.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-D_Qz4q7L.js.map → button-O59wPr5H.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-CsI6Jm3p.js → card-C-DxXv1-.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-CsI6Jm3p.js.map → card-C-DxXv1-.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CvHKUdhX.js → generateCategoricalChart-Dw5YnE5s.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CvHKUdhX.js.map → generateCategoricalChart-Dw5YnE5s.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-0Ye_un22.js → index-i9oaPE0a.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-0Ye_un22.js.map → index-i9oaPE0a.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-VQEoJl8Q.js → switch-B69QY3IM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-VQEoJl8Q.js.map → switch-B69QY3IM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-CAPm4HJo.js → toggle-BJ4Kwggu.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-CAPm4HJo.js.map → toggle-BJ4Kwggu.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-pxsNTVkh.js → useSSE-BpuA8sPd.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-pxsNTVkh.js.map → useSSE-BpuA8sPd.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/api/vector-cortex.ts +9 -0
- package/extensions/dashboard-client/src/tabs/VectorCortexMetric.tsx +10 -0
- package/extensions/dashboard-client/src/tabs/VectorCortexPlansCard.tsx +39 -0
- package/extensions/dashboard-client/src/tabs/VectorCortexRenderCard.tsx +38 -0
- package/extensions/dashboard-client/src/tabs/VectorCortexTab.tsx +11 -38
- package/extensions/dashboard-client/src/types/vector-cortex.ts +9 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex.ts +20 -0
- package/extensions/dashboard-server/routes-rag-settings-helpers.ts +6 -0
- package/extensions/dashboard-server/routes-vector-cortex-render.ts +49 -0
- package/extensions/dashboard-server/routes-vector-cortex.ts +1 -0
- package/extensions/dashboard-server/routes.ts +1 -0
- package/extensions/dashboard-server/server.ts +31 -22
- package/extensions/mega-context/vector-cortex.ts +163 -0
- package/package.json +1 -1
- package/src/config/vector-cortex.ts +13 -0
- package/src/config.ts +1 -0
- package/src/store/sqlite/global-sessions.ts +14 -2
- package/src/vector-cortex/provider/registry.ts +137 -0
- package/src/vector-cortex/provider/types.ts +163 -0
- package/src/vector-cortex/render/_acceptance-fixture.ts +128 -0
- package/src/vector-cortex/render/_acceptance-helpers.ts +39 -0
- package/src/vector-cortex/render/_acceptance-provider.ts +45 -0
- package/src/vector-cortex/render/_acceptance-scenario.ts +319 -0
- package/src/vector-cortex/render/renderer.ts +142 -0
- package/src/vector-cortex/render/types.ts +174 -0
- package/src/vector-cortex/render/validator.ts +120 -0
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-Bym21yVQ.js +0 -2
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-Bym21yVQ.js.map +0 -1
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
fetchVectorCortexQuery,
|
|
16
16
|
fetchVectorCortexReconstruct,
|
|
17
17
|
fetchVectorCortexPlans,
|
|
18
|
+
fetchVectorCortexRender,
|
|
18
19
|
fetchVectorCortexShards,
|
|
19
20
|
fetchVectorCortexTopology,
|
|
20
21
|
resetVectorCortexBreaker,
|
|
@@ -24,11 +25,15 @@ import {
|
|
|
24
25
|
type VectorCortexQueryView,
|
|
25
26
|
type VectorCortexReconstructView,
|
|
26
27
|
type VectorCortexPlansView,
|
|
28
|
+
type VectorCortexRenderView,
|
|
27
29
|
type VectorCortexShardsView,
|
|
28
30
|
type VectorCortexTopologyView,
|
|
29
31
|
} from "../api/vector-cortex";
|
|
30
32
|
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
|
|
31
33
|
import { Badge } from "../components/ui/badge";
|
|
34
|
+
import { Metric } from "./VectorCortexMetric";
|
|
35
|
+
import { VectorCortexRenderCard } from "./VectorCortexRenderCard";
|
|
36
|
+
import { VectorCortexPlansCard } from "./VectorCortexPlansCard";
|
|
32
37
|
|
|
33
38
|
function ModeChip({ mode, count }: { mode: string; count: number }): React.ReactElement {
|
|
34
39
|
return (
|
|
@@ -39,15 +44,6 @@ function ModeChip({ mode, count }: { mode: string; count: number }): React.React
|
|
|
39
44
|
);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
function Metric({ label, value }: { label: string; value: string }): React.ReactElement {
|
|
43
|
-
return (
|
|
44
|
-
<div>
|
|
45
|
-
<div className="text-xs text-muted-foreground">{label}</div>
|
|
46
|
-
<div className="font-mono text-sm">{value}</div>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
47
|
export default function VectorCortexTab(): React.ReactElement {
|
|
52
48
|
const [data, setData] = useState<VectorCortexEvaluationSummary | null>(null);
|
|
53
49
|
const [err, setError] = useState<string | null>(null);
|
|
@@ -60,6 +56,7 @@ export default function VectorCortexTab(): React.ReactElement {
|
|
|
60
56
|
const [shards, setShards] = useState<VectorCortexShardsView | null>(null);
|
|
61
57
|
const [reconstruct, setReconstruct] = useState<VectorCortexReconstructView | null>(null);
|
|
62
58
|
const [plans, setPlans] = useState<VectorCortexPlansView | null>(null);
|
|
59
|
+
const [render, setRender] = useState<VectorCortexRenderView | null>(null);
|
|
63
60
|
|
|
64
61
|
const poll = useCallback(() => {
|
|
65
62
|
fetchVectorCortexEvaluation()
|
|
@@ -89,6 +86,9 @@ export default function VectorCortexTab(): React.ReactElement {
|
|
|
89
86
|
fetchVectorCortexPlans().then(setPlans).catch(() => {
|
|
90
87
|
/* plan manifest card is best-effort (VC5A) */
|
|
91
88
|
});
|
|
89
|
+
fetchVectorCortexRender().then(setRender).catch(() => {
|
|
90
|
+
/* render conformance card is best-effort (VC5B) */
|
|
91
|
+
});
|
|
92
92
|
}, []);
|
|
93
93
|
|
|
94
94
|
useEffect(() => {
|
|
@@ -403,35 +403,8 @@ export default function VectorCortexTab(): React.ReactElement {
|
|
|
403
403
|
)}
|
|
404
404
|
</CardContent>
|
|
405
405
|
</Card>
|
|
406
|
-
<
|
|
407
|
-
|
|
408
|
-
<div className="flex items-center justify-between">
|
|
409
|
-
<CardTitle>Plan Manifests (VC5A)</CardTitle>
|
|
410
|
-
{plans?.enabled ? (
|
|
411
|
-
<Badge variant="success">ACTIVE</Badge>
|
|
412
|
-
) : (
|
|
413
|
-
<Badge variant="danger">OFF</Badge>
|
|
414
|
-
)}
|
|
415
|
-
</div>
|
|
416
|
-
</CardHeader>
|
|
417
|
-
<CardContent>
|
|
418
|
-
{!plans?.enabled ? (
|
|
419
|
-
<div className="vc-empty">PromptDagV1 + budgeted planner disabled (VC5A off).</div>
|
|
420
|
-
) : (
|
|
421
|
-
<>
|
|
422
|
-
<div className="grid grid-cols-2 gap-4 md:grid-cols-4">
|
|
423
|
-
<Metric label="DAG fixtures" value={String(plans.dagCount)} />
|
|
424
|
-
<Metric label="Plan fixtures" value={String(plans.plannerCount)} />
|
|
425
|
-
<Metric label="Plans exposed" value={String(plans.plans.length)} />
|
|
426
|
-
</div>
|
|
427
|
-
<div className="mt-3 text-xs text-muted-foreground">
|
|
428
|
-
Reader-only plan manifests only — no session payloads or prompt text.
|
|
429
|
-
Per-run plan outputs are staged in-memory this sprint.
|
|
430
|
-
</div>
|
|
431
|
-
</>
|
|
432
|
-
)}
|
|
433
|
-
</CardContent>
|
|
434
|
-
</Card>
|
|
406
|
+
<VectorCortexPlansCard view={plans} />
|
|
407
|
+
<VectorCortexRenderCard view={render} />
|
|
435
408
|
<Card>
|
|
436
409
|
<CardHeader>
|
|
437
410
|
<div className="flex items-center justify-between">
|
|
@@ -182,3 +182,12 @@ export interface VectorCortexPlansView {
|
|
|
182
182
|
plans: VectorCortexPlanManifest[];
|
|
183
183
|
updatedAt: string;
|
|
184
184
|
}
|
|
185
|
+
|
|
186
|
+
/** Reader-only render + provider-profile view (VC5B). */
|
|
187
|
+
export interface VectorCortexRenderView {
|
|
188
|
+
enabled: boolean;
|
|
189
|
+
renderCount: number;
|
|
190
|
+
providerCount: number;
|
|
191
|
+
knownProfiles: string[];
|
|
192
|
+
updatedAt: string;
|
|
193
|
+
}
|
|
@@ -296,6 +296,26 @@ export interface VectorCortexPlansView {
|
|
|
296
296
|
readonly updatedAt: string;
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Reader-only render/profile view for GET /api/vector-cortex/render (VC5B).
|
|
301
|
+
* Reports the registered render (REN-001..) and provider-profile (PRO-001..)
|
|
302
|
+
* identifier counts + the known provider-profile keys. NEVER exposes rendered
|
|
303
|
+
* node bytes, prompt text, or the canonical outbound request (reader-only,
|
|
304
|
+
* SECURITY_PRIVACY: the exact ledger is not training data).
|
|
305
|
+
*/
|
|
306
|
+
export interface VectorCortexRenderView {
|
|
307
|
+
/** Whether the VC5B render + provider-profile flag is enabled. */
|
|
308
|
+
readonly enabled: boolean;
|
|
309
|
+
/** Count of registered render fixtures (REN-001..). */
|
|
310
|
+
readonly renderCount: number;
|
|
311
|
+
/** Count of registered provider-profile fixtures (PRO-001..). */
|
|
312
|
+
readonly providerCount: number;
|
|
313
|
+
/** Known base provider-profile keys (provider//model), reader-only. */
|
|
314
|
+
readonly knownProfiles: readonly string[];
|
|
315
|
+
/** ISO timestamp of the snapshot. */
|
|
316
|
+
readonly updatedAt: string;
|
|
317
|
+
}
|
|
318
|
+
|
|
299
319
|
/**
|
|
300
320
|
* Reader-only occurrence-ledger view for GET /api/vector-cortex/ledger (VC1B).
|
|
301
321
|
* Built on the LedgerReader capability surface. Exposes occurrence IDENTITY
|
|
@@ -373,6 +373,12 @@ export const SETTINGS: ReadonlyArray<{
|
|
|
373
373
|
"Single-session DAG (PromptDagV1) + budgeted 0/1 portfolio planner: builds a stable Kahn-ordered DAG, computes the mandatory dependency/tool/anchor closure before optional selection, returns MANDATORY_CLOSURE_OVER_BUDGET with evidence preserved on overflow, and runs a utility-per-token portfolio that never exceeds the remaining budget. Framing is owned here, not in VC4C. OFF = byte-identical predecessor (VC4C).",
|
|
374
374
|
true,
|
|
375
375
|
),
|
|
376
|
+
boolDirect(
|
|
377
|
+
"MEGACOMPACT_VC5B",
|
|
378
|
+
"VC5B Validated Renderer + Provider Profiles",
|
|
379
|
+
"Validated prompt renderer: replays VC5A's stable Kahn order verbatim, preserves exact tool bytes (PREVENT-PI-002), places compacted context via the host before_agent_start prepend seam — never role:system (PREVENT-PI-003) — and SHA-256 hashes the entire canonical outbound request before provider invocation. Unknown provider/model cleanly bypasses to the predecessor prompt path. OFF = byte-identical predecessor (VC5A).",
|
|
380
|
+
true,
|
|
381
|
+
),
|
|
376
382
|
],
|
|
377
383
|
},
|
|
378
384
|
{
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/routes-vector-cortex-render.ts — VC5B render + provider-profile
|
|
3
|
+
* dashboard route.
|
|
4
|
+
*
|
|
5
|
+
* Reader-only GET /api/vector-cortex/render returning the registered render
|
|
6
|
+
* (REN-001..020) and provider-profile (PRO-001..015) identifier counts plus the
|
|
7
|
+
* known base provider-profile keys. NEVER exposes rendered node bytes, prompt
|
|
8
|
+
* text, or the canonical outbound request (reader-only, SECURITY_PRIVACY).
|
|
9
|
+
* Flag-gated on MEGACOMPACT_VC5B: `enabled:false` when off (byte-identical to
|
|
10
|
+
* the pre-VC5B predecessor).
|
|
11
|
+
*
|
|
12
|
+
* Guardrails: PREVENT-PI-004 (local in-process state only), PREVENT-011 (no
|
|
13
|
+
* `any`), reader-only aggregate (counts + profile keys only).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
17
|
+
import type { RouteContext } from "./routes-core.js";
|
|
18
|
+
import { VC5B_ENABLED } from "../../src/config.js";
|
|
19
|
+
import { REN_IDS } from "../../src/vector-cortex/render/types.js";
|
|
20
|
+
import { PRO_IDS } from "../../src/vector-cortex/provider/types.js";
|
|
21
|
+
import { KNOWN_PROVIDER_KEYS } from "../../src/vector-cortex/provider/registry.js";
|
|
22
|
+
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
23
|
+
import type { VectorCortexRenderView } from "./api-contracts/vector-cortex.js";
|
|
24
|
+
|
|
25
|
+
/** Reader-only GET /api/vector-cortex/render (VC5B). */
|
|
26
|
+
export function handleVectorCortexRender(
|
|
27
|
+
req: IncomingMessage,
|
|
28
|
+
res: ServerResponse,
|
|
29
|
+
_ctx: RouteContext,
|
|
30
|
+
): boolean {
|
|
31
|
+
const url = req.url ?? "";
|
|
32
|
+
const path = url.split("?")[0] ?? url;
|
|
33
|
+
if (path !== "/api/vector-cortex/render") return false;
|
|
34
|
+
if (req.method !== "GET") {
|
|
35
|
+
sendJson(res, 405, { error: "method_not_allowed" });
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const enabled = VC5B_ENABLED();
|
|
40
|
+
const body: VectorCortexRenderView = {
|
|
41
|
+
enabled,
|
|
42
|
+
renderCount: enabled ? REN_IDS.length : 0,
|
|
43
|
+
providerCount: enabled ? PRO_IDS.length : 0,
|
|
44
|
+
knownProfiles: enabled ? KNOWN_PROVIDER_KEYS : [],
|
|
45
|
+
updatedAt: new Date().toISOString(),
|
|
46
|
+
};
|
|
47
|
+
sendJson(res, 200, body);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
@@ -23,3 +23,4 @@ export { handleVectorCortexShards } from "./routes-vector-cortex-shards.js";
|
|
|
23
23
|
export { handleVectorCortexResidual } from "./routes-vector-cortex-residual.js";
|
|
24
24
|
export { handleVectorCortexReconstruct } from "./routes-vector-cortex-reconstruct.js";
|
|
25
25
|
export { handleVectorCortexPlans } from "./routes-vector-cortex-plans.js";
|
|
26
|
+
export { handleVectorCortexRender } from "./routes-vector-cortex-render.js";
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
handleVectorCortexResidual,
|
|
68
68
|
handleVectorCortexReconstruct,
|
|
69
69
|
handleVectorCortexPlans,
|
|
70
|
+
handleVectorCortexRender,
|
|
70
71
|
handleStatic,
|
|
71
72
|
} from "./routes.js";
|
|
72
73
|
|
|
@@ -236,15 +237,16 @@ export async function launchDashboardServer(
|
|
|
236
237
|
detectCrossRepoDrift,
|
|
237
238
|
});
|
|
238
239
|
|
|
239
|
-
// Bind host resolution:
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
240
|
+
// Bind host resolution. Default: ALL interfaces (0.0.0.0) so the dashboard
|
|
241
|
+
// is reachable on loopback (localhost — the launcher's health check + the
|
|
242
|
+
// local browser), the tailnet (Tailscale), and any LAN interface. The
|
|
243
|
+
// network-denial gate was removed (the user opted into open access);
|
|
244
|
+
// MEGACOMPACT_DASHBOARD_HOST overrides for anyone who wants to restrict to
|
|
245
|
+
// a single interface. The tailnet IP is still detected so we can surface it
|
|
246
|
+
// as the remote access address. 0.0.0.0 opts into permissive CORS below.
|
|
247
|
+
const host = process.env.MEGACOMPACT_DASHBOARD_HOST ?? "0.0.0.0";
|
|
247
248
|
const allInterfaces = host === "0.0.0.0";
|
|
249
|
+
const tailscaleIP = allInterfaces ? detectTailscaleIP() : null;
|
|
248
250
|
|
|
249
251
|
// guardrails-allow PREVENT-PI-004: optional, user-triggered /dashboard server (tailnet-local via Tailscale mesh or loopback); no remote outbound calls.
|
|
250
252
|
const server = createServer((req: IncomingMessage, res: ServerResponse) => {
|
|
@@ -312,6 +314,7 @@ export async function launchDashboardServer(
|
|
|
312
314
|
if (handleVectorCortexResidual(req, res, ctx)) return;
|
|
313
315
|
if (handleVectorCortexReconstruct(req, res, ctx)) return;
|
|
314
316
|
if (handleVectorCortexPlans(req, res, ctx)) return;
|
|
317
|
+
if (handleVectorCortexRender(req, res, ctx)) return;
|
|
315
318
|
handleStatic(req, res, ctx);
|
|
316
319
|
});
|
|
317
320
|
|
|
@@ -336,27 +339,33 @@ export async function launchDashboardServer(
|
|
|
336
339
|
});
|
|
337
340
|
|
|
338
341
|
server.listen(port, host, () => {
|
|
339
|
-
//
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
+
// Surface localhost for local reach (the launcher health-checks
|
|
343
|
+
// localhost + the local browser uses it), and — when bound to all
|
|
344
|
+
// interfaces with a tailnet present — also surface the tailnet
|
|
345
|
+
// address for remote devices on the mesh.
|
|
346
|
+
const localUrl = `http://localhost:${port}`; // guardrails-allow PREVENT-PI-004: dashboard URL (loopback/all-interfaces, user-opted open access)
|
|
347
|
+
const tailnetUrl =
|
|
348
|
+
allInterfaces && tailscaleIP ? `http://${tailscaleIP}:${port}` : null; // guardrails-allow PREVENT-PI-004: dashboard URL (tailnet, user-opted open access)
|
|
342
349
|
const url =
|
|
343
350
|
host === "127.0.0.1"
|
|
344
|
-
?
|
|
345
|
-
: `http://${host}:${port}`;
|
|
346
|
-
log("server running", { url, host });
|
|
351
|
+
? localUrl
|
|
352
|
+
: tailnetUrl ?? `http://${host}:${port}`;
|
|
353
|
+
log("server running", { url, host, tailnetUrl });
|
|
347
354
|
// eslint-disable-next-line no-console
|
|
348
|
-
console.log(
|
|
355
|
+
console.log(
|
|
356
|
+
`[mega-compact] dashboard server running: ${url}` +
|
|
357
|
+
(tailnetUrl ? ` (also ${localUrl})` : ""),
|
|
358
|
+
);
|
|
349
359
|
|
|
350
|
-
// v0.8.2: also bind the IPv6 loopback (::1) when
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
//
|
|
355
|
-
// bind ::1 — the tailnet address is what the user reaches. Non-fatal:
|
|
360
|
+
// v0.8.2: also bind the IPv6 loopback (::1) when localhost must work.
|
|
361
|
+
// On many systems `localhost` resolves to ::1 first (see /etc/hosts),
|
|
362
|
+
// so an IPv4-only bind makes the browser hit ::1:port and get refused.
|
|
363
|
+
// Bind ::1 for the explicit loopback bind AND the all-interfaces bind
|
|
364
|
+
// (a browser resolving localhost → ::1 must still connect). Non-fatal:
|
|
356
365
|
// IPv4-only hosts or a ::1 already in use just skip the mirror.
|
|
357
366
|
let v6: ReturnType<typeof createServer> | undefined;
|
|
358
367
|
const v4Handler = server.listeners("request")[0];
|
|
359
|
-
if (host === "127.0.0.1" && v4Handler) {
|
|
368
|
+
if ((host === "127.0.0.1" || allInterfaces) && v4Handler) {
|
|
360
369
|
v6 = createServer((r, s) =>
|
|
361
370
|
(v4Handler as (a: IncomingMessage, b: ServerResponse) => void).call(
|
|
362
371
|
server,
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mega-context/vector-cortex.ts — VC5B delegation seam (the sprint's production
|
|
3
|
+
* ownership: `extensions/mega-context/vector-cortex.ts`).
|
|
4
|
+
*
|
|
5
|
+
* This is the ONLY extension-side surface VC5B owns. It delegates to the pi-
|
|
6
|
+
* agnostic `src/vector-cortex/render` + `src/vector-cortex/provider` logic and
|
|
7
|
+
* wires the two structured events the sprint emits:
|
|
8
|
+
* - `vector_cortex_render_validated` — a render passed validation and will be
|
|
9
|
+
* prepended via the host `before_agent_start` systemPrompt seam.
|
|
10
|
+
* - `vector_cortex_provider_bypassed` — an unknown provider/profile forced a
|
|
11
|
+
* clean bypass (triad C, the predecessor prompt path).
|
|
12
|
+
*
|
|
13
|
+
* GUARDRAIL PREVENT-PI-003 (critical): the rendered compacted context is placed
|
|
14
|
+
* via the host `before_agent_start` systemPrompt PREPEND seam — it is NEVER
|
|
15
|
+
* emitted as a `role:"system"` conversation message. The renderer returns a
|
|
16
|
+
* `RenderManifestV1`, not a raw system-role payload; this seam composes the
|
|
17
|
+
* manifest's prepend into `event.systemPrompt`.
|
|
18
|
+
*
|
|
19
|
+
* The context handler (extensions/mega-events/context-handler.ts) is 228 lines
|
|
20
|
+
* (already a delegate shell) and under the extension hard limit, so NO split was
|
|
21
|
+
* required — VC5B delegates from here rather than modifying that handler.
|
|
22
|
+
*
|
|
23
|
+
* Pi runtime adapter: imports only pi runtime types + the VC5B logic. Flag-gated
|
|
24
|
+
* on `VC5B_ENABLED()`; flag OFF is byte-identical to the predecessor (VC5A state
|
|
25
|
+
* — the DAG/plan path), so this seam returns the host's unmodified systemPrompt.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { ExtensionAPI, ExtensionContext, BeforeAgentStartEvent } from "@earendil-works/pi-coding-agent";
|
|
29
|
+
|
|
30
|
+
import { VC5B_ENABLED } from "../../src/config/vector-cortex.js";
|
|
31
|
+
import { resolveProviderProfile } from "../../src/vector-cortex/provider/registry.js";
|
|
32
|
+
import { renderPrompt } from "../../src/vector-cortex/render/renderer.js";
|
|
33
|
+
import { validateRender } from "../../src/vector-cortex/render/validator.js";
|
|
34
|
+
import type { RenderInput, RenderManifestV1, CanonicalOutboundRequest } from "../../src/vector-cortex/render/types.js";
|
|
35
|
+
import type { ProviderProfileBundle } from "../../src/vector-cortex/provider/types.js";
|
|
36
|
+
|
|
37
|
+
/** An injected emit callback — the same (event, fields) shape as the src seams. */
|
|
38
|
+
export type VectorCortexEmit = (event: string, fields: Record<string, unknown>) => void;
|
|
39
|
+
|
|
40
|
+
/** The VC5B seam result handed back to the before_agent_start handler. */
|
|
41
|
+
export interface VectorCortexRenderOutcome {
|
|
42
|
+
readonly validated: boolean;
|
|
43
|
+
readonly bypassed: boolean;
|
|
44
|
+
readonly manifest: RenderManifestV1 | null;
|
|
45
|
+
/** The text to prepend to the host systemPrompt (empty when not VC5B). */
|
|
46
|
+
readonly systemPromptPrepend: string;
|
|
47
|
+
readonly triad: "A" | "B" | "C";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Run the full VC5B render+validate pipeline. Returns a structured outcome the
|
|
52
|
+
* `before_agent_start` handler composes into the host systemPrompt. On a clean
|
|
53
|
+
* bypass (unknown profile) it emits `vector_cortex_provider_bypassed` and the
|
|
54
|
+
* host uses the predecessor prompt path (triad C). On a validated render it
|
|
55
|
+
* emits `vector_cortex_render_validated` (triad A).
|
|
56
|
+
*
|
|
57
|
+
* All emits are best-effort and non-fatal; the flag gates zero observability
|
|
58
|
+
* writes when OFF (byte-identical to predecessor).
|
|
59
|
+
*/
|
|
60
|
+
export function runVectorCortexRender(
|
|
61
|
+
input: RenderInput,
|
|
62
|
+
emit?: VectorCortexEmit,
|
|
63
|
+
): VectorCortexRenderOutcome {
|
|
64
|
+
const fire = (event: string, fields: Record<string, unknown>): void => {
|
|
65
|
+
try {
|
|
66
|
+
if (VC5B_ENABLED()) emit?.(event, fields);
|
|
67
|
+
} catch {
|
|
68
|
+
/* non-fatal observability — never break the agent loop */
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const rendered = renderPrompt(input);
|
|
73
|
+
if (!rendered.ok) {
|
|
74
|
+
// Clean bypass (unknown profile) or a hard order mismatch. Bypass emits the
|
|
75
|
+
// provider-bypassed event and defers to the predecessor prompt path.
|
|
76
|
+
fire("vector_cortex_provider_bypassed", {
|
|
77
|
+
code: rendered.code,
|
|
78
|
+
triad: rendered.triad,
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
validated: false,
|
|
82
|
+
bypassed: true,
|
|
83
|
+
manifest: null,
|
|
84
|
+
systemPromptPrepend: "",
|
|
85
|
+
triad: rendered.triad,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Validate the canonical request BEFORE invocation. The profile at validation
|
|
90
|
+
// time must match the manifest profile (the UNIQUE injection swaps it → C).
|
|
91
|
+
const sourceToolBytes = new Map<string, string>();
|
|
92
|
+
for (const t of rendered.request.tools) sourceToolBytes.set(t.id, t.bytes);
|
|
93
|
+
const pinnedToolLengths = new Map<string, number>();
|
|
94
|
+
for (const t of rendered.request.tools) {
|
|
95
|
+
pinnedToolLengths.set(t.id, Buffer.byteLength(t.bytes, "utf8"));
|
|
96
|
+
}
|
|
97
|
+
const check = validateRender(
|
|
98
|
+
rendered.manifest,
|
|
99
|
+
rendered.request,
|
|
100
|
+
input.profile,
|
|
101
|
+
sourceToolBytes,
|
|
102
|
+
pinnedToolLengths,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
if (!check.ok) {
|
|
106
|
+
fire("vector_cortex_provider_bypassed", {
|
|
107
|
+
code: check.code,
|
|
108
|
+
triad: check.triad,
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
validated: false,
|
|
112
|
+
bypassed: true,
|
|
113
|
+
manifest: rendered.manifest,
|
|
114
|
+
systemPromptPrepend: "",
|
|
115
|
+
triad: check.triad,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fire("vector_cortex_render_validated", {
|
|
120
|
+
profileId: rendered.manifest.profileId,
|
|
121
|
+
requestDigest: rendered.manifest.requestDigest,
|
|
122
|
+
nodeCount: rendered.manifest.nodeOrder.length,
|
|
123
|
+
triad: "A",
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
validated: true,
|
|
127
|
+
bypassed: false,
|
|
128
|
+
manifest: rendered.manifest,
|
|
129
|
+
systemPromptPrepend: rendered.request.systemPromptPrepend,
|
|
130
|
+
triad: "A",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Register the VC5B `before_agent_start` prepend seam on the host. Flag OFF →
|
|
136
|
+
* byte-identical to the predecessor (returns the host's unmodified systemPrompt).
|
|
137
|
+
* The composed prepend is placed on the HOST systemPrompt, never as role:system.
|
|
138
|
+
*/
|
|
139
|
+
export function registerVectorCortexRender(
|
|
140
|
+
pi: ExtensionAPI,
|
|
141
|
+
_ctx: ExtensionContext,
|
|
142
|
+
emit?: VectorCortexEmit,
|
|
143
|
+
): void {
|
|
144
|
+
pi.on("before_agent_start", (event: BeforeAgentStartEvent, ctx: ExtensionContext) => {
|
|
145
|
+
if (!VC5B_ENABLED()) return; // byte-identical predecessor behavior
|
|
146
|
+
// The host supplies the active (provider, model) so the seam can resolve the
|
|
147
|
+
// profile. Until the host passes a render input, the seam stays inert.
|
|
148
|
+
const pending = (ctx as unknown as { megaCompactVectorCortexRender?: RenderInput }).megaCompactVectorCortexRender;
|
|
149
|
+
if (pending === undefined) return;
|
|
150
|
+
const outcome = runVectorCortexRender(pending, emit);
|
|
151
|
+
if (!outcome.validated) return; // bypass / mismatch → predecessor path
|
|
152
|
+
return { systemPrompt: `${event.systemPrompt}\n\n${outcome.systemPromptPrepend}` };
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Resolve a provider profile by (provider, model) for the host to pass in. */
|
|
157
|
+
export function resolveProfile(provider: string, model: string): ProviderProfileBundle | null {
|
|
158
|
+
const res = resolveProviderProfile(provider, model);
|
|
159
|
+
return res.ok ? res.bundle : null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Re-export the core types the host adapter consumes (contract-first). */
|
|
163
|
+
export type { RenderInput, RenderManifestV1, CanonicalOutboundRequest };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.5",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -188,6 +188,19 @@ export const VC4C_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC4C");
|
|
|
188
188
|
*/
|
|
189
189
|
export const VC5A_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC5A");
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* VC5B — validated prompt renderer + provider profiles. Default ON.
|
|
193
|
+
* `MEGACOMPACT_VC5B=0` disables and is byte-identical to the predecessor
|
|
194
|
+
* (VC5A): no render manifest is produced, no canonical request is hashed, the
|
|
195
|
+
* `vector_cortex_render_validated` / `vector_cortex_provider_bypassed` events are
|
|
196
|
+
* never emitted, and the prompt continues to be built by the predecessor VC5A
|
|
197
|
+
* DAG/plan path (its goldens are unchanged). The render/validate functions are
|
|
198
|
+
* PURE — flag OFF gates the reporter + dashboard seam, never the arithmetic.
|
|
199
|
+
* This flag MUST also be a dashboard SETTINGS toggle (visible in config UI, never
|
|
200
|
+
* in EXCLUDED_SETTINGS), mirroring VC4A/VC4B/VC4C/VC5A.
|
|
201
|
+
*/
|
|
202
|
+
export const VC5B_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC5B");
|
|
203
|
+
|
|
191
204
|
// ---------------------------------------------------------------------------
|
|
192
205
|
// Breaker state machine constants (TRIAD_RESILIENCE.md §breaker).
|
|
193
206
|
// Rolled numbers for one 60s window; VC0C consumes these at its breaker seam.
|
package/src/config.ts
CHANGED
|
@@ -82,9 +82,15 @@ export function recordSessionHeartbeat(
|
|
|
82
82
|
stateDir: string,
|
|
83
83
|
ctxWindow: number,
|
|
84
84
|
indexDir: string = getIndexDir(),
|
|
85
|
+
// Optional clock override for deterministic tests only. Production callers
|
|
86
|
+
// omit it → Date.now(), byte-identical behavior. The S39 prune test pins
|
|
87
|
+
// heartbeats to a known-old timestamp so pruneStaleSessions' Date.now()
|
|
88
|
+
// cutoff unambiguously exceeds them (no same-millisecond last_seen ==
|
|
89
|
+
// cutoff race that made pruned !== 2).
|
|
90
|
+
nowMs: number = Date.now(),
|
|
85
91
|
): void {
|
|
86
92
|
const db = openIndexStore(indexDir);
|
|
87
|
-
const now =
|
|
93
|
+
const now = nowMs;
|
|
88
94
|
db.prepare(
|
|
89
95
|
`INSERT INTO session_heartbeats (pid, session_id, repo_root, state_dir, ctx_window, last_seen)
|
|
90
96
|
VALUES (@pid, @session_id, @repo_root, @state_dir, @ctx_window, @last_seen)
|
|
@@ -127,9 +133,15 @@ export function appendTokenSample(
|
|
|
127
133
|
ctxWindow: number,
|
|
128
134
|
eventsLogPath: string | null,
|
|
129
135
|
indexDir: string = getIndexDir(),
|
|
136
|
+
// Optional clock override for deterministic tests only. Production callers
|
|
137
|
+
// omit it → falls back to Date.now(), byte-identical behavior. The S39
|
|
138
|
+
// timeseries test injects distinct timestamps so the per-ts totals map is
|
|
139
|
+
// not collapsed by same-millisecond sample coincidence (the pre-existing
|
|
140
|
+
// flake where 3 samples in one ms made totals.length == 1).
|
|
141
|
+
nowMs: number = Date.now(),
|
|
130
142
|
): void {
|
|
131
143
|
const db = openIndexStore(indexDir);
|
|
132
|
-
const now =
|
|
144
|
+
const now = nowMs;
|
|
133
145
|
db.prepare(
|
|
134
146
|
`INSERT INTO token_samples (session_id, repo_root, tokens, percent, ctx_window, ts)
|
|
135
147
|
VALUES (@session_id, @repo_root, @tokens, @percent, @ctx_window, @ts)`,
|