pi-goosedump 0.12.16 → 0.12.17

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.
Files changed (2) hide show
  1. package/dist/index.ts +72 -29
  2. package/package.json +2 -2
package/dist/index.ts CHANGED
@@ -1411,7 +1411,6 @@ function createGoosedumpIntegration(options = {}) {
1411
1411
  let operationGeneration = 0;
1412
1412
  let activeSessionFile = null;
1413
1413
  let sessionActive = false;
1414
- let agentEndObserved = true;
1415
1414
  const rememberQueue = [];
1416
1415
  let rememberRunning = null;
1417
1416
  function enqueueRemember(target, reportError) {
@@ -1503,6 +1502,19 @@ function createGoosedumpIntegration(options = {}) {
1503
1502
  function runningOperationIsCurrent(operation, generation, sessionFile) {
1504
1503
  return generation === sessionGeneration && sessionFile === activeSessionFile && compactionState.phase === "running" && compactionState.operation === operation;
1505
1504
  }
1505
+ function releasePiCompactionOnAbort(ctx, signal, operation, generation, sessionFile, request, reason) {
1506
+ signal?.addEventListener("abort", () => {
1507
+ if (!runningOperationIsCurrent(operation, generation, sessionFile))
1508
+ return;
1509
+ setCompactionState(ctx, reason !== "manual" && request && requestIsCurrent(request) ? {
1510
+ phase: "queued",
1511
+ request: {
1512
+ ...request,
1513
+ eligibleSettlement: Math.max(request.eligibleSettlement, settlementGeneration + 2)
1514
+ }
1515
+ } : { phase: "idle" });
1516
+ }, { once: true });
1517
+ }
1506
1518
  function requestHasCompactableHistory(ctx, keep) {
1507
1519
  return keep === null ? hasCompactableHistory(ctx) : keepBoundaryId(ctx.sessionManager.getBranch(), keep) !== undefined;
1508
1520
  }
@@ -1545,7 +1557,7 @@ function createGoosedumpIntegration(options = {}) {
1545
1557
  operation,
1546
1558
  sessionGeneration: generation,
1547
1559
  sessionFile,
1548
- hookActive: false
1560
+ hookClaimed: false
1549
1561
  });
1550
1562
  ctx.compact({
1551
1563
  onComplete: () => {
@@ -1564,6 +1576,17 @@ function createGoosedumpIntegration(options = {}) {
1564
1576
  });
1565
1577
  return true;
1566
1578
  }
1579
+ function deferQueuedCompaction(ctx) {
1580
+ if (compactionState.phase !== "queued")
1581
+ return;
1582
+ const request = compactionState.request;
1583
+ setImmediate(() => {
1584
+ if (compactionState.phase !== "queued" || compactionState.request !== request || !contextIsCurrent(ctx)) {
1585
+ return;
1586
+ }
1587
+ startQueuedCompaction(ctx);
1588
+ });
1589
+ }
1567
1590
  function requestCompaction(ctx, keep) {
1568
1591
  if (compactionState.phase !== "idle")
1569
1592
  return "busy";
@@ -1946,8 +1969,8 @@ ${lines.join(`
1946
1969
  if (compactionState.phase === "idle") {
1947
1970
  queueTurnCompaction(ctx, settlementGeneration);
1948
1971
  }
1949
- if (agentEndObserved && compactionState.phase === "queued" && compactionState.request.eligibleSettlement <= settlementGeneration) {
1950
- startQueuedCompaction(ctx);
1972
+ if (compactionState.phase === "queued" && compactionState.request.eligibleSettlement <= settlementGeneration) {
1973
+ deferQueuedCompaction(ctx);
1951
1974
  }
1952
1975
  }
1953
1976
  pi.on("session_start", async (_event, ctx) => {
@@ -1955,27 +1978,29 @@ ${lines.join(`
1955
1978
  settlementGeneration = 0;
1956
1979
  activeSessionFile = ctx.sessionManager.getSessionFile?.() ?? null;
1957
1980
  sessionActive = true;
1958
- agentEndObserved = true;
1959
1981
  compactionState = { phase: "idle" };
1960
1982
  goosedumpAvailable = checkGoosedump(ctx);
1961
1983
  notifyInvalidSettings(ctx);
1962
1984
  syncCompactCounters(ctx);
1963
1985
  updateStatus(ctx);
1964
1986
  queueTurnCompaction(ctx, 1);
1987
+ deferQueuedCompaction(ctx);
1965
1988
  });
1966
1989
  pi.on("session_shutdown", async () => {
1967
1990
  sessionGeneration += 1;
1968
1991
  settlementGeneration = 0;
1969
1992
  activeSessionFile = null;
1970
1993
  sessionActive = false;
1971
- agentEndObserved = true;
1972
1994
  compactionState = { phase: "idle" };
1973
1995
  });
1974
- pi.on("agent_start", async () => {
1975
- agentEndObserved = false;
1976
- });
1977
- pi.on("agent_end", async () => {
1978
- agentEndObserved = true;
1996
+ pi.on("agent_start", async (_event, ctx) => {
1997
+ if (compactionState.phase !== "running" || compactionState.owner !== "pi")
1998
+ return;
1999
+ const request = compactionState.request;
2000
+ setCompactionState(ctx, request && requestIsCurrent(request) ? {
2001
+ phase: "queued",
2002
+ request: { ...request, eligibleSettlement: settlementGeneration + 1 }
2003
+ } : { phase: "idle" });
1979
2004
  });
1980
2005
  pi.on("turn_end", async (event, ctx) => {
1981
2006
  if (isCompletedAssistant(event.message))
@@ -1987,15 +2012,8 @@ ${lines.join(`
1987
2012
  pi.on("session_before_compact", async (event, ctx) => {
1988
2013
  if (!shouldOverrideDefaultCompaction || !goosedumpAvailable)
1989
2014
  return;
1990
- if (event.customInstructions?.trim()) {
1991
- if (compactionState.phase === "running")
1992
- return { cancel: true };
1993
- if (compactionState.phase === "queued") {
1994
- setCompactionState(ctx, { phase: "idle" });
1995
- }
1996
- return;
1997
- }
1998
- if (event.signal.aborted) {
2015
+ const signal = event.signal;
2016
+ if (signal?.aborted) {
1999
2017
  if (compactionState.phase === "queued" && requestIsCurrent(compactionState.request)) {
2000
2018
  setCompactionState(ctx, event.reason === "manual" ? { phase: "idle" } : {
2001
2019
  phase: "queued",
@@ -2005,6 +2023,22 @@ ${lines.join(`
2005
2023
  }
2006
2024
  });
2007
2025
  }
2026
+ return { cancel: true };
2027
+ }
2028
+ if (event.customInstructions?.trim()) {
2029
+ if (compactionState.phase === "running")
2030
+ return { cancel: true };
2031
+ const operation2 = ++operationGeneration;
2032
+ setCompactionState(ctx, {
2033
+ phase: "running",
2034
+ request: null,
2035
+ owner: "pi",
2036
+ operation: operation2,
2037
+ sessionGeneration,
2038
+ sessionFile: activeSessionFile,
2039
+ hookClaimed: true
2040
+ });
2041
+ releasePiCompactionOnAbort(ctx, signal, operation2, sessionGeneration, activeSessionFile, null, event.reason);
2008
2042
  return;
2009
2043
  }
2010
2044
  let operation;
@@ -2013,7 +2047,7 @@ ${lines.join(`
2013
2047
  let request;
2014
2048
  let owner;
2015
2049
  if (compactionState.phase === "running") {
2016
- if (compactionState.hookActive || compactionState.owner === "pi") {
2050
+ if (compactionState.hookClaimed || compactionState.owner === "pi") {
2017
2051
  return { cancel: true };
2018
2052
  }
2019
2053
  operation = compactionState.operation;
@@ -2021,7 +2055,7 @@ ${lines.join(`
2021
2055
  sessionFile = compactionState.sessionFile;
2022
2056
  request = compactionState.request;
2023
2057
  owner = "extension";
2024
- compactionState = { ...compactionState, hookActive: true };
2058
+ compactionState = { ...compactionState, hookClaimed: true };
2025
2059
  } else {
2026
2060
  request = compactionState.phase === "queued" && requestIsCurrent(compactionState.request) ? compactionState.request : null;
2027
2061
  operation = ++operationGeneration;
@@ -2035,9 +2069,12 @@ ${lines.join(`
2035
2069
  operation,
2036
2070
  sessionGeneration: generation,
2037
2071
  sessionFile,
2038
- hookActive: true
2072
+ hookClaimed: true
2039
2073
  });
2040
2074
  }
2075
+ if (owner === "pi") {
2076
+ releasePiCompactionOnAbort(ctx, signal, operation, generation, sessionFile, request, event.reason);
2077
+ }
2041
2078
  try {
2042
2079
  const { messagesToSummarize, turnPrefixMessages } = event.preparation;
2043
2080
  if ((request?.keep ?? null) === null && messagesToSummarize.length === 0 && turnPrefixMessages.length === 0) {
@@ -2061,11 +2098,11 @@ ${lines.join(`
2061
2098
  operation,
2062
2099
  sessionGeneration: generation,
2063
2100
  sessionFile,
2064
- hookActive: true
2101
+ hookClaimed: true
2065
2102
  });
2066
2103
  }
2067
2104
  }
2068
- const compaction = await buildGoosedumpCompaction(target, event.preparation, event.branchEntries, effectiveSummaryMaxTokens(ctx.cwd, projectSettingsTrusted(ctx)), keep, event.signal, nativeExecutablePath);
2105
+ const compaction = await buildGoosedumpCompaction(target, event.preparation, event.branchEntries, effectiveSummaryMaxTokens(ctx.cwd, projectSettingsTrusted(ctx)), keep, signal, nativeExecutablePath);
2069
2106
  if (!runningOperationIsCurrent(operation, generation, sessionFile)) {
2070
2107
  return { cancel: true };
2071
2108
  }
@@ -2085,8 +2122,12 @@ ${lines.join(`
2085
2122
  if (!runningOperationIsCurrent(operation, generation, sessionFile)) {
2086
2123
  return { cancel: true };
2087
2124
  }
2088
- if (event.signal.aborted)
2125
+ if (signal?.aborted) {
2126
+ if (owner === "pi" && event.reason === "manual") {
2127
+ setCompactionState(ctx, { phase: "idle" });
2128
+ }
2089
2129
  return { cancel: true };
2130
+ }
2090
2131
  if (ctx.hasUI) {
2091
2132
  const message = err instanceof Error ? err.message : String(err);
2092
2133
  ctx.ui.notify(`goosedump compaction failed; falling back to Pi compaction: ${message}`, "error");
@@ -2094,14 +2135,14 @@ ${lines.join(`
2094
2135
  return;
2095
2136
  } finally {
2096
2137
  if (runningOperationIsCurrent(operation, generation, sessionFile)) {
2097
- setCompactionState(ctx, owner === "pi" && event.reason === "manual" ? { phase: "idle" } : {
2138
+ setCompactionState(ctx, {
2098
2139
  phase: "running",
2099
2140
  request,
2100
2141
  owner,
2101
2142
  operation,
2102
2143
  sessionGeneration: generation,
2103
2144
  sessionFile,
2104
- hookActive: false
2145
+ hookClaimed: true
2105
2146
  });
2106
2147
  }
2107
2148
  }
@@ -2114,7 +2155,9 @@ ${lines.join(`
2114
2155
  if (compactionState.phase === "queued" && compactionState.request.keep !== null && ctx.hasUI) {
2115
2156
  ctx.ui.notify("Queued keep request was superseded by another compaction.", "info");
2116
2157
  }
2117
- compactionState = { phase: "idle" };
2158
+ const extensionOwned = compactionState.phase === "running" && compactionState.owner === "extension";
2159
+ if (!extensionOwned)
2160
+ compactionState = { phase: "idle" };
2118
2161
  syncCompactCounters(ctx);
2119
2162
  updateStatus(ctx);
2120
2163
  if (!goosedumpAvailable)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goosedump",
3
- "version": "0.12.16",
3
+ "version": "0.12.17",
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.16",
41
+ "@jarkkojs/goosedump": "^0.12.17",
42
42
  "@sinclair/typebox": "^0.34.49"
43
43
  },
44
44
  "devDependencies": {