my-durable 0.0.0-stage → 0.0.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 (259) hide show
  1. package/.env.example +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +328 -2
  4. package/ai_docs/durable_pi/announcement.md +860 -0
  5. package/ai_docs/durable_pi/changelog.md +51 -0
  6. package/ai_docs/durable_pi/chord-delta-findings.md +362 -0
  7. package/ai_docs/durable_pi/coding-agent-integration.md +70 -0
  8. package/ai_docs/durable_pi/pico-v5-chord-usage.md +391 -0
  9. package/ai_docs/durable_pi/pico-v5-handoff.md +921 -0
  10. package/ai_docs/durable_pi/readme.md +617 -0
  11. package/ai_docs/durable_pi/sources.md +22 -0
  12. package/ai_docs/durable_pi/spec.md +4696 -0
  13. package/ai_docs/durable_pi/vacation-planner.md +57 -0
  14. package/ai_docs/pi/chord.md +268 -0
  15. package/ai_docs/pi/cli-integration.md +110 -0
  16. package/ai_docs/pi/cli.md +325 -0
  17. package/ai_docs/pi/codemode.md +211 -0
  18. package/ai_docs/pi/compaction.md +467 -0
  19. package/ai_docs/pi/configuration.md +51 -0
  20. package/ai_docs/pi/containerization.md +187 -0
  21. package/ai_docs/pi/custom-provider.md +177 -0
  22. package/ai_docs/pi/environment-variables.md +102 -0
  23. package/ai_docs/pi/extensions.md +278 -0
  24. package/ai_docs/pi/how-pi-works.md +53 -0
  25. package/ai_docs/pi/index.md +43 -0
  26. package/ai_docs/pi/json.md +230 -0
  27. package/ai_docs/pi/keybindings.md +198 -0
  28. package/ai_docs/pi/llama-cpp.md +118 -0
  29. package/ai_docs/pi/mcp.md +274 -0
  30. package/ai_docs/pi/message-types.md +265 -0
  31. package/ai_docs/pi/models.md +209 -0
  32. package/ai_docs/pi/overview.md +166 -0
  33. package/ai_docs/pi/packages.md +133 -0
  34. package/ai_docs/pi/pi-agent-core.md +568 -0
  35. package/ai_docs/pi/pi-ai.md +1942 -0
  36. package/ai_docs/pi/prompt-templates.md +63 -0
  37. package/ai_docs/pi/providers.md +204 -0
  38. package/ai_docs/pi/quickstart.md +140 -0
  39. package/ai_docs/pi/readme.md +99 -0
  40. package/ai_docs/pi/rpc-commands.md +864 -0
  41. package/ai_docs/pi/rpc-extension-ui.md +204 -0
  42. package/ai_docs/pi/rpc.md +197 -0
  43. package/ai_docs/pi/sdk.md +151 -0
  44. package/ai_docs/pi/security.md +103 -0
  45. package/ai_docs/pi/session-format.md +297 -0
  46. package/ai_docs/pi/sessions.md +70 -0
  47. package/ai_docs/pi/settings.md +173 -0
  48. package/ai_docs/pi/shell-aliases.md +97 -0
  49. package/ai_docs/pi/skills.md +97 -0
  50. package/ai_docs/pi/slash-commands.md +64 -0
  51. package/ai_docs/pi/sources.md +57 -0
  52. package/ai_docs/pi/terminal-setup.md +223 -0
  53. package/ai_docs/pi/termux.md +121 -0
  54. package/ai_docs/pi/themes.md +140 -0
  55. package/ai_docs/pi/tmux.md +59 -0
  56. package/ai_docs/pi/toolkit.md +168 -0
  57. package/ai_docs/pi/tui.md +129 -0
  58. package/ai_docs/pi/usage.md +98 -0
  59. package/ai_docs/pi/virtual-models.md +118 -0
  60. package/ai_docs/pi/windows.md +71 -0
  61. package/apps/dpi-backend/.nvmrc +1 -0
  62. package/apps/dpi-backend/API.md +99 -0
  63. package/apps/dpi-backend/README.md +119 -0
  64. package/apps/dpi-backend/deploy/backend.env.example +9 -0
  65. package/apps/dpi-backend/deploy/dpi-backend.plist +26 -0
  66. package/apps/dpi-backend/deploy/dpi-backend.service +22 -0
  67. package/apps/dpi-backend/package.json +33 -0
  68. package/apps/dpi-backend/prompts/one_sentence.md +3 -0
  69. package/apps/dpi-backend/prompts/smart_ass_opus_fix.md +169 -0
  70. package/apps/dpi-backend/scripts/check-contract.mjs +151 -0
  71. package/apps/dpi-backend/scripts/migrate-playground.ts +66 -0
  72. package/apps/dpi-backend/scripts/record-nested-fixture.mts +154 -0
  73. package/apps/dpi-backend/scripts/token.ts +57 -0
  74. package/apps/dpi-backend/src/addons.ts +139 -0
  75. package/apps/dpi-backend/src/auth.ts +20 -0
  76. package/apps/dpi-backend/src/config.ts +54 -0
  77. package/apps/dpi-backend/src/contract-check.ts +118 -0
  78. package/apps/dpi-backend/src/errors.ts +50 -0
  79. package/apps/dpi-backend/src/extensions.ts +510 -0
  80. package/apps/dpi-backend/src/faux.ts +80 -0
  81. package/apps/dpi-backend/src/history.ts +165 -0
  82. package/apps/dpi-backend/src/idempotency.ts +20 -0
  83. package/apps/dpi-backend/src/jev.ts +43 -0
  84. package/apps/dpi-backend/src/jobs.ts +790 -0
  85. package/apps/dpi-backend/src/main.ts +76 -0
  86. package/apps/dpi-backend/src/model-catalog.ts +180 -0
  87. package/apps/dpi-backend/src/pairing-files.ts +142 -0
  88. package/apps/dpi-backend/src/pairing.ts +459 -0
  89. package/apps/dpi-backend/src/routes.ts +217 -0
  90. package/apps/dpi-backend/src/shared-state.ts +85 -0
  91. package/apps/dpi-backend/src/store.ts +1240 -0
  92. package/apps/dpi-backend/src/streams.ts +256 -0
  93. package/apps/dpi-backend/src/tunnel.ts +955 -0
  94. package/apps/dpi-backend/tsconfig.json +13 -0
  95. package/apps/dpi-playground/README.md +83 -0
  96. package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-CFGc7lHT.js +77 -0
  97. package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-DFdKpwm_.css +1 -0
  98. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/anthropic.png +0 -0
  99. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/deepseek.png +0 -0
  100. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/durable-pi.svg +14 -0
  101. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/gemini.png +0 -0
  102. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/grok.png +0 -0
  103. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/kimi.png +0 -0
  104. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/lab.png +0 -0
  105. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/meta.png +0 -0
  106. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/minimax.png +0 -0
  107. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/openai.png +0 -0
  108. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/qwen.png +0 -0
  109. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/xiaomi.png +0 -0
  110. package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/zai.png +0 -0
  111. package/apps/dpi-playground/apps/dpi-playground-fe/dist/index.html +16 -0
  112. package/apps/dpi-playground/apps/dpi-playground-fe/index.html +15 -0
  113. package/apps/dpi-playground/apps/dpi-playground-fe/package.json +5 -0
  114. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/anthropic.png +0 -0
  115. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/deepseek.png +0 -0
  116. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/durable-pi.svg +14 -0
  117. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/gemini.png +0 -0
  118. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/grok.png +0 -0
  119. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/kimi.png +0 -0
  120. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/lab.png +0 -0
  121. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/meta.png +0 -0
  122. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/minimax.png +0 -0
  123. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/openai.png +0 -0
  124. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/qwen.png +0 -0
  125. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/xiaomi.png +0 -0
  126. package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/zai.png +0 -0
  127. package/apps/dpi-playground/apps/dpi-playground-fe/src/App.vue +180 -0
  128. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/commands.ts +119 -0
  129. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/composables.ts +129 -0
  130. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/hub.ts +40 -0
  131. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/icon-path.ts +7 -0
  132. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/ids.ts +2 -0
  133. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/jobs.ts +80 -0
  134. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/link-policy.ts +16 -0
  135. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/markdown-policy.ts +115 -0
  136. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/markdown.ts +60 -0
  137. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/pair-close.ts +23 -0
  138. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/pair-handoff.ts +56 -0
  139. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/pair.ts +166 -0
  140. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/qrcode.ts +323 -0
  141. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/signature.ts +146 -0
  142. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/store.ts +373 -0
  143. package/apps/dpi-playground/apps/dpi-playground-fe/src/client/stream.ts +183 -0
  144. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/AgentView.vue +342 -0
  145. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/Composer.vue +198 -0
  146. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/ContextBar.vue +254 -0
  147. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/DeviceCredentialsDialog.vue +40 -0
  148. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/DeviceIcon.vue +56 -0
  149. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/DirBrowser.vue +95 -0
  150. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/ExtensionsPanel.vue +96 -0
  151. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/HelpDialog.vue +69 -0
  152. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/Inspector.vue +425 -0
  153. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/JobCard.vue +221 -0
  154. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/MobileNav.vue +39 -0
  155. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/ModelPicker.vue +71 -0
  156. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/NetworkSidebar.vue +236 -0
  157. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/NewSessionDialog.vue +114 -0
  158. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/OfflinePanel.vue +128 -0
  159. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/PairDeviceWizard.vue +433 -0
  160. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/PromptDialog.vue +89 -0
  161. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/StateEditor.vue +179 -0
  162. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TasksPanel.vue +280 -0
  163. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/Toast.vue +11 -0
  164. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TokenManager.vue +175 -0
  165. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TopBar.vue +114 -0
  166. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TranscriptItem.vue +152 -0
  167. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TreeRow.vue +195 -0
  168. package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TunnelStatusBar.vue +107 -0
  169. package/apps/dpi-playground/apps/dpi-playground-fe/src/extensions.css +105 -0
  170. package/apps/dpi-playground/apps/dpi-playground-fe/src/jobs.css +655 -0
  171. package/apps/dpi-playground/apps/dpi-playground-fe/src/main.ts +22 -0
  172. package/apps/dpi-playground/apps/dpi-playground-fe/src/network.css +675 -0
  173. package/apps/dpi-playground/apps/dpi-playground-fe/src/style.css +3203 -0
  174. package/apps/dpi-playground/apps/dpi-playground-fe/tsconfig.json +16 -0
  175. package/apps/dpi-playground/apps/dpi-playground-fe/vite.config.ts +14 -0
  176. package/apps/dpi-playground/apps/dpi-playground-hub/package.json +5 -0
  177. package/apps/dpi-playground/apps/dpi-playground-hub/src/audit.ts +406 -0
  178. package/apps/dpi-playground/apps/dpi-playground-hub/src/client-ip.ts +72 -0
  179. package/apps/dpi-playground/apps/dpi-playground-hub/src/credentials.ts +265 -0
  180. package/apps/dpi-playground/apps/dpi-playground-hub/src/guard.ts +43 -0
  181. package/apps/dpi-playground/apps/dpi-playground-hub/src/http-errors.ts +156 -0
  182. package/apps/dpi-playground/apps/dpi-playground-hub/src/identity.ts +60 -0
  183. package/apps/dpi-playground/apps/dpi-playground-hub/src/limiter.ts +165 -0
  184. package/apps/dpi-playground/apps/dpi-playground-hub/src/main.ts +460 -0
  185. package/apps/dpi-playground/apps/dpi-playground-hub/src/monitor.ts +320 -0
  186. package/apps/dpi-playground/apps/dpi-playground-hub/src/mux.ts +277 -0
  187. package/apps/dpi-playground/apps/dpi-playground-hub/src/pairing.ts +816 -0
  188. package/apps/dpi-playground/apps/dpi-playground-hub/src/proxy.ts +128 -0
  189. package/apps/dpi-playground/apps/dpi-playground-hub/src/rotation.ts +583 -0
  190. package/apps/dpi-playground/apps/dpi-playground-hub/src/seed.ts +11 -0
  191. package/apps/dpi-playground/apps/dpi-playground-hub/src/transport.ts +108 -0
  192. package/apps/dpi-playground/apps/dpi-playground-hub/src/tunnel-token.ts +11 -0
  193. package/apps/dpi-playground/apps/dpi-playground-hub/src/tunnel-transport.ts +560 -0
  194. package/apps/dpi-playground/apps/dpi-playground-hub/src/tunnel.ts +873 -0
  195. package/apps/dpi-playground/apps/dpi-playground-hub/tsconfig.json +13 -0
  196. package/apps/dpi-playground/package.json +37 -0
  197. package/apps/dpi-sdk/README.md +74 -0
  198. package/apps/dpi-sdk/package.json +20 -0
  199. package/apps/dpi-sdk/scripts/net.ts +73 -0
  200. package/apps/dpi-sdk/src/api.ts +631 -0
  201. package/apps/dpi-sdk/src/app-state.ts +111 -0
  202. package/apps/dpi-sdk/src/client.ts +330 -0
  203. package/apps/dpi-sdk/src/errors.ts +16 -0
  204. package/apps/dpi-sdk/src/jobs.ts +99 -0
  205. package/apps/dpi-sdk/src/models.ts +472 -0
  206. package/apps/dpi-sdk/src/node/chunk.ts +488 -0
  207. package/apps/dpi-sdk/src/node/config.ts +175 -0
  208. package/apps/dpi-sdk/src/node/drivers.ts +402 -0
  209. package/apps/dpi-sdk/src/node/ops.ts +114 -0
  210. package/apps/dpi-sdk/src/node/private-dir.ts +48 -0
  211. package/apps/dpi-sdk/src/node/registry-migration.ts +549 -0
  212. package/apps/dpi-sdk/src/node/registry.ts +390 -0
  213. package/apps/dpi-sdk/src/node/sse-writer.ts +151 -0
  214. package/apps/dpi-sdk/src/protocol/backoff.ts +31 -0
  215. package/apps/dpi-sdk/src/protocol/limits.ts +199 -0
  216. package/apps/dpi-sdk/src/protocol/pairing.ts +311 -0
  217. package/apps/dpi-sdk/src/protocol/rest-routes.ts +105 -0
  218. package/apps/dpi-sdk/src/protocol/tunnel.ts +331 -0
  219. package/apps/dpi-sdk/src/sse.ts +117 -0
  220. package/apps/dpi-sdk/src/transcript.ts +291 -0
  221. package/apps/dpi-sdk/tsconfig.json +13 -0
  222. package/apps/dpi-sdk/w +20 -0
  223. package/apps/dpi-tui/README.md +54 -0
  224. package/apps/dpi-tui/bin/dpi-tui.mjs +5 -0
  225. package/apps/dpi-tui/package.json +20 -0
  226. package/apps/dpi-tui/src/app.ts +433 -0
  227. package/apps/dpi-tui/src/commands.ts +151 -0
  228. package/apps/dpi-tui/src/main.ts +122 -0
  229. package/apps/dpi-tui/src/pairing.ts +287 -0
  230. package/apps/dpi-tui/src/pickers.ts +238 -0
  231. package/apps/dpi-tui/src/render.ts +164 -0
  232. package/apps/dpi-tui/src/theme.ts +57 -0
  233. package/apps/dpi-tui/tsconfig.json +14 -0
  234. package/bin/device.mjs +5 -0
  235. package/bin/hub.mjs +5 -0
  236. package/bin/tui.mjs +5 -0
  237. package/deploy/Caddyfile +120 -0
  238. package/docs/verification.md +102 -0
  239. package/dpi-network.example.yaml +62 -0
  240. package/images/01_durable_agent_network.svg +185 -0
  241. package/images/02_pi_made_durable.svg +204 -0
  242. package/images/03_restart_mid_tool.svg +168 -0
  243. package/images/07_one_api_every_client.svg +123 -0
  244. package/images/08_device_session_agent.svg +123 -0
  245. package/images/09_compact_keep_history.svg +143 -0
  246. package/images/10_shared_app_state.svg +177 -0
  247. package/images/11_durable_jobs_wait.svg +141 -0
  248. package/images/12_tools_change_mid_run.svg +231 -0
  249. package/images/13_hook_blocks_tool.svg +122 -0
  250. package/images/14_fork_at_any_entry.svg +119 -0
  251. package/images/15_web_client.png +0 -0
  252. package/images/16_terminal_client.svg +43 -0
  253. package/images/17_devices_are_data.svg +182 -0
  254. package/images/18_should_every_agent_be_durable.svg +118 -0
  255. package/images/19_sqlite_on_every_device.svg +155 -0
  256. package/images/20_admission_and_effects.svg +134 -0
  257. package/justfile +33 -0
  258. package/package.json +41 -4
  259. package/scripts/verify.mjs +210 -0
