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,123 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 534" width="1200" height="534" role="img" aria-labelledby="title desc" font-family="Inter, 'Segoe UI', Helvetica, Arial, sans-serif">
2
+ <title id="title">One API, every client</title>
3
+ <desc id="desc">The web UI, dpi-tui and curl send requests through one /v1 API, checked with a bearer token, to the same agent on any device; the agent writes to agent.sqlite and the answer streams back to every client, and curl gets it in one request.</desc>
4
+ <style>
5
+ .a { animation-duration: 13s; animation-iteration-count: infinite; animation-timing-function: ease-in-out; }
6
+ .ln { animation-timing-function: linear; }
7
+ .x { transform-box: fill-box; transform-origin: center; }
8
+ @keyframes cd0 { 0%, 0.5% { opacity: 0; transform: translateX(-16px) } 3.5%, 96% { opacity: 1; transform: translateX(0) } 100% { opacity: 0; transform: translateX(0) } }
9
+ @keyframes cn0 { 0%, 1.5% { opacity: 0 } 4.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
10
+ @keyframes cd1 { 0%, 1.5% { opacity: 0; transform: translateX(-16px) } 4.5%, 96% { opacity: 1; transform: translateX(0) } 100% { opacity: 0; transform: translateX(0) } }
11
+ @keyframes cn1 { 0%, 2.5% { opacity: 0 } 5.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
12
+ @keyframes cd2 { 0%, 2.5% { opacity: 0; transform: translateX(-16px) } 5.5%, 96% { opacity: 1; transform: translateX(0) } 100% { opacity: 0; transform: translateX(0) } }
13
+ @keyframes cn2 { 0%, 3.5% { opacity: 0 } 6.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
14
+ @keyframes row1 { 0%, 7% { opacity: 0 } 9%, 96% { opacity: 1 } 100% { opacity: 0 } }
15
+ @keyframes rq0 { 0%, 9% { opacity: 0; transform: translateX(0px) } 9.6% { opacity: 1; transform: translateX(0px) } 15.2% { opacity: 1; transform: translateX(75.6px) } 16%, 100% { opacity: 0; transform: translateX(84px) } }
16
+ @keyframes rq1 { 0%, 9.6% { opacity: 0; transform: translateX(0px) } 10.2% { opacity: 1; transform: translateX(0px) } 15.8% { opacity: 1; transform: translateX(75.6px) } 16.6%, 100% { opacity: 0; transform: translateX(84px) } }
17
+ @keyframes rq2 { 0%, 10.2% { opacity: 0; transform: translateX(0px) } 10.8% { opacity: 1; transform: translateX(0px) } 16.4% { opacity: 1; transform: translateX(75.6px) } 17.2%, 100% { opacity: 0; transform: translateX(84px) } }
18
+ @keyframes key { 0%, 16.5% { opacity: .3 } 18.5%, 96% { opacity: 1 } 100% { opacity: .3 } }
19
+ @keyframes kring { 0%, 16.8% { opacity: 0; transform: scale(.92) } 18.5% { opacity: 1; transform: scale(1) } 23%, 100% { opacity: 0; transform: scale(1.12) } }
20
+ @keyframes fw { 0%, 20% { opacity: 0; transform: translateX(0px) } 21% { opacity: 1; transform: translateX(0px) } 27.5% { opacity: 1; transform: translateX(82.8px) } 29%, 100% { opacity: 0; transform: translateX(90px) } }
21
+ @keyframes pring { 0%, 28.5% { opacity: 0; transform: scale(.94) } 30% { opacity: 1; transform: scale(1) } 35%, 100% { opacity: 0; transform: scale(1.1) } }
22
+ @keyframes write { 0%, 31% { stroke-dashoffset: 1 } 35%, 100% { stroke-dashoffset: 0 } }
23
+ @keyframes head { 0%, 34% { opacity: 0 } 35.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
24
+ @keyframes dbk { 0%, 34.5% { opacity: 0 } 36% { opacity: 1 } 41%, 100% { opacity: 0 } }
25
+ @keyframes bk { 0%, 38% { opacity: 0; transform: translateX(0px) } 39% { opacity: 1; transform: translateX(0px) } 45% { opacity: 1; transform: translateX(-82.8px) } 46.5%, 100% { opacity: 0; transform: translateX(-90px) } }
26
+ @keyframes rs0 { 0%, 46% { opacity: 0; transform: translateX(0px) } 46.8% { opacity: 1; transform: translateX(-8.4px) } 52.4% { opacity: 1; transform: translateX(-79.8px) } 53%, 100% { opacity: 0; transform: translateX(-84px) } }
27
+ @keyframes rs1 { 0%, 46.5% { opacity: 0; transform: translateX(0px) } 47.3% { opacity: 1; transform: translateX(-8.4px) } 52.9% { opacity: 1; transform: translateX(-79.8px) } 53.5%, 100% { opacity: 0; transform: translateX(-84px) } }
28
+ @keyframes rs2 { 0%, 47% { opacity: 0; transform: translateX(0px) } 47.8% { opacity: 1; transform: translateX(-8.4px) } 53.4% { opacity: 1; transform: translateX(-79.8px) } 54%, 100% { opacity: 0; transform: translateX(-84px) } }
29
+ @keyframes row2 { 0%, 53.5% { opacity: 0; transform: translateX(-10px) } 56%, 96% { opacity: 1; transform: translateX(0) } 100% { opacity: 0; transform: translateX(0) } }
30
+ @keyframes done { 0%, 54.5% { opacity: 0; transform: translateX(-10px) } 57%, 96% { opacity: 1; transform: translateX(0) } 100% { opacity: 0; transform: translateX(0) } }
31
+ @media (prefers-reduced-motion: reduce) { * { animation: none !important; } }
32
+ </style>
33
+ <defs>
34
+ <symbol id="g-browser" viewBox="0 0 72 52">
35
+ <rect x="2" y="2" width="68" height="48" rx="6" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
36
+ <path d="M 2 14 H70" stroke="#F3EDEE" stroke-width="2.5"/>
37
+ <circle cx="10" cy="8" r="2" fill="#FF5252"/><circle cx="17" cy="8" r="2" fill="#B9AAAE"/><circle cx="24" cy="8" r="2" fill="#B9AAAE"/>
38
+ <path d="M 12 26 H44 M 12 34 H58 M 12 42 H36" stroke="#B9AAAE" stroke-width="3" stroke-linecap="round"/>
39
+ </symbol>
40
+ <symbol id="g-terminal" viewBox="0 0 72 52">
41
+ <rect x="2" y="2" width="68" height="48" rx="6" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
42
+ <path d="M 14 18 L24 26 L14 34" fill="none" stroke="#FF5252" stroke-width="3.2" stroke-linecap="round" stroke-linejoin="round"/>
43
+ <path d="M 30 36 H50" stroke="#F3EDEE" stroke-width="3.2" stroke-linecap="round"/>
44
+ </symbol>
45
+ <symbol id="g-check-o" viewBox="0 0 32 32">
46
+ <circle cx="16" cy="16" r="13.5" fill="none" stroke="#FF5252" stroke-width="2.5"/>
47
+ <path d="M 9.5 16.5 L14 21 L22.5 11.5" fill="none" stroke="#FF5252" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
48
+ </symbol>
49
+ <symbol id="g-key" viewBox="0 0 48 24">
50
+ <circle cx="11" cy="12" r="8" fill="none" stroke="#FF5252" stroke-width="2.8"/>
51
+ <path d="M 19 12 H45 M 36 12 V19 M 42 12 V17" stroke="#FF5252" stroke-width="2.8" stroke-linecap="round"/>
52
+ </symbol>
53
+ <symbol id="g-server" viewBox="0 0 64 44">
54
+ <rect x="3" y="4" width="58" height="16" rx="4" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
55
+ <rect x="3" y="24" width="58" height="16" rx="4" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
56
+ <circle cx="13" cy="12" r="2.6" fill="#FF5252"/><circle cx="13" cy="32" r="2.6" fill="#FF5252"/>
57
+ <path d="M 36 12 H53 M 36 32 H53" stroke="#B9AAAE" stroke-width="2.5" stroke-linecap="round"/>
58
+ </symbol>
59
+ <symbol id="g-pi" viewBox="0 0 64 64">
60
+ <rect x="1.5" y="1.5" width="61" height="61" rx="12" fill="#141011" stroke="#FF5252" stroke-width="2.5"/>
61
+ <g fill="#FFFFFF" transform="translate(16 16) scale(8)">
62
+ <path d="M 0 0H3V2H2V1H0Z"/>
63
+ <path d="M 0 1H1V2H2V3H1V4H0Z"/>
64
+ <path d="M 3 2H4V4H3Z"/>
65
+ </g>
66
+ </symbol>
67
+ <symbol id="g-db" viewBox="0 0 48 60">
68
+ <path d="M 3 10 V50 A21 7 0 0 0 45 50 V10" fill="#3A1D20" stroke="#FF5252" stroke-width="2.5"/>
69
+ <ellipse cx="24" cy="10" rx="21" ry="7" fill="#5A2328" stroke="#FF5252" stroke-width="2.5"/>
70
+ <path d="M 3 24 A21 7 0 0 0 45 24 M 3 37 A21 7 0 0 0 45 37" fill="none" stroke="#FF5252" stroke-width="2.5"/>
71
+ </symbol>
72
+ <symbol id="chip-req" viewBox="0 0 28 28"><rect width="28" height="28" rx="7" fill="#FF5252"/><path d="M 11 8.5 L17 14 L11 19.5" fill="none" stroke="#141011" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></symbol>
73
+ <symbol id="chip-res" viewBox="0 0 28 28"><rect width="28" height="28" rx="7" fill="#FF5252"/><path d="M 8 9 H20 M 8 14 H20 M 8 19 H15" fill="none" stroke="#141011" stroke-width="2.8" stroke-linecap="round"/></symbol>
74
+ </defs>
75
+ <rect width="1200" height="534" rx="18" fill="#141011"/>
76
+ <text x="48" y="70" font-size="34" font-weight="600" fill="#F3EDEE">One API, every client</text>
77
+ <path class="a" style="animation-name: cn0" d="M 502 156 H608" stroke="#B9AAAE" stroke-width="2.5"/>
78
+ <path class="a" style="animation-name: cn1" d="M 502 276 H608" stroke="#B9AAAE" stroke-width="2.5"/>
79
+ <path class="a" style="animation-name: cn2" d="M 502 396 H608" stroke="#B9AAAE" stroke-width="2.5"/>
80
+ <path d="M 776 276 H852" stroke="#B9AAAE" stroke-width="2.5"/>
81
+ <g class="a" style="animation-name: cd0">
82
+ <rect x="48" y="106" width="454" height="100" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
83
+ <use href="#g-browser" x="68" y="130" width="72" height="52"/>
84
+ <text x="160" y="164" font-size="24" fill="#F3EDEE">web UI</text>
85
+ <g class="a" style="animation-name: row1" fill="none" stroke-linecap="round"><path d="M 310 138 L316 144 L310 150" stroke="#B9AAAE" stroke-width="2.5" stroke-linejoin="round"/><path d="M 332 144 H410 M 424 144 H460" stroke="#6B5A5E" stroke-width="7"/></g><g class="a" style="animation-name: row2" fill="none" stroke-linecap="round"><path d="M 309 164 H319 M 309 169 H319 M 309 174 H316" stroke="#FF5252" stroke-width="2.2"/><path d="M 332 169 H386 M 400 169 H450 M 464 169 H476" stroke="#FF5252" stroke-width="7"/></g>
86
+ </g>
87
+ <g class="a" style="animation-name: cd1">
88
+ <rect x="48" y="226" width="454" height="100" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
89
+ <use href="#g-terminal" x="68" y="250" width="72" height="52"/>
90
+ <text x="160" y="284" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#F3EDEE">dpi-tui</text>
91
+ <g class="a" style="animation-name: row1" fill="none" stroke-linecap="round"><path d="M 310 258 L316 264 L310 270" stroke="#B9AAAE" stroke-width="2.5" stroke-linejoin="round"/><path d="M 332 264 H410 M 424 264 H460" stroke="#6B5A5E" stroke-width="7"/></g><g class="a" style="animation-name: row2" fill="none" stroke-linecap="round"><path d="M 309 284 H319 M 309 289 H319 M 309 294 H316" stroke="#FF5252" stroke-width="2.2"/><path d="M 332 289 H386 M 400 289 H450 M 464 289 H476" stroke="#FF5252" stroke-width="7"/></g>
92
+ </g>
93
+ <g class="a" style="animation-name: cd2">
94
+ <rect x="48" y="346" width="454" height="100" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
95
+ <text x="68" y="386" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="20" fill="#F3EDEE"><tspan fill="#FF5252">curl</tspan> POST …/messages</text>
96
+ <g class="a" style="animation-name: done"><use href="#g-check-o" x="68" y="404" width="22" height="22"/><text x="98" y="422" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="20" fill="#F3EDEE">done<tspan fill="#B9AAAE"> · the answer in one request</tspan></text></g>
97
+ </g>
98
+ <rect x="608" y="106" width="168" height="340" rx="22" fill="#21191B" stroke="#FF5252" stroke-width="2.5"/>
99
+ <text x="692" y="160" text-anchor="middle" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="32" font-weight="700" fill="#FF5252">/v1</text>
100
+ <g class="a" style="animation-name: key"><use href="#g-key" x="656" y="258" width="72" height="36"/></g>
101
+ <rect class="a x" style="animation-name: kring" x="642" y="249" width="100" height="54" rx="14" fill="none" stroke="#FF5252" stroke-width="2" opacity="0"/>
102
+ <text x="692" y="324" text-anchor="middle" font-size="20" fill="#B9AAAE">Bearer token</text>
103
+ <rect x="828" y="122" width="324" height="256" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
104
+ <use href="#g-server" x="848" y="142" width="58" height="40"/>
105
+ <text x="920" y="166" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#F3EDEE">dpi-backend</text>
106
+ <text x="920" y="192" font-size="20" fill="#B9AAAE">any device</text>
107
+ <use href="#g-pi" x="852" y="226" width="100" height="100"/>
108
+ <rect class="a x" style="animation-name: pring" x="844" y="218" width="116" height="116" rx="22" fill="none" stroke="#FF5252" stroke-width="2" opacity="0"/>
109
+ <path class="a" style="animation-name: write" d="M 962 276 H1018" pathLength="1" stroke-dasharray="1 1" stroke="#FF5252" stroke-width="2.5"/>
110
+ <path class="a" style="animation-name: head" d="M 1018 270 L1029 276 L1018 282 Z" fill="#FF5252"/>
111
+ <use href="#g-db" x="1036" y="241" width="56" height="70"/>
112
+ <rect class="a" style="animation-name: dbk" x="1028" y="233" width="72" height="86" rx="14" fill="none" stroke="#FF5252" stroke-width="2" opacity="0"/>
113
+ <text x="1064" y="340" text-anchor="middle" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="20" fill="#B9AAAE">agent.sqlite</text>
114
+ <use class="a" style="animation-name: rq0" href="#chip-req" x="506" y="142" width="28" height="28" opacity="0"/>
115
+ <use class="a" style="animation-name: rq1" href="#chip-req" x="506" y="262" width="28" height="28" opacity="0"/>
116
+ <use class="a" style="animation-name: rq2" href="#chip-req" x="506" y="382" width="28" height="28" opacity="0"/>
117
+ <use class="a" style="animation-name: fw" href="#chip-req" x="732" y="262" width="28" height="28" opacity="0"/>
118
+ <use class="a" style="animation-name: bk" href="#chip-res" x="822" y="262" width="28" height="28" opacity="0"/>
119
+ <use class="a" style="animation-name: rs0" href="#chip-res" x="590" y="142" width="28" height="28" opacity="0"/>
120
+ <use class="a" style="animation-name: rs1" href="#chip-res" x="590" y="262" width="28" height="28" opacity="0"/>
121
+ <use class="a" style="animation-name: rs2" href="#chip-res" x="590" y="382" width="28" height="28" opacity="0"/>
122
+ <text x="600" y="498" text-anchor="middle" font-size="22" fill="#B9AAAE">REST for commands. SSE for live state. Several clients can watch and steer one agent.</text>
123
+ </svg>
@@ -0,0 +1,123 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 652" width="1200" height="652" role="img" aria-labelledby="title desc" font-family="Inter, 'Segoe UI', Helvetica, Arial, sans-serif">
2
+ <title id="title">Device, session, agent</title>
3
+ <desc id="desc">A device runs one dpi-backend, each session on it has one harness and one agent.sqlite, and each agent is Main, a fork or a subagent; the command just tui attach mac-mini:api-refactor:fork names one agent by device, session and agent.</desc>
4
+ <style>
5
+ .a { animation-duration: 13s; animation-iteration-count: infinite; animation-timing-function: ease-in-out; }
6
+ .ln { animation-timing-function: linear; }
7
+ .x { transform-box: fill-box; transform-origin: center; }
8
+ @keyframes dev { 0%, 1% { opacity: 0; transform: translateY(8px) } 5%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
9
+ @keyframes lv0 { 0%, 2% { opacity: 0 } 6%, 96% { opacity: 1 } 100% { opacity: 0 } }
10
+ @keyframes c_da { 0%, 6% { stroke-dashoffset: 1; stroke: #B9AAAE } 11%, 53% { stroke-dashoffset: 0; stroke: #B9AAAE } 55%, 96% { stroke-dashoffset: 0; stroke: #FF5252 } 100% { stroke-dashoffset: 1; stroke: #B9AAAE } }
11
+ @keyframes c_dn { 0%, 6% { stroke-dashoffset: 1 } 11%, 96% { stroke-dashoffset: 0 } 100% { stroke-dashoffset: 1 } }
12
+ @keyframes h_da { 0%, 10.5% { opacity: 0; fill: #B9AAAE } 11.5%, 53% { opacity: 1; fill: #B9AAAE } 55%, 96% { opacity: 1; fill: #FF5252 } 100% { opacity: 0; fill: #B9AAAE } }
13
+ @keyframes h_dn { 0%, 10.5% { opacity: 0 } 11.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
14
+ @keyframes s0 { 0%, 10% { opacity: 0; transform: translateY(8px) } 14%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
15
+ @keyframes s1 { 0%, 11% { opacity: 0; transform: translateY(8px) } 15%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
16
+ @keyframes lv1 { 0%, 11.5% { opacity: 0 } 15.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
17
+ @keyframes c_sm0 { 0%, 15% { stroke-dashoffset: 1; stroke: #B9AAAE } 18.5%, 59% { stroke-dashoffset: 0; stroke: #B9AAAE } 61%, 96% { stroke-dashoffset: 0; stroke: #FF5252 } 100% { stroke-dashoffset: 1; stroke: #B9AAAE } }
18
+ @keyframes c_sm1 { 0%, 15% { stroke-dashoffset: 1 } 18.5%, 96% { stroke-dashoffset: 0 } 100% { stroke-dashoffset: 1 } }
19
+ @keyframes h_sm0 { 0%, 18% { opacity: 0; fill: #B9AAAE } 19%, 59% { opacity: 1; fill: #B9AAAE } 61%, 96% { opacity: 1; fill: #FF5252 } 100% { opacity: 0; fill: #B9AAAE } }
20
+ @keyframes h_sm1 { 0%, 18% { opacity: 0 } 19%, 96% { opacity: 1 } 100% { opacity: 0 } }
21
+ @keyframes m0 { 0%, 18% { opacity: 0; transform: translateY(8px) } 22%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
22
+ @keyframes m1 { 0%, 18.5% { opacity: 0; transform: translateY(8px) } 22.5%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
23
+ @keyframes lv2 { 0%, 19% { opacity: 0 } 23%, 96% { opacity: 1 } 100% { opacity: 0 } }
24
+ @keyframes c_fk { 0%, 23% { stroke-dashoffset: 1 } 27%, 96% { stroke-dashoffset: 0 } 100% { stroke-dashoffset: 1 } }
25
+ @keyframes h_fk { 0%, 26.5% { opacity: 0 } 27.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
26
+ @keyframes c_sub { 0%, 23% { opacity: 0 } 27%, 96% { opacity: 1 } 100% { opacity: 0 } }
27
+ @keyframes k0 { 0%, 26% { opacity: 0; transform: translateY(8px) } 30%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
28
+ @keyframes k1 { 0%, 27% { opacity: 0; transform: translateY(8px) } 31%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
29
+ @keyframes strip { 0%, 31.5% { opacity: 0; transform: translateY(10px) } 34.5%, 96% { opacity: 1; transform: translateY(0) } 100% { opacity: 0; transform: translateY(0) } }
30
+ @keyframes t0 { 0%, 35% { opacity: 0 } 35.8%, 96% { opacity: 1 } 100% { opacity: 0 } }
31
+ @keyframes t1 { 0%, 36.2% { opacity: 0 } 37%, 96% { opacity: 1 } 100% { opacity: 0 } }
32
+ @keyframes t2 { 0%, 37.4% { opacity: 0 } 38.2%, 96% { opacity: 1 } 100% { opacity: 0 } }
33
+ @keyframes t3 { 0%, 38.8% { opacity: 0 } 39.6%, 96% { opacity: 1 } 100% { opacity: 0 } }
34
+ @keyframes t4 { 0%, 40% { opacity: 0 } 40.8%, 96% { opacity: 1 } 100% { opacity: 0 } }
35
+ @keyframes t5 { 0%, 41.2% { opacity: 0 } 42%, 96% { opacity: 1 } 100% { opacity: 0 } }
36
+ @keyframes t6 { 0%, 42.6% { opacity: 0 } 43.4%, 96% { opacity: 1 } 100% { opacity: 0 } }
37
+ @keyframes t7 { 0%, 43.8% { opacity: 0 } 44.6%, 96% { opacity: 1 } 100% { opacity: 0 } }
38
+ @keyframes seg0 { 0%, 47% { fill: #F3EDEE } 49%, 96% { fill: #FF5252 } 100% { fill: #F3EDEE } }
39
+ @keyframes ul0 { 0%, 47% { opacity: 0; stroke-dashoffset: 1 } 47.3% { opacity: 1; stroke-dashoffset: 1 } 49%, 96% { opacity: 1; stroke-dashoffset: 0 } 100% { opacity: 0; stroke-dashoffset: 0 } }
40
+ @keyframes an0 { 0%, 47.5% { opacity: 0 } 49.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
41
+ @keyframes seg1 { 0%, 53% { fill: #F3EDEE } 55%, 96% { fill: #FF5252 } 100% { fill: #F3EDEE } }
42
+ @keyframes ul1 { 0%, 53% { opacity: 0; stroke-dashoffset: 1 } 53.3% { opacity: 1; stroke-dashoffset: 1 } 55%, 96% { opacity: 1; stroke-dashoffset: 0 } 100% { opacity: 0; stroke-dashoffset: 0 } }
43
+ @keyframes an1 { 0%, 53.5% { opacity: 0 } 55.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
44
+ @keyframes seg2 { 0%, 59% { fill: #F3EDEE } 61%, 96% { fill: #FF5252 } 100% { fill: #F3EDEE } }
45
+ @keyframes ul2 { 0%, 59% { opacity: 0; stroke-dashoffset: 1 } 59.3% { opacity: 1; stroke-dashoffset: 1 } 61%, 96% { opacity: 1; stroke-dashoffset: 0 } 100% { opacity: 0; stroke-dashoffset: 0 } }
46
+ @keyframes an2 { 0%, 59.5% { opacity: 0 } 61.5%, 96% { opacity: 1 } 100% { opacity: 0 } }
47
+ @keyframes dev_hl { 0%, 47% { stroke: #443438 } 49%, 96% { stroke: #FF5252 } 100% { stroke: #443438 } }
48
+ @keyframes s0_hl { 0%, 53% { stroke: #443438 } 55%, 96% { stroke: #FF5252 } 100% { stroke: #443438 } }
49
+ @keyframes fork_hl { 0%, 59% { opacity: 0 } 61%, 96% { opacity: 1 } 100% { opacity: 0 } }
50
+ @media (prefers-reduced-motion: reduce) { * { animation: none !important; } }
51
+ </style>
52
+ <defs>
53
+ <symbol id="g-server" viewBox="0 0 64 44">
54
+ <rect x="3" y="4" width="58" height="16" rx="4" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
55
+ <rect x="3" y="24" width="58" height="16" rx="4" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
56
+ <circle cx="13" cy="12" r="2.6" fill="#FF5252"/><circle cx="13" cy="32" r="2.6" fill="#FF5252"/>
57
+ <path d="M 36 12 H53 M 36 32 H53" stroke="#B9AAAE" stroke-width="2.5" stroke-linecap="round"/>
58
+ </symbol>
59
+ <symbol id="g-folder" viewBox="0 0 52 40">
60
+ <path d="M 3 8 A4 4 0 0 1 7 4 H19 L24 10 H45 A4 4 0 0 1 49 14 V33 A4 4 0 0 1 45 37 H7 A4 4 0 0 1 3 33 Z" fill="#21191B" stroke="#FF5252" stroke-width="2.5" stroke-linejoin="round"/>
61
+ </symbol>
62
+ <symbol id="g-db" viewBox="0 0 48 60">
63
+ <path d="M 3 10 V50 A21 7 0 0 0 45 50 V10" fill="#3A1D20" stroke="#FF5252" stroke-width="2.5"/>
64
+ <ellipse cx="24" cy="10" rx="21" ry="7" fill="#5A2328" stroke="#FF5252" stroke-width="2.5"/>
65
+ <path d="M 3 24 A21 7 0 0 0 45 24 M 3 37 A21 7 0 0 0 45 37" fill="none" stroke="#FF5252" stroke-width="2.5"/>
66
+ </symbol>
67
+ <symbol id="g-pi" viewBox="0 0 64 64">
68
+ <rect x="1.5" y="1.5" width="61" height="61" rx="12" fill="#141011" stroke="#FF5252" stroke-width="2.5"/>
69
+ <g fill="#FFFFFF" transform="translate(16 16) scale(8)">
70
+ <path d="M 0 0H3V2H2V1H0Z"/>
71
+ <path d="M 0 1H1V2H2V3H1V4H0Z"/>
72
+ <path d="M 3 2H4V4H3Z"/>
73
+ </g>
74
+ </symbol>
75
+ <symbol id="g-terminal" viewBox="0 0 72 52">
76
+ <rect x="2" y="2" width="68" height="48" rx="6" fill="#21191B" stroke="#F3EDEE" stroke-width="2.5"/>
77
+ <path d="M 14 18 L24 26 L14 34" fill="none" stroke="#FF5252" stroke-width="3.2" stroke-linecap="round" stroke-linejoin="round"/>
78
+ <path d="M 30 36 H50" stroke="#F3EDEE" stroke-width="3.2" stroke-linecap="round"/>
79
+ </symbol>
80
+ </defs>
81
+ <rect width="1200" height="652" rx="18" fill="#141011"/>
82
+ <text x="48" y="70" font-size="34" font-weight="600" fill="#F3EDEE">Device, session, agent</text>
83
+ <g class="a" style="animation-name: lv0"><text x="48" y="131" font-size="22" font-weight="600" fill="#B9AAAE">device:</text><text x="48" y="157" font-size="20" fill="#B9AAAE">one dpi-backend</text></g>
84
+ <g class="a" style="animation-name: lv1"><text x="48" y="261" font-size="22" font-weight="600" fill="#B9AAAE">session:</text><text x="48" y="287" font-size="20" fill="#B9AAAE">one harness, one agent.sqlite</text></g>
85
+ <g class="a" style="animation-name: lv2"><text x="48" y="414" font-size="22" font-weight="600" fill="#B9AAAE">agent:</text><text x="48" y="440" font-size="20" fill="#B9AAAE">Main, a fork or a subagent</text></g>
86
+ <rect class="a" style="animation-name: fork_hl" x="477" y="436" width="150" height="76" rx="12" fill="#21191B" stroke="#FF5252" stroke-width="2.5"/>
87
+ <path class="a ln" style="animation-name: c_dn" d="M 779 172 V200 H951 V223" pathLength="1" stroke-dasharray="1 1" fill="none" stroke="#B9AAAE" stroke-width="2.5" stroke-linejoin="round"/>
88
+ <path class="a ln" style="animation-name: c_da" d="M 779 172 V200 H607 V223" pathLength="1" stroke-dasharray="1 1" fill="none" stroke="#FF5252" stroke-width="2.5" stroke-linejoin="round"/>
89
+ <path class="a" style="animation-name: h_dn" d="M 944.5 220 L951 231 L957.5 220 Z" fill="#B9AAAE"/>
90
+ <path class="a" style="animation-name: h_da" d="M 600.5 220 L607 231 L613.5 220 Z" fill="#FF5252"/>
91
+ <path class="a ln" style="animation-name: c_sm0" d="M 607 300 V327" pathLength="1" stroke-dasharray="1 1" fill="none" stroke="#FF5252" stroke-width="2.5"/>
92
+ <path class="a ln" style="animation-name: c_sm1" d="M 951 300 V327" pathLength="1" stroke-dasharray="1 1" fill="none" stroke="#B9AAAE" stroke-width="2.5"/>
93
+ <path class="a" style="animation-name: h_sm0" d="M 600.5 324 L607 335 L613.5 324 Z" fill="#FF5252"/>
94
+ <path class="a" style="animation-name: h_sm1" d="M 944.5 324 L951 335 L957.5 324 Z" fill="#B9AAAE"/>
95
+ <g class="a" style="animation-name: c_sub"><path d="M 607 420 H690 V439" fill="none" stroke="#B9AAAE" stroke-width="2.5" stroke-dasharray="7 6"/><path d="M 683.5 436 L690 447 L696.5 436 Z" fill="#B9AAAE"/></g>
96
+ <path class="a ln" style="animation-name: c_fk" d="M 607 392 V420 H515 V439" pathLength="1" stroke-dasharray="1 1" fill="none" stroke="#FF5252" stroke-width="2.5" stroke-linejoin="round"/>
97
+ <path class="a" style="animation-name: h_fk" d="M 508.5 436 L515 447 L521.5 436 Z" fill="#FF5252"/>
98
+ <g class="a" style="animation-name: dev"><rect class="a" style="animation-name: dev_hl" x="663" y="100" width="232" height="72" rx="12" fill="#21191B" stroke="#FF5252" stroke-width="2.5"/><use href="#g-server" x="685" y="116" width="58" height="40"/><text x="759" y="145" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#F3EDEE">mac-mini</text></g>
99
+ <g class="a" style="animation-name: s0"><rect class="a" style="animation-name: s0_hl" x="462" y="232" width="290" height="68" rx="12" fill="#21191B" stroke="#FF5252" stroke-width="2.5"/><use href="#g-folder" x="478" y="249" width="44" height="34"/><text x="534" y="274" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="22" fill="#F3EDEE">api-refactor</text><use href="#g-db" x="706" y="247" width="30" height="38"/></g>
100
+ <g class="a" style="animation-name: s1"><rect x="792" y="232" width="318" height="68" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/><use href="#g-folder" x="808" y="249" width="44" height="34"/><text x="864" y="274" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="22" fill="#F3EDEE">nightly-report</text><use href="#g-db" x="1064" y="247" width="30" height="38"/></g>
101
+ <g class="a" style="animation-name: m0"><use href="#g-pi" x="579" y="336" width="56" height="56"/><text x="649" y="372" font-size="24" fill="#F3EDEE">Main</text></g>
102
+ <g class="a" style="animation-name: m1"><use href="#g-pi" x="923" y="336" width="56" height="56"/><text x="993" y="372" font-size="24" fill="#F3EDEE">Main</text></g>
103
+ <g class="a" style="animation-name: k0"><use href="#g-pi" x="489" y="448" width="52" height="52"/><text x="555" y="482" font-size="24" fill="#F3EDEE">fork</text></g>
104
+ <g class="a" style="animation-name: k1"><use href="#g-pi" x="664" y="448" width="52" height="52"/><text x="730" y="482" font-size="24" fill="#F3EDEE">subagent</text></g>
105
+ <g class="a" style="animation-name: strip">
106
+ <rect x="48" y="530" width="1104" height="96" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
107
+ <use href="#g-terminal" x="72" y="552" width="58" height="42"/>
108
+ <text class="a" style="animation-name: t0" x="152" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#F3EDEE" textLength="57.6" lengthAdjust="spacing">just</text>
109
+ <text class="a" style="animation-name: t1" x="224" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#F3EDEE" textLength="43.2" lengthAdjust="spacing">tui</text>
110
+ <text class="a" style="animation-name: t2" x="281.6" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#F3EDEE" textLength="86.4" lengthAdjust="spacing">attach</text>
111
+ <g class="a" style="animation-name: t3"><text class="a" style="animation-name: seg0" x="382.4" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#FF5252" textLength="115.2" lengthAdjust="spacing">mac-mini</text></g>
112
+ <text class="a" style="animation-name: t4" x="497.6" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#B9AAAE">:</text>
113
+ <g class="a" style="animation-name: t5"><text class="a" style="animation-name: seg1" x="512" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#FF5252" textLength="172.8" lengthAdjust="spacing">api-refactor</text></g>
114
+ <text class="a" style="animation-name: t6" x="684.8" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#B9AAAE">:</text>
115
+ <g class="a" style="animation-name: t7"><text class="a" style="animation-name: seg2" x="699.2" y="568" font-family="'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace" font-size="24" fill="#FF5252" textLength="57.6" lengthAdjust="spacing">fork</text></g>
116
+ <path class="a" style="animation-name: ul0" d="M 383.4 578 H496.6" pathLength="1" stroke-dasharray="1 1" stroke="#FF5252" stroke-width="2"/>
117
+ <g class="a" style="animation-name: an0"><text x="440" y="604" text-anchor="middle" font-size="20" fill="#B9AAAE">device</text></g>
118
+ <path class="a" style="animation-name: ul1" d="M 513 578 H683.8" pathLength="1" stroke-dasharray="1 1" stroke="#FF5252" stroke-width="2"/>
119
+ <g class="a" style="animation-name: an1"><text x="504.8" y="604" text-anchor="middle" font-size="20" fill="#B9AAAE">:</text><text x="598.4" y="604" text-anchor="middle" font-size="20" fill="#B9AAAE">session</text></g>
120
+ <path class="a" style="animation-name: ul2" d="M 700.2 578 H755.8" pathLength="1" stroke-dasharray="1 1" stroke="#FF5252" stroke-width="2"/>
121
+ <g class="a" style="animation-name: an2"><text x="692" y="604" text-anchor="middle" font-size="20" fill="#B9AAAE">:</text><text x="728" y="604" text-anchor="middle" font-size="20" fill="#B9AAAE">agent</text></g>
122
+ </g>
123
+ </svg>
@@ -0,0 +1,143 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 588" width="1200" height="588" role="img" aria-labelledby="title desc" font-family="Inter, 'Segoe UI', Helvetica, Arial, sans-serif">
2
+ <title id="title">Smaller context. Full history retained.</title>
3
+ <desc id="desc">All ten entries stay in stored history while the model context is compacted to a summary of entries 1 to 7 plus recent entries 8 to 10: the summary starts in the background at 200k tokens, compaction blocks at 250k, and search_history still reads every stored entry.</desc>
4
+ <style>
5
+ .mono { font-family: 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace; }
6
+ @keyframes h1 { 0%, 3.08% { opacity: 0; transform: scale(0.7) } 4.33% { opacity: 1; transform: scale(1.12) } 5%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
7
+ .h1 { animation: h1 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
8
+ @keyframes c1 { 0%, 4% { opacity: 0; transform: translateX(0) scale(.6) } 5.92%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(172px) scale(.6) } }
9
+ .c1 { animation: c1 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
10
+ @keyframes h2 { 0%, 6.54% { opacity: 0; transform: scale(0.7) } 7.79% { opacity: 1; transform: scale(1.12) } 8.46%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
11
+ .h2 { animation: h2 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
12
+ @keyframes c2 { 0%, 7.46% { opacity: 0; transform: translateX(0) scale(.6) } 9.38%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(115px) scale(.6) } }
13
+ .c2 { animation: c2 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
14
+ @keyframes h3 { 0%, 10% { opacity: 0; transform: scale(0.7) } 11.25% { opacity: 1; transform: scale(1.12) } 11.92%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
15
+ .h3 { animation: h3 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
16
+ @keyframes c3 { 0%, 10.92% { opacity: 0; transform: translateX(0) scale(.6) } 12.85%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(57px) scale(.6) } }
17
+ .c3 { animation: c3 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
18
+ @keyframes h4 { 0%, 13.46% { opacity: 0; transform: scale(0.7) } 14.71% { opacity: 1; transform: scale(1.12) } 15.38%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
19
+ .h4 { animation: h4 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
20
+ @keyframes c4 { 0%, 14.38% { opacity: 0; transform: translateX(0) scale(.6) } 16.31%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(0px) scale(.6) } }
21
+ .c4 { animation: c4 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
22
+ @keyframes h5 { 0%, 16.92% { opacity: 0; transform: scale(0.7) } 18.17% { opacity: 1; transform: scale(1.12) } 18.85%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
23
+ .h5 { animation: h5 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
24
+ @keyframes c5 { 0%, 17.85% { opacity: 0; transform: translateX(0) scale(.6) } 19.77%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(-57px) scale(.6) } }
25
+ .c5 { animation: c5 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
26
+ @keyframes h6 { 0%, 20.38% { opacity: 0; transform: scale(0.7) } 21.63% { opacity: 1; transform: scale(1.12) } 22.31%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
27
+ .h6 { animation: h6 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
28
+ @keyframes c6 { 0%, 21.31% { opacity: 0; transform: translateX(0) scale(.6) } 23.23%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(-115px) scale(.6) } }
29
+ .c6 { animation: c6 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
30
+ @keyframes h7 { 0%, 23.85% { opacity: 0; transform: scale(0.7) } 25.1% { opacity: 1; transform: scale(1.12) } 25.77%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
31
+ .h7 { animation: h7 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
32
+ @keyframes c7 { 0%, 24.77% { opacity: 0; transform: translateX(0) scale(.6) } 26.69%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(-172px) scale(.6) } }
33
+ .c7 { animation: c7 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
34
+ @keyframes h8 { 0%, 30% { opacity: 0; transform: scale(0.7) } 31.25% { opacity: 1; transform: scale(1.12) } 31.92%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
35
+ .h8 { animation: h8 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
36
+ @keyframes c8 { 0%, 30.92% { opacity: 0; transform: translateX(0) scale(.6) } 32.85%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(57px) scale(.6) } }
37
+ .c8 { animation: c8 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
38
+ @keyframes h9 { 0%, 33.46% { opacity: 0; transform: scale(0.7) } 34.71% { opacity: 1; transform: scale(1.12) } 35.38%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
39
+ .h9 { animation: h9 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
40
+ @keyframes c9 { 0%, 34.38% { opacity: 0; transform: translateX(0) scale(.6) } 36.31%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(0px) scale(.6) } }
41
+ .c9 { animation: c9 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
42
+ @keyframes h10 { 0%, 36.92% { opacity: 0; transform: scale(0.7) } 38.17% { opacity: 1; transform: scale(1.12) } 38.85%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.7) } }
43
+ .h10 { animation: h10 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
44
+ @keyframes c10 { 0%, 37.85% { opacity: 0; transform: translateX(0) scale(.6) } 39.77%, 42.69% { opacity: 1; transform: translateX(0) scale(1) } 45%, 100% { opacity: 0; transform: translateX(-57px) scale(.6) } }
45
+ .c10 { animation: c10 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
46
+ @keyframes meter { 0%, 4% { transform: scaleX(0) } 5.92%, 7.46% { transform: scaleX(0.408) } 9.38%, 10.92% { transform: scaleX(0.816) } 12.85%, 14.38% { transform: scaleX(1.224) } 16.31%, 17.85% { transform: scaleX(1.633) } 19.77%, 21.31% { transform: scaleX(2.041) } 23.23%, 24.77% { transform: scaleX(2.449) } 26.69%, 30.92% { transform: scaleX(2.857) } 32.85%, 34.38% { transform: scaleX(3.000) } 36.31%, 37.85% { transform: scaleX(3.143) } 39.77%, 45% { transform: scaleX(3.286) } 49.62%, 96% { transform: scaleX(1) } 100% { transform: scaleX(0) } }
47
+ .meter { animation: meter 13s ease-in-out infinite; transform-box: fill-box; transform-origin: left center; }
48
+ @keyframes chip { 0%, 26.54% { opacity: 0 } 28.85%, 48.46% { opacity: 1 } 50.77%, 100% { opacity: 0 } }
49
+ .chip { animation: chip 13s ease-in-out infinite; }
50
+ @keyframes brk { 0%, 39.23% { opacity: 0 } 41.15%, 96% { opacity: 1 } 100% { opacity: 0 } }
51
+ .brk { animation: brk 13s ease-in-out infinite; }
52
+ @keyframes arA { 0%, 40% { stroke-dashoffset: 93.0 } 43.08%, 96% { stroke-dashoffset: 0 } 100% { stroke-dashoffset: 93.0 } }
53
+ .arA { animation: arA 13s ease-in-out infinite; }
54
+ @keyframes arAh { 0%, 42.69% { opacity: 0 } 43.46%, 96% { opacity: 1 } 100% { opacity: 0 } }
55
+ .arAh { animation: arAh 13s ease-in-out infinite; }
56
+ @keyframes arB { 0%, 40% { stroke-dashoffset: 93.0 } 43.08%, 96% { stroke-dashoffset: 0 } 100% { stroke-dashoffset: 93.0 } }
57
+ .arB { animation: arB 13s ease-in-out infinite; }
58
+ @keyframes arBh { 0%, 42.69% { opacity: 0 } 43.46%, 96% { opacity: 1 } 100% { opacity: 0 } }
59
+ .arBh { animation: arBh 13s ease-in-out infinite; }
60
+ @keyframes sum { 0%, 44.62% { opacity: 0; transform: scale(0.8) } 46.37% { opacity: 1; transform: scale(1.12) } 47.31%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.8) } }
61
+ .sum { animation: sum 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
62
+ @keyframes rec { 0%, 44.62% { opacity: 0; transform: scale(0.8) } 46.37% { opacity: 1; transform: scale(1.12) } 47.31%, 96% { opacity: 1; transform: scale(1) } 100% { opacity: 0; transform: scale(0.8) } }
63
+ .rec { animation: rec 13s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
64
+ @media (prefers-reduced-motion: reduce) { * { animation: none !important; } }
65
+ </style>
66
+ <defs>
67
+ <marker id="ah-muted" viewBox="0 0 12 12" refX="4" refY="6" markerWidth="12" markerHeight="12" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 1 L12 6 L0 11 Z" fill="#B9AAAE"/></marker>
68
+ <clipPath id="track"><rect x="300" y="410" width="808" height="12" rx="6"/></clipPath>
69
+ </defs>
70
+
71
+ <rect width="1200" height="588" rx="18" fill="#141011"/>
72
+ <text x="48" y="70" font-size="34" font-weight="600" fill="#F3EDEE">Smaller context. Full history retained.</text>
73
+
74
+ <!-- Stored history keeps every entry -->
75
+ <rect x="48" y="100" width="1104" height="116" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
76
+ <text x="72" y="159" font-size="20" letter-spacing="1" fill="#B9AAAE">STORED HISTORY</text>
77
+ <g class="h1"><rect x="300" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="335" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">1</text></g>
78
+ <g class="h2"><rect x="382" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="417" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">2</text></g>
79
+ <g class="h3"><rect x="464" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="499" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">3</text></g>
80
+ <g class="h4"><rect x="546" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="581" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">4</text></g>
81
+ <g class="h5"><rect x="628" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="663" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">5</text></g>
82
+ <g class="h6"><rect x="710" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="745" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">6</text></g>
83
+ <g class="h7"><rect x="792" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="827" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">7</text></g>
84
+ <g class="h8"><rect x="874" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="909" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">8</text></g>
85
+ <g class="h9"><rect x="956" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="991" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">9</text></g>
86
+ <g class="h10"><rect x="1038" y="124" width="70" height="56" rx="8" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="1073" y="160" text-anchor="middle" font-size="22" fill="#F3EDEE">10</text></g>
87
+ <g class="brk" stroke="#B9AAAE" stroke-width="2" fill="none">
88
+ <path d="M304 190 V198 H858 V190"/>
89
+ <path d="M878 190 V198 H1104 V190"/>
90
+ </g>
91
+
92
+ <!-- Background summary while entries keep arriving -->
93
+ <g class="chip" opacity="0">
94
+ <rect x="612" y="228" width="357" height="36" rx="18" fill="#21191B" stroke="#FF5252" stroke-width="2"/>
95
+ <text x="790.5" y="253" text-anchor="middle" font-size="20" fill="#F3EDEE">summarizing in the background</text>
96
+ </g>
97
+
98
+ <!-- Model context: copied from the history as summary + recent entries -->
99
+ <rect x="48" y="276" width="1104" height="204" rx="12" fill="#21191B" stroke="#443438" stroke-width="2"/>
100
+ <text x="72" y="350" font-size="20" letter-spacing="1" fill="#B9AAAE">MODEL CONTEXT</text>
101
+ <path class="arA" d="M581 198 L581 290" stroke="#B9AAAE" stroke-width="2.5" fill="none" stroke-dasharray="93.0"/>
102
+ <path class="arAh" d="M581 289 L581 290" stroke="#B9AAAE" stroke-width="2.5" fill="none" marker-end="url(#ah-muted)"/>
103
+ <path class="arB" d="M991 198 L991 290" stroke="#B9AAAE" stroke-width="2.5" fill="none" stroke-dasharray="93.0"/>
104
+ <path class="arBh" d="M991 289 L991 290" stroke="#B9AAAE" stroke-width="2.5" fill="none" marker-end="url(#ah-muted)"/>
105
+ <g class="c1" opacity="0"><rect x="312" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="335" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">1</text></g>
106
+ <g class="c2" opacity="0"><rect x="394" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="417" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">2</text></g>
107
+ <g class="c3" opacity="0"><rect x="476" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="499" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">3</text></g>
108
+ <g class="c4" opacity="0"><rect x="558" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="581" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">4</text></g>
109
+ <g class="c5" opacity="0"><rect x="640" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="663" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">5</text></g>
110
+ <g class="c6" opacity="0"><rect x="722" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="745" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">6</text></g>
111
+ <g class="c7" opacity="0"><rect x="804" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="827" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">7</text></g>
112
+ <g class="c8" opacity="0"><rect x="886" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="909" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">8</text></g>
113
+ <g class="c9" opacity="0"><rect x="968" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="991" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">9</text></g>
114
+ <g class="c10" opacity="0"><rect x="1050" y="320" width="46" height="46" rx="6" fill="#141011" stroke="#B9AAAE" stroke-width="2"/><text class="mono" x="1073" y="350" text-anchor="middle" font-size="20" fill="#B9AAAE">10</text></g>
115
+ <g class="sum">
116
+ <rect x="461" y="300" width="240" height="86" rx="10" fill="#141011" stroke="#FF5252" stroke-width="2"/>
117
+ <text x="581" y="336" text-anchor="middle" font-size="22" fill="#F3EDEE">SUMMARY</text>
118
+ <text x="581" y="365" text-anchor="middle" font-size="20" fill="#B9AAAE">entries 1–7</text>
119
+ </g>
120
+ <g class="rec">
121
+ <rect x="874" y="300" width="234" height="86" rx="10" fill="#141011" stroke="#FF5252" stroke-width="2"/>
122
+ <text x="991" y="336" text-anchor="middle" font-size="22" fill="#F3EDEE">RECENT ENTRIES</text>
123
+ <text x="991" y="365" text-anchor="middle" font-size="20" fill="#B9AAAE">8–10</text>
124
+ </g>
125
+
126
+ <!-- Context meter: 0 to 250k tokens -->
127
+ <rect x="300" y="410" width="808" height="12" rx="6" fill="#141011" stroke="#443438" stroke-width="1.5"/>
128
+ <g clip-path="url(#track)">
129
+ <rect class="meter" x="300" y="410" width="226" height="12" fill="#FF5252"/>
130
+ </g>
131
+ <path d="M946 400 V432" stroke="#FF5252" stroke-width="2.5"/>
132
+ <path d="M1108 400 V432" stroke="#B9AAAE" stroke-width="2.5"/>
133
+ <text class="mono" x="946" y="458" text-anchor="middle" font-size="20" fill="#FF5252">200k</text>
134
+ <text class="mono" x="1108" y="458" text-anchor="end" font-size="20" fill="#B9AAAE">250k</text>
135
+
136
+ <!-- Notes -->
137
+ <path d="M75 506 V528" stroke="#FF5252" stroke-width="3"/>
138
+ <text x="92" y="524" font-size="22" fill="#B9AAAE">Background summary at 200k tokens</text>
139
+ <path d="M75 540 V562" stroke="#B9AAAE" stroke-width="3"/>
140
+ <text x="92" y="558" font-size="22" fill="#B9AAAE">Blocks at 250k</text>
141
+ <rect x="601" y="509" width="15" height="15" rx="3" fill="none" stroke="#B9AAAE" stroke-width="2"/>
142
+ <text x="628" y="524" font-size="22" fill="#B9AAAE"><tspan class="mono">search_history</tspan> still reads every entry</text>
143
+ </svg>