@pi-unipi/ralph 2.4.0 → 2.4.2

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 (3) hide show
  1. package/index.ts +10 -5
  2. package/package.json +3 -3
  3. package/ralph-loop.ts +10 -0
package/index.ts CHANGED
@@ -145,8 +145,11 @@ export default function (pi: ExtensionAPI) {
145
145
  }
146
146
  });
147
147
 
148
- // Inject ralph instructions when loop is active
149
- pi.on("before_agent_start", async (event, ctx) => {
148
+ // Inject ralph instructions when loop is active.
149
+ // NOTE: injected as a hidden tail message (not the system prompt) so the
150
+ // cacheable prefix (system prompt + prior history) stays byte-stable across
151
+ // turns. The iteration number changes every turn and must never touch the prefix.
152
+ pi.on("before_agent_start", async (_event, ctx) => {
150
153
  const mgr = getManager(ctx, pi);
151
154
  const currentLoop = mgr.getCurrentLoop();
152
155
  if (!currentLoop) return;
@@ -165,9 +168,11 @@ export default function (pi: ExtensionAPI) {
165
168
  instructions += `- Otherwise, call ralph_done tool to proceed to next iteration`;
166
169
 
167
170
  return {
168
- systemPrompt:
169
- event.systemPrompt +
170
- `\n[RALPH LOOP - ${state.name} - Iteration ${iterStr}]\n\n${instructions}`,
171
+ message: {
172
+ customType: "unipi-ralph-loop-reminder",
173
+ content: `[RALPH LOOP - ${state.name} - Iteration ${iterStr}]\n\n${instructions}`,
174
+ display: false,
175
+ },
171
176
  };
172
177
  });
173
178
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/ralph",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "Long-running iterative development loops for Pi coding agent",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -27,8 +27,8 @@
27
27
  "access": "public"
28
28
  },
29
29
  "dependencies": {
30
- "@pi-unipi/core": "2.4.0",
31
- "@pi-unipi/info-screen": "2.4.0"
30
+ "@pi-unipi/core": "2.4.1",
31
+ "@pi-unipi/info-screen": "2.4.1"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@earendil-works/pi-ai": "^0.80.0",
package/ralph-loop.ts CHANGED
@@ -374,6 +374,8 @@ export class RalphLoopManager {
374
374
  return null;
375
375
  }
376
376
 
377
+ this.emitIterationDone(state);
378
+
377
379
  const needsReflection =
378
380
  state.reflectEvery > 0 && (state.iteration - 1) % state.reflectEvery === 0;
379
381
  if (needsReflection) state.lastReflectionAt = state.iteration;
@@ -384,6 +386,14 @@ export class RalphLoopManager {
384
386
  return { state, needsReflection };
385
387
  }
386
388
 
389
+ private emitIterationDone(state: LoopState): void {
390
+ this.emitFn(UNIPI_EVENTS.RALPH_ITERATION_DONE, {
391
+ name: state.name,
392
+ iteration: state.iteration - 1,
393
+ nextIteration: state.iteration,
394
+ });
395
+ }
396
+
387
397
  archiveLoop(name: string): boolean {
388
398
  const state = this.loadState(name);
389
399
  if (!state) return false;