pi-mega-compact 0.20.4 → 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 +3 -1
- 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 +2 -0
- 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
|
|
|
@@ -313,6 +314,7 @@ export async function launchDashboardServer(
|
|
|
313
314
|
if (handleVectorCortexResidual(req, res, ctx)) return;
|
|
314
315
|
if (handleVectorCortexReconstruct(req, res, ctx)) return;
|
|
315
316
|
if (handleVectorCortexPlans(req, res, ctx)) return;
|
|
317
|
+
if (handleVectorCortexRender(req, res, ctx)) return;
|
|
316
318
|
handleStatic(req, res, ctx);
|
|
317
319
|
});
|
|
318
320
|
|
|
@@ -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)`,
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/provider/registry.ts — fixture-backed base provider profile
|
|
3
|
+
* registry (VC5B, task 2).
|
|
4
|
+
*
|
|
5
|
+
* The registry resolves a `(provider, model)` pair to a `ProviderProfileBundle`
|
|
6
|
+
* (CONTRACTS §ProviderProfileV1 + role/tool/cache rules). Unknown provider/model
|
|
7
|
+
* returns `PRO_PROFILE_UNKNOWN` and the renderer CLEANLY bypasses vector-cortex
|
|
8
|
+
* rendering (NOT an error — the host uses the predecessor prompt path).
|
|
9
|
+
*
|
|
10
|
+
* Profiles are fixture-backed: each base profile is declared here as a constant
|
|
11
|
+
* and is also pinned as a conformance fixture under `conformance/vector-cortex/v2/
|
|
12
|
+
* provider/` (registered by `scripts/gen-fixtures/provider.mjs`). The registry is
|
|
13
|
+
* the REAL resolver the acceptance suite drives; the fixtures are the committed
|
|
14
|
+
* canonical corpus that proves each profile's cache-identity behavior.
|
|
15
|
+
*
|
|
16
|
+
* Pi-agnostic, dependency-free, zero network (PREVENT-PI-004 / PREVENT-011).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
PRO_PROFILE_UNKNOWN,
|
|
21
|
+
type ProviderProfileBundle,
|
|
22
|
+
type ProviderProfileResult,
|
|
23
|
+
type ProviderProfileV1,
|
|
24
|
+
} from "./types.js";
|
|
25
|
+
|
|
26
|
+
/** A registry key is `provider` + `model`. Lookup is exact-match. */
|
|
27
|
+
function key(provider: string, model: string): string {
|
|
28
|
+
return `${provider}//${model}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The base role rule every VC5B profile shares: the renderer MUST use the host
|
|
33
|
+
* `before_agent_start` prepend seam and MUST NOT inject `role:"system"`
|
|
34
|
+
* (PREVENT-PI-003, critical).
|
|
35
|
+
*/
|
|
36
|
+
const BASE_ROLE = {
|
|
37
|
+
useHostPrependSeam: true,
|
|
38
|
+
forbidSystemRoleInjection: true,
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The base tool rule every VC5B profile shares: exact tool bytes preserved
|
|
43
|
+
* (PREVENT-PI-002) and the renderer never reorders away from the validator order.
|
|
44
|
+
*/
|
|
45
|
+
const BASE_TOOL = {
|
|
46
|
+
preserveExactToolBytes: true,
|
|
47
|
+
forbidToolReorder: true,
|
|
48
|
+
} as const;
|
|
49
|
+
|
|
50
|
+
/** Build a base cache rule (entire-canonical-request hashing by default). */
|
|
51
|
+
function baseCache(stableFields: readonly string[]): ProviderProfileBundle["cache"] {
|
|
52
|
+
return {
|
|
53
|
+
hashMode: "entire-canonical-request",
|
|
54
|
+
stableFields,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Build a contract-profile shape pinned as a conformance fixture too. */
|
|
59
|
+
function profile(
|
|
60
|
+
id: string,
|
|
61
|
+
version: string,
|
|
62
|
+
excludedJsonPointers: ProviderProfileV1["excludedJsonPointers"],
|
|
63
|
+
): ProviderProfileV1 {
|
|
64
|
+
return {
|
|
65
|
+
schema: "provider-profile-v1",
|
|
66
|
+
id,
|
|
67
|
+
version,
|
|
68
|
+
hashMode: "entire-canonical-request",
|
|
69
|
+
excludedJsonPointers,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The fixture-backed base profiles. Each entry is the REAL bundle the renderer
|
|
75
|
+
* resolves; the parallel conformance fixtures prove the cache-identity behavior.
|
|
76
|
+
*/
|
|
77
|
+
const BASE_PROFILES: readonly ProviderProfileBundle[] = [
|
|
78
|
+
{
|
|
79
|
+
profile: profile("anthropic-claude-opus", "v1", []),
|
|
80
|
+
role: BASE_ROLE,
|
|
81
|
+
tool: BASE_TOOL,
|
|
82
|
+
cache: baseCache(["systemPromptPrepend", "tools", "nodes"]),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
profile: profile("anthropic-claude-sonnet", "v1", []),
|
|
86
|
+
role: BASE_ROLE,
|
|
87
|
+
tool: BASE_TOOL,
|
|
88
|
+
cache: baseCache(["systemPromptPrepend", "tools", "nodes"]),
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
profile: profile("openai-gpt", "v1", []),
|
|
92
|
+
role: BASE_ROLE,
|
|
93
|
+
tool: BASE_TOOL,
|
|
94
|
+
cache: baseCache(["systemPromptPrepend", "tools", "nodes"]),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
// A profile that proves a fixture-excluded pointer: a provider whose
|
|
98
|
+
// request-id header cannot affect cache identity. Excluded + versioned.
|
|
99
|
+
profile: profile("google-gemini", "v1", [
|
|
100
|
+
{
|
|
101
|
+
pointer: "/requestId",
|
|
102
|
+
fixtureId: "PRO-EXCLUDE-010",
|
|
103
|
+
proofDigest: "sha256:excluded-request-id-proof",
|
|
104
|
+
},
|
|
105
|
+
]),
|
|
106
|
+
role: BASE_ROLE,
|
|
107
|
+
tool: BASE_TOOL,
|
|
108
|
+
cache: baseCache(["systemPromptPrepend", "tools", "nodes"]),
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const REGISTRY: ReadonlyMap<string, ProviderProfileBundle> = new Map(
|
|
113
|
+
BASE_PROFILES.map((b) => [key(b.profile.id, b.profile.version), b] as const),
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Resolve a `(provider, model)` pair to a `ProviderProfileBundle`. Unknown
|
|
118
|
+
* provider / model / version → a CLEAN bypass (`PRO_PROFILE_UNKNOWN`), never an
|
|
119
|
+
* error. The renderer consults this and, on `ok:false`, selects triad C (the
|
|
120
|
+
* predecessor prompt path).
|
|
121
|
+
*/
|
|
122
|
+
export function resolveProviderProfile(
|
|
123
|
+
provider: string,
|
|
124
|
+
model: string,
|
|
125
|
+
): ProviderProfileResult {
|
|
126
|
+
const bundle = REGISTRY.get(key(provider, model));
|
|
127
|
+
if (bundle === undefined) {
|
|
128
|
+
return { ok: false, code: PRO_PROFILE_UNKNOWN };
|
|
129
|
+
}
|
|
130
|
+
return { ok: true, bundle };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** The fixture-backed base profiles (exposed for tests / dashboard introspection). */
|
|
134
|
+
export const BASE_PROVIDER_PROFILES: readonly ProviderProfileBundle[] = BASE_PROFILES;
|
|
135
|
+
|
|
136
|
+
/** The set of known `(provider, model)` keys, for conformance registration. */
|
|
137
|
+
export const KNOWN_PROVIDER_KEYS: readonly string[] = Array.from(REGISTRY.keys());
|