pi-goosedump 0.12.42 → 0.12.44
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/index.ts +63 -9
- package/package.json +2 -2
package/dist/index.ts
CHANGED
|
@@ -826,6 +826,8 @@ class CompactionRuntime {
|
|
|
826
826
|
activeSessionFile = null;
|
|
827
827
|
sessionActive = false;
|
|
828
828
|
activePi = null;
|
|
829
|
+
expectedTurnBoundaryAbort = false;
|
|
830
|
+
suppressedAbortMessages = new WeakSet;
|
|
829
831
|
constructor(deps) {
|
|
830
832
|
this.overrideDefaultCompaction = deps.overrideDefaultCompaction;
|
|
831
833
|
this.nativeExecutablePath = deps.nativeExecutablePath;
|
|
@@ -884,6 +886,7 @@ class CompactionRuntime {
|
|
|
884
886
|
this.activeSessionFile = ctx.sessionManager.getSessionFile?.() ?? null;
|
|
885
887
|
this.sessionActive = true;
|
|
886
888
|
this.compactionState = { phase: "idle" };
|
|
889
|
+
this.expectedTurnBoundaryAbort = false;
|
|
887
890
|
this.syncCompactCounters(ctx);
|
|
888
891
|
this.updateStatus(ctx);
|
|
889
892
|
this.queueTurnCompaction(ctx, 1);
|
|
@@ -895,6 +898,7 @@ class CompactionRuntime {
|
|
|
895
898
|
this.activeSessionFile = null;
|
|
896
899
|
this.sessionActive = false;
|
|
897
900
|
this.compactionState = { phase: "idle" };
|
|
901
|
+
this.expectedTurnBoundaryAbort = false;
|
|
898
902
|
}
|
|
899
903
|
onAgentStart(ctx) {
|
|
900
904
|
if (this.compactionState.phase !== "running" || this.compactionState.owner !== "pi")
|
|
@@ -904,7 +908,19 @@ class CompactionRuntime {
|
|
|
904
908
|
this.syncCompactCounters(ctx);
|
|
905
909
|
this.setCompactionState(ctx, request ? this.requeueRequest(request, this.settlementGeneration + 1) : { phase: "idle" });
|
|
906
910
|
}
|
|
911
|
+
onMessageEnd(event, ctx) {
|
|
912
|
+
if (!this.expectedTurnBoundaryAbort || !this.contextIsCurrent(ctx) || event.message.role !== "assistant" || event.message.stopReason !== "aborted") {
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
this.expectedTurnBoundaryAbort = false;
|
|
916
|
+
this.suppressedAbortMessages.add(event.message);
|
|
917
|
+
return {
|
|
918
|
+
message: { ...event.message, stopReason: "stop", errorMessage: undefined }
|
|
919
|
+
};
|
|
920
|
+
}
|
|
907
921
|
onTurnEnd(event, ctx) {
|
|
922
|
+
if (this.suppressedAbortMessages.delete(event.message))
|
|
923
|
+
return;
|
|
908
924
|
if (!isCompletedAssistant(event.message))
|
|
909
925
|
return;
|
|
910
926
|
const resumeAfter = event.toolResults.length > 0 && !ctx.hasPendingMessages();
|
|
@@ -917,6 +933,7 @@ class CompactionRuntime {
|
|
|
917
933
|
this.interruptToolLoopForQueuedCompaction(ctx, resumeAfter);
|
|
918
934
|
}
|
|
919
935
|
onAgentSettled(ctx) {
|
|
936
|
+
this.expectedTurnBoundaryAbort = false;
|
|
920
937
|
this.settlementGeneration += 1;
|
|
921
938
|
this.syncCompactCounters(ctx);
|
|
922
939
|
this.updateStatus(ctx);
|
|
@@ -1094,7 +1111,7 @@ class CompactionRuntime {
|
|
|
1094
1111
|
const target = compactionEntry.details.target;
|
|
1095
1112
|
if (typeof target !== "string")
|
|
1096
1113
|
return;
|
|
1097
|
-
this.enqueueRemember(target, (message) => {
|
|
1114
|
+
this.enqueueRemember(target, ctx, (message) => {
|
|
1098
1115
|
if (ctx.hasUI) {
|
|
1099
1116
|
ctx.ui.notify(`goosedump memory learning skipped: ${message}`, "warning");
|
|
1100
1117
|
}
|
|
@@ -1147,6 +1164,7 @@ class CompactionRuntime {
|
|
|
1147
1164
|
phase: "queued",
|
|
1148
1165
|
request: { ...request, resumeAfter: true }
|
|
1149
1166
|
};
|
|
1167
|
+
this.expectedTurnBoundaryAbort = true;
|
|
1150
1168
|
ctx.abort();
|
|
1151
1169
|
}
|
|
1152
1170
|
queueThresholdCompaction(ctx, eligibleSettlement, resumeAfter) {
|
|
@@ -1258,6 +1276,38 @@ class CompactionRuntime {
|
|
|
1258
1276
|
}
|
|
1259
1277
|
}
|
|
1260
1278
|
|
|
1279
|
+
// src/memory-activity.ts
|
|
1280
|
+
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
1281
|
+
var MEMORY_ACTIVITY_WIDGET_KEY = "goosedump-memory-activity";
|
|
1282
|
+
var ACTIVITY_FRAMES = ["▰▱▱▱", "▱▰▱▱", "▱▱▰▱", "▱▱▱▰", "▱▱▰▱", "▱▰▱▱"];
|
|
1283
|
+
function showMemoryActivity(ctx) {
|
|
1284
|
+
if (!ctx.hasUI)
|
|
1285
|
+
return;
|
|
1286
|
+
ctx.ui.setWidget(MEMORY_ACTIVITY_WIDGET_KEY, (tui, theme) => {
|
|
1287
|
+
let frame = 0;
|
|
1288
|
+
const timer = setInterval(() => {
|
|
1289
|
+
frame = (frame + 1) % ACTIVITY_FRAMES.length;
|
|
1290
|
+
tui.requestRender();
|
|
1291
|
+
}, 140);
|
|
1292
|
+
timer.unref();
|
|
1293
|
+
return {
|
|
1294
|
+
render(width) {
|
|
1295
|
+
const bar = theme.fg("accent", ACTIVITY_FRAMES[frame] ?? ACTIVITY_FRAMES[0]);
|
|
1296
|
+
const label = theme.fg("muted", "long-term memory");
|
|
1297
|
+
return [truncateToWidth(`${bar} ${label}`, width, "")];
|
|
1298
|
+
},
|
|
1299
|
+
invalidate() {},
|
|
1300
|
+
dispose() {
|
|
1301
|
+
clearInterval(timer);
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
}, { placement: "belowEditor" });
|
|
1305
|
+
}
|
|
1306
|
+
function hideMemoryActivity(ctx) {
|
|
1307
|
+
if (ctx.hasUI)
|
|
1308
|
+
ctx.ui.setWidget(MEMORY_ACTIVITY_WIDGET_KEY, undefined);
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1261
1311
|
// src/policy.ts
|
|
1262
1312
|
var GOOSE_TOOL_NAMES = [
|
|
1263
1313
|
"goose_remember",
|
|
@@ -1502,7 +1552,7 @@ function registerGooseTools(pi, deps) {
|
|
|
1502
1552
|
const resolved = resolveHistoryTarget(ctx, "goose_remember", params);
|
|
1503
1553
|
if (!resolved.ok)
|
|
1504
1554
|
return resolved.result;
|
|
1505
|
-
enqueueRemember(resolved.target, (message) => {
|
|
1555
|
+
enqueueRemember(resolved.target, ctx, (message) => {
|
|
1506
1556
|
if (ctx.hasUI) {
|
|
1507
1557
|
ctx.ui.notify(`goosedump memory learning failed: ${message}`, "warning");
|
|
1508
1558
|
}
|
|
@@ -1671,7 +1721,7 @@ import {
|
|
|
1671
1721
|
Key,
|
|
1672
1722
|
decodeKittyPrintable,
|
|
1673
1723
|
matchesKey,
|
|
1674
|
-
truncateToWidth,
|
|
1724
|
+
truncateToWidth as truncateToWidth2,
|
|
1675
1725
|
visibleWidth,
|
|
1676
1726
|
wrapTextWithAnsi
|
|
1677
1727
|
} from "@earendil-works/pi-tui";
|
|
@@ -1745,7 +1795,7 @@ class NumberInputSubmenu {
|
|
|
1745
1795
|
}
|
|
1746
1796
|
}
|
|
1747
1797
|
function makeRow(content, innerW, border) {
|
|
1748
|
-
const line =
|
|
1798
|
+
const line = truncateToWidth2(content, innerW);
|
|
1749
1799
|
const pad = Math.max(0, innerW - visibleWidth(line));
|
|
1750
1800
|
return `${border} ${line}${" ".repeat(pad)} ${border}`;
|
|
1751
1801
|
}
|
|
@@ -1873,7 +1923,7 @@ async function runSettingsEditor(ctx) {
|
|
|
1873
1923
|
const { accent, bold, dim, muted, text } = colors;
|
|
1874
1924
|
const innerW = overlayInnerWidth(width);
|
|
1875
1925
|
const pad = (value, cellWidth) => {
|
|
1876
|
-
const clipped =
|
|
1926
|
+
const clipped = truncateToWidth2(value, cellWidth);
|
|
1877
1927
|
return `${clipped}${" ".repeat(Math.max(0, cellWidth - visibleWidth(clipped)))}`;
|
|
1878
1928
|
};
|
|
1879
1929
|
const tabLabel = (label, active) => active ? accent(bold(`[${label}]`)) : muted(label);
|
|
@@ -1884,7 +1934,7 @@ async function runSettingsEditor(ctx) {
|
|
|
1884
1934
|
} else if (tab === "help") {
|
|
1885
1935
|
const shortcutWidth = Math.max(visibleWidth("Shortcut"), ...helpRows.map(([shortcut]) => visibleWidth(shortcut)));
|
|
1886
1936
|
const descriptionWidth = Math.max(1, innerW - shortcutWidth - 4);
|
|
1887
|
-
content.push(dim(` ${pad("Shortcut", shortcutWidth)} Description`), ...helpRows.map(([shortcut, description]) => ` ${accent(pad(shortcut, shortcutWidth))} ${text(
|
|
1937
|
+
content.push(dim(` ${pad("Shortcut", shortcutWidth)} Description`), ...helpRows.map(([shortcut, description]) => ` ${accent(pad(shortcut, shortcutWidth))} ${text(truncateToWidth2(description, descriptionWidth))}`));
|
|
1888
1938
|
} else {
|
|
1889
1939
|
for (const [index, spec] of specs.entries()) {
|
|
1890
1940
|
const selected = index === selectedSetting;
|
|
@@ -2015,7 +2065,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
2015
2065
|
}
|
|
2016
2066
|
return {
|
|
2017
2067
|
render(width) {
|
|
2018
|
-
const header = overlayHeader(colors, width, `Goosedump search: ${
|
|
2068
|
+
const header = overlayHeader(colors, width, `Goosedump search: ${truncateToWidth2(query, 44)}`);
|
|
2019
2069
|
if (error) {
|
|
2020
2070
|
return [header, ...overlayError(colors, width, error), overlayFooter(colors, width)];
|
|
2021
2071
|
}
|
|
@@ -2375,12 +2425,12 @@ function createGoosedumpIntegration(options = {}) {
|
|
|
2375
2425
|
const nativeExecutablePath = options.nativeExecutablePath ?? resolveNativeGoosedumpBinary();
|
|
2376
2426
|
const rememberQueue = [];
|
|
2377
2427
|
let rememberRunning = null;
|
|
2378
|
-
function enqueueRemember(target, reportError) {
|
|
2428
|
+
function enqueueRemember(target, ctx, reportError) {
|
|
2379
2429
|
for (let i = rememberQueue.length - 1;i >= 0; i -= 1) {
|
|
2380
2430
|
if (rememberQueue[i]?.target === target)
|
|
2381
2431
|
rememberQueue.splice(i, 1);
|
|
2382
2432
|
}
|
|
2383
|
-
rememberQueue.push({ target, reportError });
|
|
2433
|
+
rememberQueue.push({ target, ctx, reportError });
|
|
2384
2434
|
ensureRememberWorker();
|
|
2385
2435
|
}
|
|
2386
2436
|
function ensureRememberWorker() {
|
|
@@ -2391,11 +2441,14 @@ function createGoosedumpIntegration(options = {}) {
|
|
|
2391
2441
|
const job = rememberQueue.shift();
|
|
2392
2442
|
if (!job)
|
|
2393
2443
|
continue;
|
|
2444
|
+
showMemoryActivity(job.ctx);
|
|
2394
2445
|
try {
|
|
2395
2446
|
await goosedumpMemoryRemember(job.target, undefined, nativeExecutablePath);
|
|
2396
2447
|
} catch (err) {
|
|
2397
2448
|
const message = err instanceof Error ? err.message : String(err);
|
|
2398
2449
|
job.reportError(message);
|
|
2450
|
+
} finally {
|
|
2451
|
+
hideMemoryActivity(job.ctx);
|
|
2399
2452
|
}
|
|
2400
2453
|
}
|
|
2401
2454
|
})().finally(() => {
|
|
@@ -2444,6 +2497,7 @@ ${renderToolRoutingPolicy()}`
|
|
|
2444
2497
|
pi.on("agent_start", async (_event, ctx) => {
|
|
2445
2498
|
compaction.onAgentStart(ctx);
|
|
2446
2499
|
});
|
|
2500
|
+
pi.on("message_end", (event, ctx) => compaction.onMessageEnd(event, ctx));
|
|
2447
2501
|
pi.on("turn_end", async (event, ctx) => {
|
|
2448
2502
|
compaction.onTurnEnd(event, ctx);
|
|
2449
2503
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goosedump",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.44",
|
|
4
4
|
"description": "Pi extension for goosedump session search, durable memory, session management, and compaction",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compaction",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@earendil-works/pi-tui": "^0.82.1",
|
|
41
|
-
"@jarkkojs/goosedump": "^0.12.
|
|
41
|
+
"@jarkkojs/goosedump": "^0.12.44",
|
|
42
42
|
"@sinclair/typebox": "^0.34.49"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|