pi-mega-compact 0.4.2 → 0.4.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/extensions/mega-compact.ts +10 -7
- package/package.json +1 -1
- package/src/store/sprint10.test.ts +32 -0
- package/src/store/sqlite.ts +19 -0
|
@@ -333,19 +333,22 @@ export default function (pi: ExtensionAPI) {
|
|
|
333
333
|
const dedupStr = storageRate * 100 >= 10
|
|
334
334
|
? `${Math.round(storageRate * 100)}%`
|
|
335
335
|
: `${(storageRate * 100).toFixed(1)}%`;
|
|
336
|
-
// saved = cumulative original − stored
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
336
|
+
// saved = tokens removed from context (cumulative original − stored).
|
|
337
|
+
// Show BOTH this-session (rt.tokensSaved) and repo-wide-total
|
|
338
|
+
// (repo.tokensSaved) so the user sees per-session progress vs the running
|
|
339
|
+
// repo total. "used" = stored checkpoint tokens (repo.totalTokenEstimate
|
|
340
|
+
// vs st.totalTokenEstimate). Use "k" only at/above 1000 so small-but-real
|
|
341
|
+
// numbers stay visible (previously Math.round(x/1000) zeroed <1000).
|
|
342
|
+
const fmt = (x: number) => (x >= 1000 ? `${(x / 1000).toFixed(1)}k` : `${x}`);
|
|
343
|
+
const savedStr = `${fmt(rt.tokensSaved)} sess / ${fmt(repo.tokensSaved)} repo`;
|
|
344
|
+
const usedStr = `${fmt(st.totalTokenEstimate)} sess / ${fmt(repo.totalTokenEstimate)} repo`;
|
|
342
345
|
const agentStr = activeAgents > 0 ? ` │ 🤖 ${activeAgents} agent${activeAgents === 1 ? "" : "s"}` : "";
|
|
343
346
|
const turnStr = currentTurn > 0 ? ` │ turn ${currentTurn}` : "";
|
|
344
347
|
ctx.ui.setWidget(
|
|
345
348
|
WIDGET_KEY,
|
|
346
349
|
[
|
|
347
350
|
` ⚡ ${config.tier} │ ${tokStr}/${maxStr} tokens (${pctStr}) │ ${st.checkpointCount} chkpt${st.checkpointCount === 1 ? "" : "s"}${agentStr}${turnStr}`,
|
|
348
|
-
` ${triggerLabel} │ dedup: ${dedupStr} │ saved: ${savedStr}
|
|
351
|
+
` ${triggerLabel} │ dedup: ${dedupStr} │ used: ${usedStr} │ saved: ${savedStr}`,
|
|
349
352
|
],
|
|
350
353
|
{ placement: "aboveEditor" },
|
|
351
354
|
);
|
package/package.json
CHANGED
|
@@ -174,6 +174,38 @@ test("checkAllIntegrity covers every session", () => {
|
|
|
174
174
|
assert.ok(reports.every((r: { ok: boolean }) => r.ok));
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
+
// --- schema migration (v0.4.2: original_token_estimate) -------------------
|
|
178
|
+
|
|
179
|
+
test("Sprint 10 migration: pre-0.4.2 db gains original_token_estimate and repoStats works", () => {
|
|
180
|
+
const dir = join(baseTmp, `run-${counter++}`);
|
|
181
|
+
// Simulate a v0.4.1-era store: openStore() builds the full current schema,
|
|
182
|
+
// then drop the original_token_estimate column that 0.4.2 added. CREATE TABLE
|
|
183
|
+
// IF NOT EXISTS is a no-op on an existing table, which is exactly why the
|
|
184
|
+
// shipped v0.4.2 crashed at runtime on old repos ("no such column").
|
|
185
|
+
const db = openStore(dir);
|
|
186
|
+
db.exec("ALTER TABLE context_chunks DROP COLUMN original_token_estimate;");
|
|
187
|
+
closeStore(dir);
|
|
188
|
+
|
|
189
|
+
// Re-open through the real code path — must ALTER the column in, not crash.
|
|
190
|
+
const vs = new VectorStore({ dedupSim: 0.9, stateDir: dir });
|
|
191
|
+
vs.add({
|
|
192
|
+
sessionId: "sess_mig",
|
|
193
|
+
summary: "legacy region",
|
|
194
|
+
regionText: "some region text to compact",
|
|
195
|
+
tokenEstimate: 100,
|
|
196
|
+
originalTokenEstimate: 500,
|
|
197
|
+
timestamp: 1,
|
|
198
|
+
});
|
|
199
|
+
const repo = vs.repoStats();
|
|
200
|
+
// No "no such column" crash = migration succeeded; totals reflect the new col.
|
|
201
|
+
assert.equal(repo.checkpointCount, 1);
|
|
202
|
+
assert.equal(repo.originalTokens, 500, "originalTokens read from migrated column");
|
|
203
|
+
// Re-open a second time to prove idempotency (column already exists).
|
|
204
|
+
closeStore(dir);
|
|
205
|
+
const vs2 = new VectorStore({ dedupSim: 0.9, stateDir: dir });
|
|
206
|
+
assert.equal(vs2.repoStats().originalTokens, 500, "stable across re-open");
|
|
207
|
+
});
|
|
208
|
+
|
|
177
209
|
// --- cleanup ---------------------------------------------------------------
|
|
178
210
|
|
|
179
211
|
test("Sprint 10 cleanup", () => {
|
package/src/store/sqlite.ts
CHANGED
|
@@ -190,6 +190,12 @@ function initSchema(db: Database.Database): void {
|
|
|
190
190
|
tokenize='trigram'
|
|
191
191
|
);
|
|
192
192
|
`);
|
|
193
|
+
// Idempotent column migrations. `CREATE TABLE IF NOT EXISTS` is a no-op on a
|
|
194
|
+
// pre-existing table, so new columns added to context_chunks after a store was
|
|
195
|
+
// first created (e.g. original_token_estimate in v0.4.2) must be ALTERed in for
|
|
196
|
+
// databases created by an older version — otherwise repoStats()/upsert crash
|
|
197
|
+
// with "no such column" and the extension fails to load. Additive only.
|
|
198
|
+
ensureColumn(db, "context_chunks", "original_token_estimate", "INTEGER");
|
|
193
199
|
const v = db.prepare("SELECT value FROM meta WHERE key='schema_version'").get() as
|
|
194
200
|
| { value: string }
|
|
195
201
|
| undefined;
|
|
@@ -198,6 +204,19 @@ function initSchema(db: Database.Database): void {
|
|
|
198
204
|
}
|
|
199
205
|
}
|
|
200
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Add `column` (with `decl`, e.g. "INTEGER") to `table` if it does not already
|
|
209
|
+
* exist. Idempotent: checks PRAGMA table_info first, so it is safe to run on
|
|
210
|
+
* every open. Table/column/decl are code-controlled constants (never user
|
|
211
|
+
* input), so the unavoidable identifier interpolation here does not violate
|
|
212
|
+
* PREVENT-002 (no external data reaches this SQL).
|
|
213
|
+
*/
|
|
214
|
+
function ensureColumn(db: Database.Database, table: string, column: string, decl: string): void {
|
|
215
|
+
const cols = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;
|
|
216
|
+
if (cols.some((c) => c.name === column)) return;
|
|
217
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${decl}`);
|
|
218
|
+
}
|
|
219
|
+
|
|
201
220
|
/** Read a string-valued meta key (or undefined). Used for cumulative counters. */
|
|
202
221
|
export function getMeta(key: string, stateDir: string = getStateDir()): string | undefined {
|
|
203
222
|
const db = openStore(stateDir);
|