pi-goosedump 0.12.17 → 0.12.18
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/README.md +11 -11
- package/dist/index.ts +78 -14
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -93,17 +93,17 @@ Optional settings live under `goosedump` in:
|
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
`turnsBeforeCompact` is an integer from 0 to 255. `0` disables scheduled
|
|
96
|
-
compaction. Each
|
|
97
|
-
that call tools. The countdown is restored when a session
|
|
98
|
-
the footer with a status dot (green when >25% turns
|
|
99
|
-
when ≤12.5%) followed by a hexadecimal countdown.
|
|
100
|
-
remain, `● GD:00` is ready to compact, and `● GD:--`
|
|
101
|
-
adds `queued` while compaction is waiting for the active
|
|
102
|
-
`compacting` while the summary is being built. Pi remains
|
|
103
|
-
its normal context threshold. Whichever limit is reached
|
|
104
|
-
and every successful compaction resets the countdown. A
|
|
105
|
-
compaction leaves the counter armed at zero and is not
|
|
106
|
-
settlement.
|
|
96
|
+
compaction. Each fully settled agent run counts as one turn; intermediate model
|
|
97
|
+
responses that call tools do not. The countdown is restored when a session
|
|
98
|
+
resumes and appears in the footer with a status dot (green when >25% turns
|
|
99
|
+
remain, yellow when ≤25%, red when ≤12.5%) followed by a hexadecimal countdown.
|
|
100
|
+
`● GD:0A` means ten turns remain, `● GD:00` is ready to compact, and `● GD:--`
|
|
101
|
+
is disabled. The footer adds `queued` while compaction is waiting for the active
|
|
102
|
+
agent run to settle and `compacting` while the summary is being built. Pi remains
|
|
103
|
+
the sole scheduler for its normal context threshold. Whichever limit is reached
|
|
104
|
+
first compacts once, and every successful compaction resets the countdown. A
|
|
105
|
+
failed or cancelled compaction leaves the counter armed at zero and is not
|
|
106
|
+
retried in the same settlement.
|
|
107
107
|
|
|
108
108
|
`summaryMaxTokens` is an integer from 512 to 65536 (default 4096). The effective
|
|
109
109
|
summary budget is the lower of this value and 80% of Pi's `compaction.reserveTokens`,
|
package/dist/index.ts
CHANGED
|
@@ -590,11 +590,26 @@ function currentSessionTarget(ctx) {
|
|
|
590
590
|
function isCompactionEntry(entry) {
|
|
591
591
|
return entry.type === "compaction";
|
|
592
592
|
}
|
|
593
|
+
var COMPLETED_AGENT_RUN_ENTRY = "goosedump-completed-agent-run";
|
|
593
594
|
function isMessageEntry(entry) {
|
|
594
595
|
return entry.type === "message";
|
|
595
596
|
}
|
|
596
|
-
function
|
|
597
|
-
|
|
597
|
+
function isTerminalAssistant(message) {
|
|
598
|
+
if (message.role !== "assistant")
|
|
599
|
+
return false;
|
|
600
|
+
if (message.stopReason !== "stop" && message.stopReason !== "length")
|
|
601
|
+
return false;
|
|
602
|
+
return !(Array.isArray(message.content) && message.content.some((part) => isRecord(part) && part.type === "toolCall"));
|
|
603
|
+
}
|
|
604
|
+
function completedAgentRunData(entry) {
|
|
605
|
+
if (entry.type !== "custom" || entry.customType !== COMPLETED_AGENT_RUN_ENTRY)
|
|
606
|
+
return;
|
|
607
|
+
if (!isRecord(entry.data) || entry.data.version !== 1)
|
|
608
|
+
return;
|
|
609
|
+
const startedAfterEntryId = entry.data.startedAfterEntryId;
|
|
610
|
+
if (startedAfterEntryId !== null && typeof startedAfterEntryId !== "string")
|
|
611
|
+
return;
|
|
612
|
+
return { version: 1, startedAfterEntryId };
|
|
598
613
|
}
|
|
599
614
|
var SUMMARIZABLE_ENTRY_TYPES = new Set(["message", "custom_message", "branch_summary"]);
|
|
600
615
|
function piKeepRecentTokens(cwd, includeProject) {
|
|
@@ -666,7 +681,7 @@ function activeHistoryStartIndex(branchEntries) {
|
|
|
666
681
|
const compaction = latestCompaction(branchEntries);
|
|
667
682
|
return compaction ? compactionBoundaryStartIndex(branchEntries, compaction) : 0;
|
|
668
683
|
}
|
|
669
|
-
function
|
|
684
|
+
function completedRunsSinceCompaction(branchEntries) {
|
|
670
685
|
let start = 0;
|
|
671
686
|
for (let i = branchEntries.length - 1;i >= 0; i -= 1) {
|
|
672
687
|
if (isCompactionEntry(branchEntries[i])) {
|
|
@@ -674,10 +689,27 @@ function completedTurnsSinceCompaction(branchEntries) {
|
|
|
674
689
|
break;
|
|
675
690
|
}
|
|
676
691
|
}
|
|
692
|
+
const firstMarkerIndex = branchEntries.findIndex((entry, index) => index >= start && completedAgentRunData(entry) !== undefined);
|
|
693
|
+
if (firstMarkerIndex < 0) {
|
|
694
|
+
let completed2 = 0;
|
|
695
|
+
for (let i = start;i < branchEntries.length; i += 1) {
|
|
696
|
+
const entry = branchEntries[i];
|
|
697
|
+
if (isMessageEntry(entry) && isTerminalAssistant(entry.message))
|
|
698
|
+
completed2 += 1;
|
|
699
|
+
}
|
|
700
|
+
return completed2;
|
|
701
|
+
}
|
|
702
|
+
const firstMarker = completedAgentRunData(branchEntries[firstMarkerIndex]);
|
|
703
|
+
const boundaryIndex = firstMarker?.startedAfterEntryId ? branchEntries.findIndex((entry) => entry.id === firstMarker.startedAfterEntryId) : start - 1;
|
|
704
|
+
const legacyEnd = boundaryIndex >= start ? boundaryIndex + 1 : start;
|
|
677
705
|
let completed = 0;
|
|
678
|
-
for (let i = start;i <
|
|
706
|
+
for (let i = start;i < legacyEnd; i += 1) {
|
|
679
707
|
const entry = branchEntries[i];
|
|
680
|
-
if (isMessageEntry(entry) &&
|
|
708
|
+
if (isMessageEntry(entry) && isTerminalAssistant(entry.message))
|
|
709
|
+
completed += 1;
|
|
710
|
+
}
|
|
711
|
+
for (let i = firstMarkerIndex;i < branchEntries.length; i += 1) {
|
|
712
|
+
if (completedAgentRunData(branchEntries[i]) !== undefined)
|
|
681
713
|
completed += 1;
|
|
682
714
|
}
|
|
683
715
|
return completed;
|
|
@@ -845,7 +877,7 @@ async function runSettingsEditor(ctx) {
|
|
|
845
877
|
const specs = [
|
|
846
878
|
{
|
|
847
879
|
key: "turnsBeforeCompact",
|
|
848
|
-
description: "
|
|
880
|
+
description: "Completed agent runs before compaction; 0 disables.",
|
|
849
881
|
min: TURNS_BEFORE_COMPACT_MIN,
|
|
850
882
|
max: TURNS_BEFORE_COMPACT_MAX
|
|
851
883
|
},
|
|
@@ -1411,6 +1443,8 @@ function createGoosedumpIntegration(options = {}) {
|
|
|
1411
1443
|
let operationGeneration = 0;
|
|
1412
1444
|
let activeSessionFile = null;
|
|
1413
1445
|
let sessionActive = false;
|
|
1446
|
+
let agentRunObserved = false;
|
|
1447
|
+
let agentRunStartEntryId = null;
|
|
1414
1448
|
const rememberQueue = [];
|
|
1415
1449
|
let rememberRunning = null;
|
|
1416
1450
|
function enqueueRemember(target, reportError) {
|
|
@@ -1448,9 +1482,9 @@ function createGoosedumpIntegration(options = {}) {
|
|
|
1448
1482
|
}
|
|
1449
1483
|
function syncCompactCounters(ctx) {
|
|
1450
1484
|
compactSettings = resolveGoosedumpSettings(ctx.cwd, projectSettingsTrusted(ctx));
|
|
1451
|
-
const
|
|
1452
|
-
turnsRemaining = Math.max(0, compactSettings.turnsBeforeCompact -
|
|
1453
|
-
counterTriggered = compactSettings.turnsBeforeCompact > 0 &&
|
|
1485
|
+
const completedRuns = completedRunsSinceCompaction(ctx.sessionManager.getBranch());
|
|
1486
|
+
turnsRemaining = Math.max(0, compactSettings.turnsBeforeCompact - completedRuns);
|
|
1487
|
+
counterTriggered = compactSettings.turnsBeforeCompact > 0 && completedRuns >= compactSettings.turnsBeforeCompact;
|
|
1454
1488
|
}
|
|
1455
1489
|
function updateStatus(ctx) {
|
|
1456
1490
|
if (!goosedumpAvailable)
|
|
@@ -1475,7 +1509,7 @@ function createGoosedumpIntegration(options = {}) {
|
|
|
1475
1509
|
compactionState = state;
|
|
1476
1510
|
updateStatus(ctx);
|
|
1477
1511
|
}
|
|
1478
|
-
function
|
|
1512
|
+
function noteCompletedRun(ctx) {
|
|
1479
1513
|
if (!goosedumpAvailable || !shouldOverrideDefaultCompaction)
|
|
1480
1514
|
return;
|
|
1481
1515
|
syncCompactCounters(ctx);
|
|
@@ -1978,6 +2012,8 @@ ${lines.join(`
|
|
|
1978
2012
|
settlementGeneration = 0;
|
|
1979
2013
|
activeSessionFile = ctx.sessionManager.getSessionFile?.() ?? null;
|
|
1980
2014
|
sessionActive = true;
|
|
2015
|
+
agentRunObserved = false;
|
|
2016
|
+
agentRunStartEntryId = null;
|
|
1981
2017
|
compactionState = { phase: "idle" };
|
|
1982
2018
|
goosedumpAvailable = checkGoosedump(ctx);
|
|
1983
2019
|
notifyInvalidSettings(ctx);
|
|
@@ -1991,9 +2027,28 @@ ${lines.join(`
|
|
|
1991
2027
|
settlementGeneration = 0;
|
|
1992
2028
|
activeSessionFile = null;
|
|
1993
2029
|
sessionActive = false;
|
|
2030
|
+
agentRunObserved = false;
|
|
2031
|
+
agentRunStartEntryId = null;
|
|
1994
2032
|
compactionState = { phase: "idle" };
|
|
1995
2033
|
});
|
|
2034
|
+
pi.on("session_tree", async (_event, ctx) => {
|
|
2035
|
+
sessionGeneration += 1;
|
|
2036
|
+
settlementGeneration = 0;
|
|
2037
|
+
activeSessionFile = ctx.sessionManager.getSessionFile?.() ?? null;
|
|
2038
|
+
sessionActive = true;
|
|
2039
|
+
agentRunObserved = false;
|
|
2040
|
+
agentRunStartEntryId = null;
|
|
2041
|
+
compactionState = { phase: "idle" };
|
|
2042
|
+
syncCompactCounters(ctx);
|
|
2043
|
+
updateStatus(ctx);
|
|
2044
|
+
queueTurnCompaction(ctx, 1);
|
|
2045
|
+
deferQueuedCompaction(ctx);
|
|
2046
|
+
});
|
|
1996
2047
|
pi.on("agent_start", async (_event, ctx) => {
|
|
2048
|
+
if (!agentRunObserved) {
|
|
2049
|
+
agentRunObserved = true;
|
|
2050
|
+
agentRunStartEntryId = ctx.sessionManager.getBranch().at(-1)?.id ?? null;
|
|
2051
|
+
}
|
|
1997
2052
|
if (compactionState.phase !== "running" || compactionState.owner !== "pi")
|
|
1998
2053
|
return;
|
|
1999
2054
|
const request = compactionState.request;
|
|
@@ -2002,11 +2057,20 @@ ${lines.join(`
|
|
|
2002
2057
|
request: { ...request, eligibleSettlement: settlementGeneration + 1 }
|
|
2003
2058
|
} : { phase: "idle" });
|
|
2004
2059
|
});
|
|
2005
|
-
pi.on("turn_end", async (event, ctx) => {
|
|
2006
|
-
if (isCompletedAssistant(event.message))
|
|
2007
|
-
noteCompletedTurn(ctx);
|
|
2008
|
-
});
|
|
2009
2060
|
pi.on("agent_settled", async (_event, ctx) => {
|
|
2061
|
+
if (agentRunObserved) {
|
|
2062
|
+
const countRun = shouldOverrideDefaultCompaction && compactSettings.turnsBeforeCompact > 0;
|
|
2063
|
+
if (countRun) {
|
|
2064
|
+
pi.appendEntry(COMPLETED_AGENT_RUN_ENTRY, {
|
|
2065
|
+
version: 1,
|
|
2066
|
+
startedAfterEntryId: agentRunStartEntryId
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
agentRunObserved = false;
|
|
2070
|
+
agentRunStartEntryId = null;
|
|
2071
|
+
if (countRun)
|
|
2072
|
+
noteCompletedRun(ctx);
|
|
2073
|
+
}
|
|
2010
2074
|
handleAgentSettled(ctx);
|
|
2011
2075
|
});
|
|
2012
2076
|
pi.on("session_before_compact", async (event, ctx) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goosedump",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.18",
|
|
4
4
|
"description": "Pi extension for goosedump session search, durable memory, 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.18",
|
|
42
42
|
"@sinclair/typebox": "^0.34.49"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|