pi-mega-compact 0.12.2 → 0.12.4
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/extensions/dashboard-server/routes-game.js +6 -1
- package/dist/extensions/mega-runtime/dashboard-snapshot.js +23 -5
- package/dist/src/memoryGraph/sources.js +7 -5
- package/extensions/dashboard-server/routes-game.ts +6 -1
- package/extensions/mega-runtime/dashboard-snapshot.ts +23 -5
- package/package.json +1 -1
- package/src/memoryGraph/sources.ts +7 -5
|
@@ -194,7 +194,12 @@ export function handlePerf(req, res, ctx) {
|
|
|
194
194
|
minutes = 30;
|
|
195
195
|
minutes = Math.min(minutes, 1440); // cap at 24h
|
|
196
196
|
const sinceTs = Date.now() - minutes * 60_000;
|
|
197
|
-
|
|
197
|
+
let rows = readPerfSamples(stateDir, sinceTs); // guardrails-allow PREVENT-PI-004: local SQLite read (loopback dashboard)
|
|
198
|
+
// Fallback: if the window is empty (stale data from a previous
|
|
199
|
+
// session), show the most recent 200 samples regardless of age.
|
|
200
|
+
if (rows.length === 0) {
|
|
201
|
+
rows = readPerfSamples(stateDir, 0).slice(-200);
|
|
202
|
+
}
|
|
198
203
|
const byKind = new Map();
|
|
199
204
|
for (const r of rows) {
|
|
200
205
|
let arr = byKind.get(r.kind);
|
|
@@ -51,7 +51,21 @@ export function buildDashboardSnapshot(ctx) {
|
|
|
51
51
|
tierPct: ctx.config.tierPct,
|
|
52
52
|
effectiveThresholdPct: ctx.config.tierPct != null ? ctx.config.tierPct * 100 : null,
|
|
53
53
|
},
|
|
54
|
-
store:
|
|
54
|
+
store: {
|
|
55
|
+
checkpointCount: ctx.st.checkpointCount,
|
|
56
|
+
totalTokenEstimate: ctx.st.totalTokenEstimate,
|
|
57
|
+
originalTokens: ctx.st.originalTokens,
|
|
58
|
+
tokensSaved: ctx.st.tokensSaved,
|
|
59
|
+
injectedCount: ctx.st.injectedCount,
|
|
60
|
+
dedupHitRate: ctx.st.dedupHitRate,
|
|
61
|
+
// Session-scoped dedup stats from runtime counters, NOT the
|
|
62
|
+
// cumulative meta table (which is repo-wide and belongs in the
|
|
63
|
+
// repo card below). rt.dedupSkips/dedupAttempts reset on session
|
|
64
|
+
// restart so the session card shows only this session's dedup.
|
|
65
|
+
storageDedupRate: ctx.rt.dedupAttempts > 0 ? ctx.rt.dedupSkips / ctx.rt.dedupAttempts : 0,
|
|
66
|
+
dedupAttempts: ctx.rt.dedupAttempts,
|
|
67
|
+
dedupCollapsed: ctx.rt.dedupSkips,
|
|
68
|
+
},
|
|
55
69
|
crew: {
|
|
56
70
|
activeAgents: ctx.activeAgents,
|
|
57
71
|
currentTurn: ctx.currentTurn,
|
|
@@ -76,13 +90,17 @@ export function buildDashboardSnapshot(ctx) {
|
|
|
76
90
|
integrity: ctx.di,
|
|
77
91
|
cacheHits: {
|
|
78
92
|
session: ctx.rt.dedupSkips + ctx.rt.recallInjections,
|
|
79
|
-
|
|
93
|
+
// Total = cumulative dedup collapses (meta table) + session
|
|
94
|
+
// recall injections. The meta table is the authoritative
|
|
95
|
+
// cumulative counter for dedup; recall injections are tracked
|
|
96
|
+
// per-session in rt and there's no cumulative counter yet.
|
|
97
|
+
total: ctx.repo.dedupCollapsed,
|
|
80
98
|
sessionTokensSaved: ctx.rt.cacheHitTokens,
|
|
81
|
-
totalTokensSaved: ctx.
|
|
99
|
+
totalTokensSaved: ctx.repo.dedupCollapsed > 0 ? ctx.repo.dedupCollapsed * 100 : 0,
|
|
82
100
|
},
|
|
83
101
|
compacts: {
|
|
84
102
|
session: ctx.rt.compactCount,
|
|
85
|
-
total: ctx.
|
|
103
|
+
total: ctx.repo.checkpointCount,
|
|
86
104
|
},
|
|
87
105
|
timeSaved: {
|
|
88
106
|
compact: {
|
|
@@ -91,7 +109,7 @@ export function buildDashboardSnapshot(ctx) {
|
|
|
91
109
|
},
|
|
92
110
|
cacheHit: {
|
|
93
111
|
sessionSec: ctx.rt.cacheHitTokens / 1000,
|
|
94
|
-
totalSec: (ctx.
|
|
112
|
+
totalSec: (ctx.repo.dedupCollapsed * 100) / 1000,
|
|
95
113
|
},
|
|
96
114
|
},
|
|
97
115
|
model: ctx.currentModel
|
|
@@ -48,10 +48,11 @@ export function buildCheckpointNodes(db, sessionId, nodes, edges) {
|
|
|
48
48
|
let prevId = null;
|
|
49
49
|
for (const row of rows) {
|
|
50
50
|
const id = String(row.id);
|
|
51
|
+
const rowSessionId = sessionId || String(row.session_id ?? "");
|
|
51
52
|
const summary = String(row.summary ?? "");
|
|
52
53
|
const node = {
|
|
53
54
|
id,
|
|
54
|
-
sessionId,
|
|
55
|
+
sessionId: rowSessionId,
|
|
55
56
|
label: id,
|
|
56
57
|
summaryTruncated: summary.length > 200 ? summary.slice(0, 197) + "..." : summary,
|
|
57
58
|
tokenEstimate: Number(row.token_estimate ?? 0),
|
|
@@ -107,14 +108,14 @@ export function buildTurnNodes(db, sessionId, nodes, edges) {
|
|
|
107
108
|
const existingIds = new Set(nodes.map((n) => n.id));
|
|
108
109
|
const rows = sessionId
|
|
109
110
|
? db
|
|
110
|
-
.prepare(`SELECT turn_index, role, pressure_band, ctx_tokens, ctx_percent,
|
|
111
|
+
.prepare(`SELECT turn_index, session_id, role, pressure_band, ctx_tokens, ctx_percent,
|
|
111
112
|
epoch_id, ended_at
|
|
112
113
|
FROM turns
|
|
113
114
|
WHERE session_id = ?
|
|
114
115
|
ORDER BY turn_index ASC`)
|
|
115
116
|
.all(sessionId)
|
|
116
117
|
: db
|
|
117
|
-
.prepare(`SELECT turn_index, role, pressure_band, ctx_tokens, ctx_percent,
|
|
118
|
+
.prepare(`SELECT turn_index, session_id, role, pressure_band, ctx_tokens, ctx_percent,
|
|
118
119
|
epoch_id, ended_at
|
|
119
120
|
FROM turns
|
|
120
121
|
ORDER BY turn_index ASC`)
|
|
@@ -124,7 +125,8 @@ export function buildTurnNodes(db, sessionId, nodes, edges) {
|
|
|
124
125
|
let prevId = null;
|
|
125
126
|
for (const row of rows) {
|
|
126
127
|
const ti = Number(row.turn_index);
|
|
127
|
-
const
|
|
128
|
+
const rowSessionId = sessionId || String(row.session_id ?? "");
|
|
129
|
+
const nodeId = `turn:${rowSessionId}:${ti}`;
|
|
128
130
|
if (existingIds.has(nodeId))
|
|
129
131
|
continue;
|
|
130
132
|
existingIds.add(nodeId);
|
|
@@ -132,7 +134,7 @@ export function buildTurnNodes(db, sessionId, nodes, edges) {
|
|
|
132
134
|
const endedAt = row.ended_at ? Number(row.ended_at) : Date.now();
|
|
133
135
|
const node = {
|
|
134
136
|
id: nodeId,
|
|
135
|
-
sessionId,
|
|
137
|
+
sessionId: rowSessionId,
|
|
136
138
|
label: `Turn ${ti}`,
|
|
137
139
|
summaryTruncated: `Turn ${ti}: ${role}${row.epoch_id ? ` (epoch: ${String(row.epoch_id)})` : ""}`,
|
|
138
140
|
tokenEstimate: row.ctx_tokens ? Number(row.ctx_tokens) : 0,
|
|
@@ -234,7 +234,12 @@ export function handlePerf(
|
|
|
234
234
|
if (!Number.isFinite(minutes) || minutes <= 0) minutes = 30;
|
|
235
235
|
minutes = Math.min(minutes, 1440); // cap at 24h
|
|
236
236
|
const sinceTs = Date.now() - minutes * 60_000;
|
|
237
|
-
|
|
237
|
+
let rows = readPerfSamples(stateDir, sinceTs); // guardrails-allow PREVENT-PI-004: local SQLite read (loopback dashboard)
|
|
238
|
+
// Fallback: if the window is empty (stale data from a previous
|
|
239
|
+
// session), show the most recent 200 samples regardless of age.
|
|
240
|
+
if (rows.length === 0) {
|
|
241
|
+
rows = readPerfSamples(stateDir, 0).slice(-200);
|
|
242
|
+
}
|
|
238
243
|
const byKind = new Map<string, number[]>();
|
|
239
244
|
for (const r of rows) {
|
|
240
245
|
let arr = byKind.get(r.kind);
|
|
@@ -110,7 +110,21 @@ export function buildDashboardSnapshot(ctx: SnapshotBuildContext): DashboardSnap
|
|
|
110
110
|
tierPct: ctx.config.tierPct,
|
|
111
111
|
effectiveThresholdPct: ctx.config.tierPct != null ? ctx.config.tierPct * 100 : null,
|
|
112
112
|
},
|
|
113
|
-
store:
|
|
113
|
+
store: {
|
|
114
|
+
checkpointCount: ctx.st.checkpointCount,
|
|
115
|
+
totalTokenEstimate: ctx.st.totalTokenEstimate,
|
|
116
|
+
originalTokens: ctx.st.originalTokens,
|
|
117
|
+
tokensSaved: ctx.st.tokensSaved,
|
|
118
|
+
injectedCount: ctx.st.injectedCount,
|
|
119
|
+
dedupHitRate: ctx.st.dedupHitRate,
|
|
120
|
+
// Session-scoped dedup stats from runtime counters, NOT the
|
|
121
|
+
// cumulative meta table (which is repo-wide and belongs in the
|
|
122
|
+
// repo card below). rt.dedupSkips/dedupAttempts reset on session
|
|
123
|
+
// restart so the session card shows only this session's dedup.
|
|
124
|
+
storageDedupRate: ctx.rt.dedupAttempts > 0 ? ctx.rt.dedupSkips / ctx.rt.dedupAttempts : 0,
|
|
125
|
+
dedupAttempts: ctx.rt.dedupAttempts,
|
|
126
|
+
dedupCollapsed: ctx.rt.dedupSkips,
|
|
127
|
+
},
|
|
114
128
|
crew: {
|
|
115
129
|
activeAgents: ctx.activeAgents,
|
|
116
130
|
currentTurn: ctx.currentTurn,
|
|
@@ -135,13 +149,17 @@ export function buildDashboardSnapshot(ctx: SnapshotBuildContext): DashboardSnap
|
|
|
135
149
|
integrity: ctx.di,
|
|
136
150
|
cacheHits: {
|
|
137
151
|
session: ctx.rt.dedupSkips + ctx.rt.recallInjections,
|
|
138
|
-
|
|
152
|
+
// Total = cumulative dedup collapses (meta table) + session
|
|
153
|
+
// recall injections. The meta table is the authoritative
|
|
154
|
+
// cumulative counter for dedup; recall injections are tracked
|
|
155
|
+
// per-session in rt and there's no cumulative counter yet.
|
|
156
|
+
total: ctx.repo.dedupCollapsed,
|
|
139
157
|
sessionTokensSaved: ctx.rt.cacheHitTokens,
|
|
140
|
-
totalTokensSaved: ctx.
|
|
158
|
+
totalTokensSaved: ctx.repo.dedupCollapsed > 0 ? ctx.repo.dedupCollapsed * 100 : 0,
|
|
141
159
|
},
|
|
142
160
|
compacts: {
|
|
143
161
|
session: ctx.rt.compactCount,
|
|
144
|
-
total: ctx.
|
|
162
|
+
total: ctx.repo.checkpointCount,
|
|
145
163
|
},
|
|
146
164
|
timeSaved: {
|
|
147
165
|
compact: {
|
|
@@ -150,7 +168,7 @@ export function buildDashboardSnapshot(ctx: SnapshotBuildContext): DashboardSnap
|
|
|
150
168
|
},
|
|
151
169
|
cacheHit: {
|
|
152
170
|
sessionSec: ctx.rt.cacheHitTokens / 1000,
|
|
153
|
-
totalSec: (ctx.
|
|
171
|
+
totalSec: (ctx.repo.dedupCollapsed * 100) / 1000,
|
|
154
172
|
},
|
|
155
173
|
},
|
|
156
174
|
model: ctx.currentModel
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.4",
|
|
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",
|
|
@@ -77,10 +77,11 @@ export function buildCheckpointNodes(
|
|
|
77
77
|
let prevId: string | null = null;
|
|
78
78
|
for (const row of rows) {
|
|
79
79
|
const id = String(row.id);
|
|
80
|
+
const rowSessionId = sessionId || String(row.session_id ?? "");
|
|
80
81
|
const summary = String(row.summary ?? "");
|
|
81
82
|
const node: MemoryGraphNode = {
|
|
82
83
|
id,
|
|
83
|
-
sessionId,
|
|
84
|
+
sessionId: rowSessionId,
|
|
84
85
|
label: id,
|
|
85
86
|
summaryTruncated: summary.length > 200 ? summary.slice(0, 197) + "..." : summary,
|
|
86
87
|
tokenEstimate: Number(row.token_estimate ?? 0),
|
|
@@ -149,7 +150,7 @@ export function buildTurnNodes(
|
|
|
149
150
|
const rows = sessionId
|
|
150
151
|
? (db
|
|
151
152
|
.prepare(
|
|
152
|
-
`SELECT turn_index, role, pressure_band, ctx_tokens, ctx_percent,
|
|
153
|
+
`SELECT turn_index, session_id, role, pressure_band, ctx_tokens, ctx_percent,
|
|
153
154
|
epoch_id, ended_at
|
|
154
155
|
FROM turns
|
|
155
156
|
WHERE session_id = ?
|
|
@@ -158,7 +159,7 @@ export function buildTurnNodes(
|
|
|
158
159
|
.all(sessionId) as Array<Record<string, unknown>>)
|
|
159
160
|
: (db
|
|
160
161
|
.prepare(
|
|
161
|
-
`SELECT turn_index, role, pressure_band, ctx_tokens, ctx_percent,
|
|
162
|
+
`SELECT turn_index, session_id, role, pressure_band, ctx_tokens, ctx_percent,
|
|
162
163
|
epoch_id, ended_at
|
|
163
164
|
FROM turns
|
|
164
165
|
ORDER BY turn_index ASC`,
|
|
@@ -170,7 +171,8 @@ export function buildTurnNodes(
|
|
|
170
171
|
let prevId: string | null = null;
|
|
171
172
|
for (const row of rows) {
|
|
172
173
|
const ti = Number(row.turn_index);
|
|
173
|
-
const
|
|
174
|
+
const rowSessionId = sessionId || String(row.session_id ?? "");
|
|
175
|
+
const nodeId = `turn:${rowSessionId}:${ti}`;
|
|
174
176
|
if (existingIds.has(nodeId)) continue;
|
|
175
177
|
existingIds.add(nodeId);
|
|
176
178
|
|
|
@@ -179,7 +181,7 @@ export function buildTurnNodes(
|
|
|
179
181
|
|
|
180
182
|
const node: MemoryGraphNode = {
|
|
181
183
|
id: nodeId,
|
|
182
|
-
sessionId,
|
|
184
|
+
sessionId: rowSessionId,
|
|
183
185
|
label: `Turn ${ti}`,
|
|
184
186
|
summaryTruncated: `Turn ${ti}: ${role}${row.epoch_id ? ` (epoch: ${String(row.epoch_id)})` : ""}`,
|
|
185
187
|
tokenEstimate: row.ctx_tokens ? Number(row.ctx_tokens) : 0,
|