pi-posthorse 0.10.14 → 0.10.16

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 CHANGED
@@ -35,6 +35,8 @@ See the [changelog](https://github.com/fitchmultz/pi-posthorse/blob/main/CHANGEL
35
35
 
36
36
  Recoverable history is not guaranteed model recall. See the [practical guarantees and limits](https://github.com/fitchmultz/pi-posthorse/blob/main/docs/context-recovery.md) for the stock-Pi comparison, search scope, checkpoints, privacy, concurrency and cost, or the [rollover reference](https://github.com/fitchmultz/pi-posthorse/blob/main/docs/reference.md#how-it-works) for implementation details.
37
37
 
38
+ The [field study](https://github.com/fitchmultz/pi-posthorse/blob/main/docs/field-study.md) measures what agents did around 24,940 context boundaries in daily use: note and history use, repeated work, stops, wait time, and cost. It is observational, not a controlled comparison with stock compaction.
39
+
38
40
  ## Tools
39
41
 
40
42
  These tools are available to the model:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-posthorse",
3
- "version": "0.10.14",
3
+ "version": "0.10.16",
4
4
  "type": "module",
5
5
  "description": "Posthorse: fresh context, same journey. No-summary context rollover for Pi, with sparse budget reminders, handoffs, notes, and history.",
6
6
  "keywords": [
package/src/reminders.ts CHANGED
@@ -231,10 +231,8 @@ function countRetainedFromProjected(
231
231
  continue;
232
232
  }
233
233
  for (const msg of item.messages) {
234
- const role = msg.role ?? "";
235
234
  if (
236
- role !== "system" &&
237
- !stale({ role, customType: msg.customType, details: msg.details })
235
+ !stale({ role: msg.role ?? "", customType: msg.customType, details: msg.details })
238
236
  ) {
239
237
  count += 1;
240
238
  }
package/src/rollover.ts CHANGED
@@ -113,22 +113,6 @@ function staleReminderPredicate(
113
113
  isReminderType(message.customType) &&
114
114
  (!enabled || !reminderMatches(message.details, fingerprint));
115
115
  }
116
- function retainedTailEnd(
117
- messages: ContextWithSystemEvent["messages"],
118
- start: number,
119
- count: number,
120
- ): number | undefined {
121
- let remaining = count;
122
- for (let index = start; index < messages.length; index += 1) {
123
- if (messages[index]?.role !== "system") {
124
- remaining -= 1;
125
- }
126
- if (remaining === 0) {
127
- return index + 1;
128
- }
129
- }
130
- return undefined;
131
- }
132
116
  function chronologicalRetainedTail(
133
117
  messages: ContextWithSystemEvent["messages"],
134
118
  ctx: ExtensionContext,
@@ -137,9 +121,12 @@ function chronologicalRetainedTail(
137
121
  const summaryIndex = messages.findIndex((message) => message.role !== "system");
138
122
  const first = messages[summaryIndex];
139
123
  if (first?.role === "compactionSummary" && hasRetainedRolloverMarker(first.summary)) {
124
+ // Pi projects no system messages into the retained tail, but an earlier handler can
125
+ // present a retained message as one (pi-change-working-dir's directory snapshots).
126
+ // Count positions, not roles, so the record never lands inside the next tool batch.
140
127
  const count = countRetainedMessages(ctx, stale);
141
- const end = count > 0 ? retainedTailEnd(messages, summaryIndex + 1, count) : undefined;
142
- if (end !== undefined) {
128
+ const end = summaryIndex + 1 + count;
129
+ if (count > 0 && end <= messages.length) {
143
130
  const prefix = messages.slice(0, summaryIndex);
144
131
  const retainedSlice = messages.slice(summaryIndex + 1, end);
145
132
  const afterSlice = messages.slice(end);