@@ -0,0 +1,467 @@
1
+ > Source: [packages/coding-agent/docs/compaction.md](https://github.com/earendil-works/pi/blob/b78e6a9085343ec0f308c3d377da72528b4cf7ee/packages/coding-agent/docs/compaction.md)
2
+ > Retrieved with Firecrawl: 2026-10-05. Repository snapshot: `b78e6a9085343ec0f308c3d377da72528b4cf7ee`.
3
+ > Relative documentation links point to local copies where available, otherwise to the source snapshot.
4
+
5
+ # Compaction Reference
6
+
7
+ This reference describes automatic compaction, branch summarization, persisted entries, and extension hooks. For the user workflow, see [Sessions and Context](sessions.md#manage-conversation-context).
8
+
9
+ **Source files** ([pi](https://github.com/earendil-works/pi)):
10
+ - [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) - Auto-compaction logic
11
+ - [`packages/coding-agent/src/core/compaction/branch-summarization.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) - Branch summarization
12
+ - [`packages/coding-agent/src/core/compaction/utils.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/utils.ts) - Shared utilities (file tracking, serialization)
13
+ - [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/session-manager.ts) - Entry types (`CompactionEntry`, `BranchSummaryEntry`)
14
+ - [`packages/coding-agent/src/core/extensions/types.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/extensions/types.ts) - Extension event types
15
+
16
+ For TypeScript definitions in your project, inspect `node_modules/@earendil-works/pi-coding-agent/dist/`.
17
+
18
+ ## Overview
19
+
20
+ Pi has two summarization mechanisms:
21
+
22
+ | Mechanism | Trigger | Purpose |
23
+ |-----------|---------|---------|
24
+ | Compaction | Context exceeds threshold, or `/compact` | Summarize old messages to free up context |
25
+ | Branch summarization | `/tree` navigation | Preserve context when switching branches |
26
+
27
+ Both use closely related structured formats and track file operations cumulatively. Summarization requests disable prompt-cache writes because these one-off prompts are unlikely to be reused.
28
+
29
+ ## Compaction
30
+
31
+ ### When It Triggers
32
+
33
+ Auto-compaction triggers when:
34
+
35
+ ```
36
+ contextTokens > contextWindow - reserveTokens
37
+ ```
38
+
39
+ By default, `reserveTokens` is 16384 tokens (configurable in `~/.pi/agent/settings.json` or `<project-dir>/.pi/settings.json`). This leaves room for the LLM's response.
40
+
41
+ During a multi-turn agent run, Pi checks the canonical projected context after tools finish and their results are appended, before starting the next assistant response. If the threshold is crossed, Pi compacts during `prepareNextTurn`, then performs the existing catch-up steering poll before `turn_start`. It skips this between-turn check when the completed tool batch terminates the run and no queued message requires another response. Pi also checks before a new user prompt and performs final-attempt overflow recovery after the low-level run ends.
42
+
43
+ A provider context-overflow error or an early final `stopReason: "length"` can select one compact-and-retry recovery attempt. Length responses with tool calls retain their synthetic failed tool results and follow the ordinary tool/queue scheduler rather than forcing the run to end.
44
+
45
+ You can also trigger manually with `/compact [instructions]`, where optional instructions focus the summary.
46
+
47
+ ### How It Works
48
+
49
+ 1. **Find cut point**: Walk backwards through the finalized session projection, accumulating token estimates until `keepRecentTokens` (default 20k, configurable in `~/.pi/agent/settings.json` or `<project-dir>/.pi/settings.json`) is reached
50
+ 2. **Extract messages**: Collect projected messages from the previous kept boundary (or session start) up to the cut point
51
+ 3. **Generate summary**: Call LLM to summarize with structured format, passing the previous summary as iterative context when present
52
+ 4. **Append entry**: Save `CompactionEntry` with summary and `firstKeptEntryId`
53
+ 5. **Rebuilds context**: Session rebuilds the context for the next request, using summary + messages from `firstKeptEntryId` onwards
54
+
55
+ ```
56
+ Before compaction:
57
+
58
+ entry: 0 1 2 3 4 5 6 7 8 9
59
+ ┌─────┬─────┬─────┬──────┬─────┬─────┬──────┬──────┬─────┬─────┐
60
+ │ hdr │ usr │ ass │ tool │ usr │ ass │ tool │ tool │ ass │ tool│
61
+ └─────┴─────┴─────┴──────┴─────┴─────┴──────┴──────┴─────┴─────┘
62
+ └────────┬───────┘ └──────────────┬──────────────┘
63
+ messagesToSummarize kept messages
64
+ ↑
65
+ firstKeptEntryId (entry 4)
66
+
67
+ After compaction (new entry appended):
68
+
69
+ entry: 0 1 2 3 4 5 6 7 8 9 10
70
+ ┌─────┬─────┬─────┬──────┬─────┬─────┬──────┬──────┬─────┬─────┬─────┐
71
+ │ hdr │ usr │ ass │ tool │ usr │ ass │ tool │ tool │ ass │ tool│ cmp │
72
+ └─────┴─────┴─────┴──────┴─────┴─────┴──────┴──────┴─────┴─────┴─────┘
73
+ └──────────┬──────┘ └──────────────────────┬───────────────────┘
74
+ not sent to LLM sent to LLM
75
+ ↑
76
+ starts from firstKeptEntryId
77
+
78
+ What the LLM sees:
79
+
80
+ ┌────────┬─────────┬─────┬─────┬──────┬──────┬─────┬──────┐
81
+ │ system │ summary │ usr │ ass │ tool │ tool │ ass │ tool │
82
+ └────────┴─────────┴─────┴─────┴──────┴──────┴─────┴──────┘
83
+ ↑ ↑ └─────────────────┬────────────────┘
84
+ prompt from cmp messages from firstKeptEntryId
85
+ ```
86
+
87
+ On repeated compactions, the summarized span starts at the previous compaction's kept boundary (`firstKeptEntryId`), not at the compaction entry itself, falling back to the entry after the previous compaction if that kept entry cannot be found in the path. A retain-none compaction records its own ID as `firstKeptEntryId`; repeated compaction starts after that entry. This preserves messages that survived the earlier compaction by including them in the next summarization pass as well. Pi also recalculates `tokensBefore` from the rebuilt, context-edited session projection before writing the new `CompactionEntry`, so the token count reflects the actual pre-compaction context being replaced. Omitted raw entries remain stored but do not affect cut selection, summaries, checkpoints, or token estimates.
88
+
89
+ ### Overflow and Length Recovery Ordering
90
+
91
+ Recovery preserves the existing lifecycle and queue order. The completed attempt remains visible to `turn_end` and `agent_end`; post-run recovery then repairs persisted model context before a fresh retry:
92
+
93
+ ```text
94
+ persist final assistant response
95
+ → extension/public turn_end
96
+ → extension/public agent_end
97
+ → append context_edit omissions for the selected attempt
98
+ → for overflow/length: run session_before_compact and append compaction on success
99
+ → start the retry as a fresh run
100
+ ```
101
+
102
+ If recovery compaction fails or is cancelled, Pi keeps the omission edits, appends no compaction, and schedules no internal retry. Existing queued work remains governed by ordinary steering and follow-up rules. `agent_before_settle` sees the repaired projection after recovery processing. Raw transcript history, exports, billing totals, and history-search extensions can still inspect the omitted attempt.
103
+
104
+ ### Split user-message spans
105
+
106
+ A user-message span starts with a user message and includes all turns until the next user message. Normally, compaction cuts at user-message boundaries.
107
+
108
+ When one user-message span exceeds `keepRecentTokens`, the cut point lands within that span at an assistant message. This is a split user-message span:
109
+
110
+ ```
111
+ Split user-message span (one span exceeds budget):
112
+
113
+ entry: 0 1 2 3 4 5 6 7 8
114
+ ┌─────┬─────┬─────┬──────┬─────┬──────┬──────┬─────┬──────┐
115
+ │ hdr │ usr │ ass │ tool │ ass │ tool │ tool │ ass │ tool │
116
+ └─────┴─────┴─────┴──────┴─────┴──────┴──────┴─────┴──────┘
117
+ ↑ ↑
118
+ turnStartIndex = 1 firstKeptEntryId = 7
119
+ │ │
120
+ └──── turnPrefixMessages (1-6) ───────┘
121
+ └── kept (7-8)
122
+
123
+ isSplitTurn = true
124
+ messagesToSummarize = [] (no earlier user-message spans)
125
+ turnPrefixMessages = [usr, ass, tool, ass, tool, tool]
126
+ ```
127
+
128
+ For split user-message spans, Pi generates two summaries and merges them:
129
+ 1. **History summary**: Previous context (if any)
130
+ 2. **User-message-span prefix summary**: The early part of the split user-message span
131
+
132
+ ### Cut Point Rules
133
+
134
+ Valid cut points are:
135
+ - User messages
136
+ - Assistant messages
137
+ - BashExecution messages
138
+ - Custom messages (custom_message, branch_summary)
139
+
140
+ Never cut at tool results (they must stay with their tool call).
141
+
142
+ Preparation advances the kept boundary into a context-invisible suffix only when that suffix contains an omitted assistant attempt and no unomitted context-producing entries. Recovery `context_edit` omissions satisfy this rule; intrinsically context-invisible metadata may coexist with them. Metadata alone and newly appended custom messages do not move the cut. A replacement edit affecting the candidate input or summarized prefix also blocks advancement because the omitted assistant answered the pre-edit input; replacements of suffix entries that are ultimately omitted remain safe. This allows an over-budget recovered input to be summarized while retaining the edits that keep the abandoned attempt omitted, without making bookkeeping change whether new model input is preserved verbatim.
143
+
144
+ ### CompactionEntry Structure
145
+
146
+ Defined in [`session-manager.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/session-manager.ts):
147
+
148
+ ```typescript
149
+ interface CompactionEntry<T = unknown> {
150
+ type: "compaction";
151
+ id: string;
152
+ parentId: string | null;
153
+ timestamp: string;
154
+ summary: string;
155
+ firstKeptEntryId: string;
156
+ tokensBefore: number;
157
+ usage?: Usage; // LLM usage that generated the summary
158
+ fromHook?: boolean; // true if provided by extension (legacy field name)
159
+ details?: T; // implementation-specific data
160
+ }
161
+
162
+ // Default compaction uses this for details (from compaction.ts):
163
+ interface CompactionDetails {
164
+ readFiles: string[];
165
+ modifiedFiles: string[];
166
+ }
167
+ ```
168
+
169
+ Extensions can store any JSON-serializable data in `details`. The default compaction tracks file operations, but custom extension implementations can use their own structure. Generated and extension-provided summaries store their LLM `usage` when available so session totals include summarization work.
170
+
171
+ See [`prepareCompaction()`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) and [`compact()`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) for the implementation. For direct programmatic summarization, `generateSummary()` returns the summary text and `generateSummaryWithUsage()` returns `{ text, usage }`.
172
+
173
+ ## Branch Summarization
174
+
175
+ ### When It Triggers
176
+
177
+ When you use `/tree` to navigate to a different branch, Pi offers to summarize the work you're leaving. This injects context from the left branch into the new branch.
178
+
179
+ ### How It Works
180
+
181
+ 1. **Find common ancestor**: Deepest node shared by old and new positions
182
+ 2. **Collect entries**: Walk from old leaf back to common ancestor
183
+ 3. **Prepare with budget**: Include messages up to token budget (newest first)
184
+ 4. **Generate summary**: Call LLM with structured format
185
+ 5. **Append entry**: Save `BranchSummaryEntry` at navigation point
186
+
187
+ ```
188
+ Tree before navigation:
189
+
190
+ ┌─ B ─ C ─ D (old leaf, being abandoned)
191
+ A ───┤
192
+ └─ E ─ F (target)
193
+
194
+ Common ancestor: A
195
+ Entries to summarize: B, C, D
196
+
197
+ After navigation with summary:
198
+
199
+ ┌─ B ─ C ─ D
200
+ A ───┤
201
+ └─ E ─ F ─ [summary of B,C,D] (new leaf)
202
+ ```
203
+
204
+ ### Cumulative File Tracking
205
+
206
+ Default compaction and branch summarization track files cumulatively. Both extract file operations from tool calls in the messages being summarized. Compaction also carries file lists from the previous Pi-generated compaction. Branch summarization carries file lists from Pi-generated branch summaries in the entries it summarizes.
207
+
208
+ File tracking therefore accumulates across default compactions and nested default branch summaries. Pi does not automatically carry file lists from extension-generated summaries whose `fromHook` field is `true`; extensions manage their own `details` format.
209
+
210
+ ### BranchSummaryEntry Structure
211
+
212
+ Defined in [`session-manager.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/session-manager.ts):
213
+
214
+ ```typescript
215
+ interface BranchSummaryEntry<T = unknown> {
216
+ type: "branch_summary";
217
+ id: string;
218
+ parentId: string | null;
219
+ timestamp: string;
220
+ summary: string;
221
+ fromId: string; // Entry we navigated from
222
+ usage?: Usage; // LLM usage that generated the summary
223
+ fromHook?: boolean; // true if provided by extension (legacy field name)
224
+ details?: T; // implementation-specific data
225
+ }
226
+
227
+ // Default branch summarization uses this for details (from branch-summarization.ts):
228
+ interface BranchSummaryDetails {
229
+ readFiles: string[];
230
+ modifiedFiles: string[];
231
+ }
232
+ ```
233
+
234
+ Same as compaction, extensions can store custom data in `details`.
235
+
236
+ See [`collectEntriesForBranchSummary()`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), [`prepareBranchEntries()`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), and [`generateBranchSummary()`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) for the implementation.
237
+
238
+ ## Summary Format
239
+
240
+ Both formats include Goal, Constraints & Preferences, Progress, Key Decisions, and Next Steps. Compaction summaries also include Critical Context. Branch summaries stop after Next Steps. Pi appends file lists to either format when relevant.
241
+
242
+ Compaction summaries use this format:
243
+
244
+ ```markdown
245
+ ## Goal
246
+ [What the user is trying to accomplish]
247
+
248
+ ## Constraints & Preferences
249
+ - [Requirements mentioned by user]
250
+
251
+ ## Progress
252
+ ### Done
253
+ - [x] [Completed tasks]
254
+
255
+ ### In Progress
256
+ - [ ] [Current work]
257
+
258
+ ### Blocked
259
+ - [Issues, if any]
260
+
261
+ ## Key Decisions
262
+ - **[Decision]**: [Rationale]
263
+
264
+ ## Next Steps
265
+ 1. [What should happen next]
266
+
267
+ ## Critical Context
268
+ - [Data needed to continue]
269
+
270
+ <read-files>
271
+ path/to/file1.ts
272
+ path/to/file2.ts
273
+ </read-files>
274
+
275
+ <modified-files>
276
+ path/to/changed.ts
277
+ </modified-files>
278
+ ```
279
+
280
+ ### Message Serialization
281
+
282
+ Before summarization, messages are serialized to text via [`serializeConversation()`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/utils.ts):
283
+
284
+ ```
285
+ [User]: What they said
286
+ [Assistant thinking]: Internal reasoning
287
+ [Assistant]: Response text
288
+ [Assistant tool calls]: read(path="foo.ts"); edit(path="bar.ts", ...)
289
+ [Tool result]: Output from tool
290
+ ```
291
+
292
+ This prevents the model from treating it as a conversation to continue.
293
+
294
+ Tool results are truncated to 2000 characters during serialization. Content beyond that limit is replaced with a marker indicating how many characters were truncated. This keeps summarization requests within reasonable token budgets, since tool results (especially from `read` and `bash`) are typically the largest contributors to context size.
295
+
296
+ ## Custom Summarization via Extensions
297
+
298
+ Extensions can intercept and customize both compaction and branch summarization. See [`extensions/types.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/extensions/types.ts) for event type definitions.
299
+
300
+ ### session_before_compact
301
+
302
+ Fired before auto-compaction or `/compact`. Can cancel or provide custom summary. See `SessionBeforeCompactEvent` and `CompactionPreparation` in the types file.
303
+
304
+ ```typescript
305
+ pi.on("session_before_compact", async (event, ctx) => {
306
+ const { preparation, branchEntries, customInstructions, reason, willRetry, signal } = event;
307
+
308
+ // preparation.messagesToSummarize - messages to summarize
309
+ // preparation.turnPrefixMessages - user-message-span prefix (if isSplitTurn)
310
+ // preparation.previousSummary - previous compaction summary
311
+ // preparation.fileOps - extracted file operations
312
+ // preparation.tokensBefore - context tokens before compaction
313
+ // preparation.firstKeptEntryId - where kept messages start
314
+ // preparation.settings - effective settings after applying model overrides
315
+
316
+ // branchEntries - all entries on current branch (for custom state)
317
+ // reason - "manual" (/compact), "threshold", or "overflow"
318
+ // willRetry - whether the aborted turn is retried after compaction (overflow recovery)
319
+ // signal - AbortSignal (pass to LLM calls)
320
+
321
+ // Cancel:
322
+ return { cancel: true };
323
+
324
+ // Custom summary:
325
+ return {
326
+ compaction: {
327
+ summary: "Your summary...",
328
+ firstKeptEntryId: preparation.firstKeptEntryId,
329
+ tokensBefore: preparation.tokensBefore,
330
+ // usage: summaryResponse.usage, // Optional; included in session totals
331
+ details: { /* custom data */ },
332
+ }
333
+ };
334
+ });
335
+ ```
336
+
337
+ #### Converting Messages to Text
338
+
339
+ To generate a summary with your own model, convert messages to text using `serializeConversation`:
340
+
341
+ ```typescript
342
+ import { convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
343
+
344
+ pi.on("session_before_compact", async (event, ctx) => {
345
+ const { preparation } = event;
346
+
347
+ // Convert AgentMessage[] to Message[], then serialize to text
348
+ const conversationText = serializeConversation(
349
+ convertToLlm(preparation.messagesToSummarize)
350
+ );
351
+ // Returns:
352
+ // [User]: message text
353
+ // [Assistant thinking]: thinking content
354
+ // [Assistant]: response text
355
+ // [Assistant tool calls]: read(path="..."); bash(command="...")
356
+ // [Tool result]: output text
357
+
358
+ // Now send to your model for summarization
359
+ const { summary, usage } = await myModel.summarize(conversationText);
360
+
361
+ return {
362
+ compaction: {
363
+ summary,
364
+ firstKeptEntryId: preparation.firstKeptEntryId,
365
+ tokensBefore: preparation.tokensBefore,
366
+ usage,
367
+ }
368
+ };
369
+ });
370
+ ```
371
+
372
+ See [custom-compaction.ts](https://github.com/earendil-works/pi/blob/b78e6a9085343ec0f308c3d377da72528b4cf7ee/packages/coding-agent/examples/extensions/custom-compaction.ts) for a complete example using a different model.
373
+
374
+ ### session_compact_failed
375
+
376
+ Fired when manual or automatic compaction fails or is aborted. This is useful for telemetry extensions that need to pair `session_before_compact` attempts with terminal outcomes.
377
+
378
+ ```typescript
379
+ pi.on("session_compact_failed", async (event, ctx) => {
380
+ const { reason, errorMessage, aborted, willRetry, fromExtension } = event;
381
+ // reason - "manual" (/compact), "threshold", or "overflow"
382
+ // errorMessage - present for non-abort failures
383
+ // aborted - true for canceled/aborted compactions
384
+ // willRetry - whether the aborted turn would have retried after compaction
385
+ // fromExtension - whether extension-provided compaction content was being used
386
+ });
387
+ ```
388
+
389
+ ### session_before_tree
390
+
391
+ Fired before `/tree` navigation. Always fires regardless of whether user chose to summarize. Can cancel navigation or provide custom summary.
392
+
393
+ ```typescript
394
+ pi.on("session_before_tree", async (event, ctx) => {
395
+ const { preparation, signal } = event;
396
+
397
+ // preparation.targetId - where we're navigating to
398
+ // preparation.oldLeafId - current position (being abandoned)
399
+ // preparation.commonAncestorId - shared ancestor
400
+ // preparation.entriesToSummarize - entries that would be summarized
401
+ // preparation.userWantsSummary - whether user chose to summarize
402
+
403
+ // Cancel navigation entirely:
404
+ return { cancel: true };
405
+
406
+ // Provide custom summary (only used if userWantsSummary is true):
407
+ if (preparation.userWantsSummary) {
408
+ return {
409
+ summary: {
410
+ summary: "Your summary...",
411
+ // usage: summaryResponse.usage, // Optional; included in session totals
412
+ details: { /* custom data */ },
413
+ }
414
+ };
415
+ }
416
+ });
417
+ ```
418
+
419
+ See `SessionBeforeTreeEvent` and `TreePreparation` in the types file.
420
+
421
+ ## Settings
422
+
423
+ Configure compaction in `~/.pi/agent/settings.json` or `<project-dir>/.pi/settings.json`:
424
+
425
+ ```json
426
+ {
427
+ "compaction": {
428
+ "enabled": true,
429
+ "reserveTokens": 16384,
430
+ "keepRecentTokens": 20000
431
+ }
432
+ }
433
+ ```
434
+
435
+ | Setting | Default | Description |
436
+ |---------|---------|-------------|
437
+ | `enabled` | `true` | Enable auto-compaction |
438
+ | `reserveTokens` | `16384` | Tokens to reserve for LLM response |
439
+ | `keepRecentTokens` | `20000` | Recent tokens to keep (not summarized) |
440
+
441
+ Disable auto-compaction with `"enabled": false`. You can still compact manually with `/compact`.
442
+
443
+ ### Per-model overrides
444
+
445
+ Use `compaction.modelOverrides` to tune token budgets for different models:
446
+
447
+ ```json
448
+ {
449
+ "compaction": {
450
+ "reserveTokens": 16384,
451
+ "keepRecentTokens": 20000,
452
+ "modelOverrides": {
453
+ "some-provider/big-model": {
454
+ "reserveTokens": 400000
455
+ }
456
+ }
457
+ }
458
+ }
459
+ ```
460
+
461
+ For a model with a 1M context window, this override triggers compaction above 600K tokens and keeps the ordinary 20000 recent tokens. Other models retain the ordinary 16384-token reserve. `reserveTokens` also influences summarization output limits, capped by the model's maximum output tokens; it is not solely a trigger threshold.
462
+
463
+ Keys are exact, case-sensitive `provider/modelId` values, including any slashes within the model ID. Each `reserveTokens` and `keepRecentTokens` value falls back independently from the model override to the ordinary setting to the built-in default. Values must be non-negative safe integers. Invalid values in the matching model override produce an error when read; only omitted fields fall back to the ordinary setting. Model override entries must be objects. Invalid ordinary token settings produce an error when read, even if the active model has a valid override. Only omitted ordinary values use built-in defaults. `enabled` remains global, not model-specific.
464
+
465
+ These resolved values are used for manual compaction, all automatic threshold checks, overflow recovery, and extension-visible `preparation.settings`. Model switches affect subsequent checks and compactions without changing ordinary settings. Compaction already in progress uses the model and settings captured for that operation. Branch summarization settings are unaffected.
466
+
467
+ Overrides work in both global and project settings. The files merge recursively before lookup, so a global model-specific value beats a project-wide fallback; a project must override that model entry to change it. See [Settings](settings.md#per-model-compaction-overrides) for details.
@@ -0,0 +1,51 @@
1
+ > Source: [packages/coding-agent/docs/configuration.md](https://github.com/earendil-works/pi/blob/b78e6a9085343ec0f308c3d377da72528b4cf7ee/packages/coding-agent/docs/configuration.md)
2
+ > Retrieved with Firecrawl: 2026-10-05. Repository snapshot: `b78e6a9085343ec0f308c3d377da72528b4cf7ee`.
3
+ > Relative documentation links point to local copies where available, otherwise to the source snapshot.
4
+
5
+ # Configuration
6
+
7
+ Pi supports user-level and project configuration. User-level configuration lives in the agent directory, which defaults to `~/.pi/agent`. Project configuration lives in `.pi` under the working directory and loads after [project trust](security.md#understand-project-trust) is granted. The only exception is `sessionDir`, which Pi reads before resolving trust so it can locate sessions.
8
+
9
+ In interactive mode, use `/settings` to change common preferences. For other options, ask Pi to update the configuration or edit the relevant files directly. Run `/reload` after manually changing settings, keybindings, instructions, or resources.
10
+
11
+ ## Agent directory
12
+
13
+ The agent directory is shown as `<agent-dir>` below. Set its location with the `PI_CODING_AGENT_DIR` environment variable or the SDK's [`agentDir`](sdk.md) option.
14
+
15
+ | Path | Responsibility |
16
+ |---|---|
17
+ | `<agent-dir>/settings.json` | User-level [settings](settings.md), including preferences, defaults, resource paths, and Pi package declarations. |
18
+ | `<agent-dir>/keybindings.json` | Custom terminal UI and application [keybindings](keybindings.md). |
19
+ | `<agent-dir>/mcp.json` | [MCP servers](mcp.md) available in every project. |
20
+ | `<agent-dir>/models.json` | [Compatible endpoints, models, and model overrides](models.md#configure-a-compatible-endpoint). |
21
+ | `<agent-dir>/auth.json` | Saved API keys and OAuth credentials. |
22
+ | `<agent-dir>/AGENTS.override.md`, `AGENTS.md`, `AGENTS.MD`, `CLAUDE.md`, or `CLAUDE.MD` | User instructions applied across working directories. |
23
+ | `<agent-dir>/SYSTEM.md` | Replaces Pi’s default system prompt. |
24
+ | `<agent-dir>/APPEND_SYSTEM.md` | Adds instructions to Pi’s system prompt. |
25
+ | `<agent-dir>/extensions/` | User [extensions](extensions.md). |
26
+ | `<agent-dir>/skills/` | User [skills](skills.md) and supporting files. |
27
+ | `<agent-dir>/prompts/` | User [prompt templates](prompt-templates.md) exposed as slash commands. |
28
+ | `<agent-dir>/themes/` | User [theme](themes.md) files. |
29
+
30
+ ## Project `.pi` directory
31
+
32
+ | Path | Responsibility |
33
+ |---|---|
34
+ | `.pi/settings.json` | Project-level [settings](settings.md), resource paths, and Pi package declarations. |
35
+ | `.pi/mcp.json` | Project [MCP servers](mcp.md). |
36
+ | `.pi/SYSTEM.md` | Replaces the system prompt for the project. |
37
+ | `.pi/APPEND_SYSTEM.md` | Adds project-specific instructions to the system prompt. |
38
+ | `.pi/extensions/` | Project extensions. |
39
+ | `.pi/skills/` | Project skills and supporting files. |
40
+ | `.pi/prompts/` | Project prompt templates exposed as slash commands. |
41
+ | `.pi/themes/` | Project theme files. |
42
+
43
+ For `SYSTEM.md` and `APPEND_SYSTEM.md`, the trusted project file takes precedence over the corresponding agent-directory file. Files with the same name are not combined.
44
+
45
+ ## Context files
46
+
47
+ Context files are separate from project `.pi` configuration. Pi loads them from the agent directory, the working directory, and its parent directories. A context file applies whenever Pi runs in its directory or anywhere below it.
48
+
49
+ An `AGENTS.override.md` replaces `AGENTS.md` or `CLAUDE.md` only in the same directory. It does not suppress context files from the agent directory or other directories.
50
+
51
+ Context-file discovery does not require project trust.