pi: asynchronous exit summaries Pi, a terminal-based AI assistant, now exits instantly on Ctrl+D instead of waiting several seconds for a session summary, after developer Thiago Perrotta forked the pi-memory package into pi-memory-async. The fix writes a durable JSON job synchronously during shutdown and processes it asynchronously in the next session, eliminating the blocking LLM request and qmd update. The change preserves the original daily log entry while keeping the upstream package intact. ♠ Problem statement : ctrl+d in pi https://github.com/earendil-works/pi took several seconds to quit. The culprit was pi-memory https://www.npmjs.com/package/pi-memory ’s session shutdown handler. It sent one last LLM request to summarize the session, wrote its answer to the daily log, then ran qmd update . Pi awaits all shutdown handlers, correctly, so quitting waited for everything: js pi.on "session shutdown", async event, ctx = { const result = await generateExitSummary ctx ; fs.writeFileSync filePath, entry, "utf-8" ; await runQmdUpdateNow ; } ; Making that promise fire-and-forget would not work: Pi exits immediately after shutdown, and either the in-flight request keeps Node alive or gets killed before it can write anything. Instead, I made the shutdown path write a durable job, synchronously: js const job: ExitSummaryJob = { version: 1, id: randomUUID , createdAt: new Date .toISOString , date: todayStr , reason, sessionId: shortSessionId ctx.sessionManager.getSessionId , conversationText: truncated.text, truncated: truncated.truncated, totalChars: truncated.totalChars, }; const jobPath = path.join EXIT SUMMARY JOBS DIR, ${job.createdAt.replace / :. /g, "-" }-${job.id}.json , ; fs.writeFileSync jobPath, ${JSON.stringify job }\n , { encoding: "utf-8", flag: "wx" } ; The next interactive session starts an unref’ed worker. It atomically renames one job to claim it, generates summary with active model, writes it back to original day’s daily log, and deletes job. Failed jobs return to queue. A stale claimed job retries after ten minutes. I kept upstream package intact by replacing it with a local package, effectively forking it: % pi remove npm:pi-memory Removed npm:pi-memory % pi install ~/.pi/agent/local/pi-memory-async Installed /Users/thiago.perrotta/.pi/agent/local/pi-memory-async % pi list User packages: local/pi-memory-async /Users/thiago.perrotta/.pi/agent/local/pi-memory-async Jobs live in ~/.pi/agent/memory/exit-summary-jobs/ . ctrl+d only writes one JSON file now; summary happens during next session, without blocking exits. Source code : pi-memory-async https://github.com/thiagowfx/.dotfiles/tree/1f175b77a960a460b4e5cc677d6d6390e0cc0530/pi/.pi/agent/local/pi-memory-async . 🤖 Drafted with /bloggify .— § — Reply via email mailto:serendipity@perrotta.dev?subject=Reply to: pi: asynchronous exit summaries