@pheem49/mint 1.16.0 → 1.18.0

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 (984) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +2 -2
  3. package/README.md +8 -2
  4. package/Release_Note.md +222 -72
  5. package/apps/mint-companion/src-tauri/src/compact.rs +69 -0
  6. package/apps/mint-companion/src-tauri/src/main.rs +218 -11
  7. package/apps/mint-companion/vite.config.ts +2 -1
  8. package/crates/mint-cli/src/agent/diff_render.rs +66 -44
  9. package/crates/mint-cli/src/agent/live_status.rs +64 -6
  10. package/crates/mint-cli/src/agent/markdown_render.rs +342 -5
  11. package/crates/mint-cli/src/agent.rs +202 -47
  12. package/crates/mint-cli/src/commands/agent.rs +223 -117
  13. package/crates/mint-cli/src/commands/browser.rs +114 -0
  14. package/crates/mint-cli/src/commands/config.rs +14 -1
  15. package/crates/mint-cli/src/commands/integrations.rs +3 -3
  16. package/crates/mint-cli/src/commands/knowledge.rs +16 -2
  17. package/crates/mint-cli/src/commands/mod.rs +15 -4
  18. package/crates/mint-cli/src/commands/tailnet_web.rs +3 -7
  19. package/crates/mint-cli/src/companion_navigation.rs +268 -0
  20. package/crates/mint-cli/src/interactive/chat_tui/dialog.rs +572 -0
  21. package/crates/mint-cli/src/interactive/chat_tui/mod.rs +1427 -0
  22. package/crates/mint-cli/src/interactive/chat_tui/render.rs +1524 -0
  23. package/crates/mint-cli/src/interactive/chat_tui/selection.rs +401 -0
  24. package/crates/mint-cli/src/interactive/chat_tui/state.rs +1833 -0
  25. package/crates/mint-cli/src/interactive/chat_tui/tests.rs +3414 -0
  26. package/crates/mint-cli/src/interactive/chat_tui/thought.rs +202 -0
  27. package/crates/mint-cli/src/interactive/chat_tui/transcript.rs +728 -0
  28. package/crates/mint-cli/src/interactive/chat_tui/watermark.rs +148 -0
  29. package/crates/mint-cli/src/interactive/command_ui.rs +92 -5
  30. package/crates/mint-cli/src/interactive/composer.rs +186 -0
  31. package/crates/mint-cli/src/interactive/format.rs +78 -3
  32. package/crates/mint-cli/src/interactive/input_box.rs +61 -1
  33. package/crates/mint-cli/src/interactive/resume_picker.rs +367 -25
  34. package/crates/mint-cli/src/interactive/slash_commands.rs +758 -373
  35. package/crates/mint-cli/src/interactive/tool_activity.rs +468 -56
  36. package/crates/mint-cli/src/interactive.rs +74 -5
  37. package/crates/mint-cli/src/main.rs +26 -2
  38. package/crates/mint-cli/src/markdown.rs +2 -37
  39. package/crates/mint-cli/src/onboard.rs +3897 -1321
  40. package/crates/mint-cli/src/setup.rs +1342 -624
  41. package/crates/mint-cli/src/terminal_theme.rs +159 -35
  42. package/crates/mint-cli/tests/library_intake.rs +1 -0
  43. package/crates/mint-cli/tests/mods_testing.rs +5 -1
  44. package/crates/mint-companion-protocol/src/lib.rs +113 -0
  45. package/crates/mint-core/src/agent/chat/anthropic.rs +318 -0
  46. package/crates/mint-core/src/agent/chat/custom.rs +149 -0
  47. package/crates/mint-core/src/agent/chat/gemini.rs +518 -0
  48. package/crates/mint-core/src/agent/chat/mod.rs +857 -0
  49. package/crates/mint-core/src/agent/chat/ollama.rs +321 -0
  50. package/crates/mint-core/src/agent/chat/openai.rs +582 -0
  51. package/crates/mint-core/src/agent/chat/streaming.rs +469 -0
  52. package/crates/mint-core/src/agent/chat/tests.rs +1479 -0
  53. package/crates/mint-core/src/agent/memory.rs +129 -8
  54. package/crates/mint-core/src/agent/safety.rs +56 -4
  55. package/crates/mint-core/src/agent/skill_inventory.rs +3 -1
  56. package/crates/mint-core/src/agent/skills.rs +1 -0
  57. package/crates/mint-core/src/agent/tasks.rs +2 -2
  58. package/crates/mint-core/src/api_server/routes/auth.rs +1 -4
  59. package/crates/mint-core/src/api_server/routes/chat.rs +53 -17
  60. package/crates/mint-core/src/api_server/routes/gemini_live.rs +14 -1
  61. package/crates/mint-core/src/api_server/routes/html_preview.rs +1 -8
  62. package/crates/mint-core/src/api_server/routes/misc.rs +116 -0
  63. package/crates/mint-core/src/api_server/routes/profile_oauth.rs +43 -26
  64. package/crates/mint-core/src/api_server/routes/sessions.rs +114 -76
  65. package/crates/mint-core/src/api_server/routes/skills_subagents.rs +11 -7
  66. package/crates/mint-core/src/api_server/routes/status_health.rs +18 -8
  67. package/crates/mint-core/src/api_server.rs +211 -65
  68. package/crates/mint-core/src/avatar_bridge.rs +5 -24
  69. package/crates/mint-core/src/browser/cdp.rs +92 -30
  70. package/crates/mint-core/src/browser/headless.rs +582 -0
  71. package/crates/mint-core/src/browser/input.rs +7 -62
  72. package/crates/mint-core/src/browser/interact.rs +0 -14
  73. package/crates/mint-core/src/browser/mod.rs +10 -30
  74. package/crates/mint-core/src/browser/navigate.rs +83 -44
  75. package/crates/mint-core/src/browser/runtime.rs +282 -0
  76. package/crates/mint-core/src/browser/session.rs +240 -400
  77. package/crates/mint-core/src/browser/workflow.rs +496 -0
  78. package/crates/mint-core/src/companion/navigation.rs +115 -0
  79. package/crates/mint-core/src/companion.rs +109 -1
  80. package/crates/mint-core/src/cron/store.rs +2 -2
  81. package/crates/mint-core/src/integrations/mcp.rs +6 -8
  82. package/crates/mint-core/src/integrations/mcp_result.rs +45 -0
  83. package/crates/mint-core/src/lib.rs +10 -11
  84. package/crates/mint-core/src/media/gemini_live.rs +636 -86
  85. package/crates/mint-core/src/media/image_proxy.rs +563 -0
  86. package/crates/mint-core/src/media/library/migration.rs +26 -0
  87. package/crates/mint-core/src/media/library/tests.rs +1 -1
  88. package/crates/mint-core/src/media/library/thumbnails.rs +8 -2
  89. package/crates/mint-core/src/media/pictures.rs +1 -1
  90. package/crates/mint-core/src/media/tool_images.rs +287 -0
  91. package/crates/mint-core/src/media/tts/playback.rs +609 -0
  92. package/crates/mint-core/src/media/tts.rs +1 -0
  93. package/crates/mint-core/src/media.rs +2 -0
  94. package/crates/mint-core/src/mods/manager.rs +101 -35
  95. package/crates/mint-core/src/orchestration/context_render.rs +878 -44
  96. package/crates/mint-core/src/orchestration/decision_parsing.rs +536 -39
  97. package/crates/mint-core/src/orchestration/diagnostics.rs +307 -0
  98. package/crates/mint-core/src/orchestration/full_skill_result_tests.rs +12 -0
  99. package/crates/mint-core/src/orchestration/image_regressions.rs +379 -0
  100. package/crates/mint-core/src/orchestration/loop_guard.rs +479 -0
  101. package/crates/mint-core/src/orchestration/mcp_outcome_tests.rs +864 -0
  102. package/crates/mint-core/src/orchestration/memory_skill.rs +88 -28
  103. package/crates/mint-core/src/orchestration/mod.rs +859 -4244
  104. package/crates/mint-core/src/orchestration/reliability.rs +581 -0
  105. package/crates/mint-core/src/orchestration/repeated_failures.rs +8 -0
  106. package/crates/mint-core/src/orchestration/review_regressions.rs +179 -28
  107. package/crates/mint-core/src/orchestration/tests.rs +1665 -0
  108. package/crates/mint-core/src/orchestration/tools/dispatch.rs +967 -0
  109. package/crates/mint-core/src/orchestration/tools/files.rs +32 -3
  110. package/crates/mint-core/src/orchestration/tools/mod.rs +5 -1
  111. package/crates/mint-core/src/orchestration/tools/planning.rs +102 -42
  112. package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +19 -4
  113. package/crates/mint-core/src/orchestration/tools/project.rs +1 -1
  114. package/crates/mint-core/src/orchestration/tools/shell.rs +157 -62
  115. package/crates/mint-core/src/orchestration/tools/web.rs +5 -1
  116. package/crates/mint-core/src/orchestration/trajectory_schema.rs +353 -0
  117. package/crates/mint-core/src/orchestration/truncation.rs +368 -0
  118. package/crates/mint-core/src/orchestration/types.rs +648 -0
  119. package/crates/mint-core/src/orchestration/verification.rs +36 -9
  120. package/crates/mint-core/src/orchestration/workspace_helpers.rs +76 -27
  121. package/crates/mint-core/src/prompts/agent.rs +69 -102
  122. package/crates/mint-core/src/prompts/tool_catalog.rs +104 -153
  123. package/crates/mint-core/src/search/files.rs +20 -0
  124. package/crates/mint-core/src/search/web_search.rs +44 -3
  125. package/crates/mint-core/src/slash/mod.rs +481 -55
  126. package/crates/mint-core/src/slash/models.rs +6 -1
  127. package/crates/mint-core/src/swarm/batch.rs +643 -0
  128. package/crates/mint-core/src/swarm/dossier.rs +152 -0
  129. package/crates/mint-core/src/swarm/labels.rs +100 -0
  130. package/crates/mint-core/src/swarm/mod.rs +158 -0
  131. package/crates/mint-core/src/swarm/permissions.rs +167 -0
  132. package/crates/mint-core/src/system/auth.rs +156 -7
  133. package/crates/mint-core/src/system/bg_shell.rs +78 -9
  134. package/crates/mint-core/src/system/config.rs +266 -35
  135. package/crates/mint-core/src/system/mint_web.rs +33 -12
  136. package/crates/mint-core/src/system/shell.rs +179 -10
  137. package/crates/mint-core/src/system/workspace.rs +204 -0
  138. package/crates/mint-core/tests/background_retention.rs +1 -1
  139. package/crates/mint-core/tests/memory_persistence.rs +27 -0
  140. package/crates/mint-mod-runtime/src/lib.rs +37 -23
  141. package/out/web/assets/ArtifactPreviewPanel-Cx6BVOOF.js +2 -0
  142. package/out/web/assets/ArtifactPreviewPanel-DAT_Y7i0.css +1 -0
  143. package/out/web/assets/CalculationCard-D2E74u5q.js +1 -0
  144. package/out/web/assets/CliSessionsView-ZbdtSjvK.css +1 -0
  145. package/out/web/assets/CliSessionsView-z5i6qGyb.js +1 -0
  146. package/out/web/assets/CodeReviewPage-BK2bOScd.css +1 -0
  147. package/out/web/assets/CodeReviewPage-Dp6zHuHu.js +2 -0
  148. package/out/web/assets/CommandPalette-DaKlzbKs.js +1 -0
  149. package/out/web/assets/ImageGenCard-BMCJHP9O.js +1 -0
  150. package/out/web/assets/ImageSearchCard-Cld_SOUg.js +1 -0
  151. package/out/web/assets/ImageStudioPanel-B5N7TjeB.js +1 -0
  152. package/out/web/assets/LibraryPage-CMB89rJ0.css +1 -0
  153. package/out/web/assets/LibraryPage-DbZEi4W_.js +2 -0
  154. package/out/web/assets/LinkedFoldersView-9B9DIPoZ.js +1 -0
  155. package/out/web/assets/McpRegistryPicker-DnXPlzI7.js +1 -0
  156. package/out/web/assets/McpServersView-CiNBNUl4.js +1 -0
  157. package/out/web/assets/MermaidCard-BBDNEXbY.js +2 -0
  158. package/out/web/assets/MintDashboard-C_UYPoNV.js +119 -0
  159. package/out/web/assets/MintDashboard-DTd8C_c8.css +1 -0
  160. package/out/web/assets/PlanCard-C2x5pajq.js +1 -0
  161. package/out/web/assets/PluginsView-DoTg9MVa.js +1 -0
  162. package/out/web/assets/RewindModal-B5oowrR0.js +1 -0
  163. package/out/web/assets/ScheduledTasksView-BD5DVPkZ.js +1 -0
  164. package/out/web/assets/SelectField-Cy6CghrU.js +1 -0
  165. package/out/web/assets/SelectField-lFEkkWCU.css +1 -0
  166. package/out/web/assets/SettingsWindow-BYl_oCFh.js +4 -0
  167. package/out/web/assets/SettingsWindow-Ckcgnjt8.css +1 -0
  168. package/out/web/assets/SkillsView-CIeWwq5z.js +2 -0
  169. package/out/web/assets/StockCard-DxUciKyp.js +1 -0
  170. package/out/web/assets/ToolSurfacePage-qBgs_VHq.css +1 -0
  171. package/out/web/assets/ToolSurfacePage-saVbVrkE.js +38 -0
  172. package/out/web/assets/UiFeatureCard-CdY0hGWy.js +1 -0
  173. package/out/web/assets/UiGridCard-BBK3I5hC.js +1 -0
  174. package/out/web/assets/UiMockupWidget-CpR9EDuc.js +1 -0
  175. package/out/web/assets/{VeoStudioPanel-DOj7_WR3.css → VeoStudioPanel-9kU9YLEN.css} +1 -1
  176. package/out/web/assets/VeoStudioPanel-Co6-wEWM.js +4 -0
  177. package/out/web/assets/WeatherCard-Buzi7Vfu.js +1 -0
  178. package/out/web/assets/WorkspacePanel-BfHKkulU.js +1 -0
  179. package/out/web/assets/WorkspacePdfPreview-Bi8Zzyir.js +2 -0
  180. package/out/web/assets/abnfDiagram-VCTEODGH-CMfR95N2.js +1 -0
  181. package/out/web/assets/architecture-7GRP2DOG-DhAM4HyO.js +1 -0
  182. package/out/web/assets/architectureDiagram-5GKGNRK7-Yk3TUJ_F.js +36 -0
  183. package/out/web/assets/{blockDiagram-NRAW4CY4-BrrqzHW5.js → blockDiagram-I7D4REHJ-X9fBgJik.js} +4 -4
  184. package/out/web/assets/c4Diagram-7LVT6UL2-Bk9x7N-8.js +38 -0
  185. package/out/web/assets/chunk-2Q5K7J3B-D2JLPQzF.js +1 -0
  186. package/out/web/assets/{chunk-TEH6E4GO-G4Cdlyrt.js → chunk-4HAMMTFA-Dx5fk1_0.js} +3 -3
  187. package/out/web/assets/{chunk-5VM5RSS4-BiPuE0io.js → chunk-5VM5RSS4-BZ2oBPYQ.js} +1 -1
  188. package/out/web/assets/chunk-75Z2AOVW-BszTQoM4.js +2 -0
  189. package/out/web/assets/chunk-DU6HZSFF-DK-As3rk.js +128 -0
  190. package/out/web/assets/chunk-F27PBJKO-LmncZZIS.js +1 -0
  191. package/out/web/assets/chunk-FOHPRMQF-JXEeeJ9r.js +161 -0
  192. package/out/web/assets/{chunk-GMAD6QVW-BuhEcgHq.js → chunk-GMAD6QVW-DSQ_sDRJ.js} +12 -12
  193. package/out/web/assets/chunk-GVQU2GXP-Cno3ulje.js +1 -0
  194. package/out/web/assets/chunk-IMKFNOWR-bIzfY9Jc.js +231 -0
  195. package/out/web/assets/chunk-JWPE2WC7-BeEMUFDw.js +1 -0
  196. package/out/web/assets/chunk-L3NEJ4N5-Dl6eOa0D.js +1 -0
  197. package/out/web/assets/chunk-OSK3NFVY-BaUGJ-cM.js +10 -0
  198. package/out/web/assets/chunk-P2QGCYS3-_066ndhH.js +1 -0
  199. package/out/web/assets/chunk-POPQ4Y6H-YT1AKhTv.js +1 -0
  200. package/out/web/assets/chunk-PWAF6VOD-CrEgDsxh.js +1 -0
  201. package/out/web/assets/chunk-SHT3W25Y-_KwaRLOl.js +168 -0
  202. package/out/web/assets/{chunk-SVP7TREG-Bu_yYb-V.js → chunk-SVP7TREG-BQ1qb32L.js} +1 -1
  203. package/out/web/assets/{chunk-LCL6LL3I-BhXV9zyH.js → chunk-TICWLB2K-BDyehCtg.js} +4 -4
  204. package/out/web/assets/chunk-XXDRQBXY-B9YlhOkE.js +1 -0
  205. package/out/web/assets/chunk-Y2CYZVJY-BxCWjNVG.js +1 -0
  206. package/out/web/assets/classDiagram-ZZMXUADV-BoSpzRCJ.js +1 -0
  207. package/out/web/assets/classDiagram-v2-VYDZK3BY-BoSpzRCJ.js +1 -0
  208. package/out/web/assets/config-2suVFPZg.css +1 -0
  209. package/out/web/assets/config-CkRCdkxn.js +2 -0
  210. package/out/web/assets/core-Mi3s5D4_.js +1 -0
  211. package/out/web/assets/cose-bilkent-JH36ORCC-qlna31ty.js +1 -0
  212. package/out/web/assets/cynefin-OW5HDTMX-Dl_31aaN.js +1 -0
  213. package/out/web/assets/cynefinDiagram-5FMLGOSQ-Bpir8jha.js +62 -0
  214. package/out/web/assets/cytoscape.esm-DWtAUG0r.js +321 -0
  215. package/out/web/assets/dagre-CnWJJM5f.js +1 -0
  216. package/out/web/assets/dagre-GXQ25YYZ-D9xu3nsq.js +4 -0
  217. package/out/web/assets/diagram-S7CK7UJ4-DeveoEeB.js +30 -0
  218. package/out/web/assets/diagram-UQ7AKVKN-p4xWRESV.js +41 -0
  219. package/out/web/assets/{diagram-VSXAHHWV-BJ86Ov2Y.js → diagram-VSXAHHWV-C7qz9NDF.js} +1 -1
  220. package/out/web/assets/diagram-VX7I27RA-DRiCa3Vd.js +24 -0
  221. package/out/web/assets/diagram-Z3DM3KII-Bt7zduQX.js +24 -0
  222. package/out/web/assets/dist-9ISJ7r-g.js +1 -0
  223. package/out/web/assets/dist-js-BV3mI7uw.js +1 -0
  224. package/out/web/assets/ebnfDiagram-PWID7BFC-DV9WpwdR.js +1 -0
  225. package/out/web/assets/{erDiagram-SSCWMZ5O-CzzmnZWT.js → erDiagram-RLTQ6QDP-BJ_nwG2m.js} +3 -3
  226. package/out/web/assets/event-D7D-EBy9.js +1 -0
  227. package/out/web/assets/eventmodeling-NTZA5JFV-BTBMrfVa.js +1 -0
  228. package/out/web/assets/flowDiagram-HODETNUW-Cdlq3cJL.js +1 -0
  229. package/out/web/assets/ganttDiagram-EL5Y4UJY-DQLdsXrC.js +292 -0
  230. package/out/web/assets/gitGraph-4MIJSDKK-CL1OEOQ_.js +1 -0
  231. package/out/web/assets/gitGraphDiagram-WWUBYQGX-8cSi42H7.js +106 -0
  232. package/out/web/assets/graphlib-Bh9gHply.js +1 -0
  233. package/out/web/assets/index-BocxnrDG.js +168 -0
  234. package/out/web/assets/index-yeh_r55a.css +1 -0
  235. package/out/web/assets/info-A6RAGUB7-C1zsX5sc.js +1 -0
  236. package/out/web/assets/infoDiagram-27XIBGKW-DsRYtIyI.js +2 -0
  237. package/out/web/assets/{ishikawaDiagram-5VMMS53U-s38yo28y.js → ishikawaDiagram-5VMMS53U-B2crwIXj.js} +4 -4
  238. package/out/web/assets/journeyDiagram-3NMN7TZE-BTH-GyVR.js +139 -0
  239. package/out/web/assets/jsx-runtime-DmUwWVTj.js +1 -0
  240. package/out/web/assets/{kanban-definition-3QL26DDD-DodjgySL.js → kanban-definition-UXKFOSKX-BeRfCnuA.js} +6 -6
  241. package/out/web/assets/katex-MCdQaEAD.js +257 -0
  242. package/out/web/assets/mermaid-parser.core-BJwgCBBc.js +7 -0
  243. package/out/web/assets/mermaid.core-CsDDodN8.js +44 -0
  244. package/out/web/assets/{mindmap-definition-FBJOCRG2-260WBDxZ.js → mindmap-definition-YA3MSWOX-B42efOQ1.js} +4 -4
  245. package/out/web/assets/modelManager-B3ZFMh8v.js +2 -0
  246. package/out/web/assets/oauthManager-Ch5Du2fF.js +1 -0
  247. package/out/web/assets/packet-AYTQ26CC-B6xUyE6r.js +1 -0
  248. package/out/web/assets/pdf-Bcahc2yC.js +56 -0
  249. package/out/web/assets/pdf.worker.min-Dkey6ZUl.mjs +27 -0
  250. package/out/web/assets/pegDiagram-XKGWAZYB-1LabVycL.js +1 -0
  251. package/out/web/assets/pie-WAS4IAKB-DJwo-nf_.js +1 -0
  252. package/out/web/assets/pieDiagram-E7YTZNPT-icmAqzy4.js +39 -0
  253. package/out/web/assets/{quadrantDiagram-AXDQQJYC-B8D3gU5d.js → quadrantDiagram-AXDQQJYC-CZ-wEx41.js} +4 -4
  254. package/out/web/assets/radar-RG4KPBEZ-D7d-Xriw.js +1 -0
  255. package/out/web/assets/railroad-74A4TZTK-viuhdYbs.js +1 -0
  256. package/out/web/assets/railroad-abnf-HS5TGJTU-DNXiCNea.js +1 -0
  257. package/out/web/assets/railroad-ebnf-LZEXJU2U-nkSu1-0C.js +1 -0
  258. package/out/web/assets/railroad-peg-WCYAUIDC-BhbMeQzz.js +1 -0
  259. package/out/web/assets/railroadDiagram-O6MQD6OU-CLpG1jUX.js +1 -0
  260. package/out/web/assets/{requirementDiagram-EFPCY7ZU-D2X-Ewik.js → requirementDiagram-BXWQKSXE-kRDrvWrc.js} +3 -3
  261. package/out/web/assets/rolldown-runtime-CNOWq4Kh.js +1 -0
  262. package/out/web/assets/rough.esm-CNnFptCR.js +1 -0
  263. package/out/web/assets/sankeyDiagram-P5KCCOFB-DxAwmq4x.js +40 -0
  264. package/out/web/assets/sequenceDiagram-WJ2MYXX4-aLgY-6Wz.js +162 -0
  265. package/out/web/assets/sizeCapture-INFHLROL-C8Q8DbV5.js +1 -0
  266. package/out/web/assets/src-CRDfRlHM.js +1 -0
  267. package/out/web/assets/stateDiagram-D77RDMKH-D5QWfOhp.js +1 -0
  268. package/out/web/assets/stateDiagram-v2-MP3YSRHH-D6OiZoAP.js +1 -0
  269. package/out/web/assets/studio-BBZQ_-QK.js +1 -0
  270. package/out/web/assets/swimlanes-42K2YHIH-CRs5UyA-.js +1 -0
  271. package/out/web/assets/swimlanesDiagram-VR7AAH4N-UgEXIsV0.js +8 -0
  272. package/out/web/assets/syntaxHighlight-C-wAGT84.js +3 -0
  273. package/out/web/assets/timeline-definition-24CTP7MA-Denqd9qb.js +120 -0
  274. package/out/web/assets/treeView-Q6P3EWNA-0my3Z3s4.js +1 -0
  275. package/out/web/assets/treemap-WGGIJYW6-B_EjkLYq.js +1 -0
  276. package/out/web/assets/vennDiagram-4TSXK5OY-DxVg3Ewr.js +34 -0
  277. package/out/web/assets/wardley-WFR3VGLG-CGD-Tj4p.js +1 -0
  278. package/out/web/assets/{wardleyDiagram-VM6X3IG4-DAdXELbQ.js → wardleyDiagram-VM6X3IG4-CmfS39Xm.js} +35 -35
  279. package/out/web/assets/window-CkUOP7t0.js +1 -0
  280. package/out/web/assets/workspaces-SYPrmbgC.js +1 -0
  281. package/out/web/assets/{xychartDiagram-S5SC5T6Z-IZIXf3Vo.js → xychartDiagram-S5SC5T6Z-BVM9bKis.js} +4 -4
  282. package/out/web/index-web.html +4 -4
  283. package/out/web/index.html +4 -4
  284. package/out/web/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  285. package/out/web/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  286. package/out/web/pdfjs/cmaps/78-H.bcmap +0 -0
  287. package/out/web/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  288. package/out/web/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  289. package/out/web/pdfjs/cmaps/78-V.bcmap +0 -0
  290. package/out/web/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  291. package/out/web/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  292. package/out/web/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  293. package/out/web/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  294. package/out/web/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  295. package/out/web/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  296. package/out/web/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  297. package/out/web/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  298. package/out/web/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  299. package/out/web/pdfjs/cmaps/Add-H.bcmap +0 -0
  300. package/out/web/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  301. package/out/web/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  302. package/out/web/pdfjs/cmaps/Add-V.bcmap +0 -0
  303. package/out/web/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  304. package/out/web/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  305. package/out/web/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  306. package/out/web/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  307. package/out/web/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  308. package/out/web/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  309. package/out/web/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  310. package/out/web/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  311. package/out/web/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  312. package/out/web/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  313. package/out/web/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  314. package/out/web/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  315. package/out/web/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  316. package/out/web/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  317. package/out/web/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  318. package/out/web/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  319. package/out/web/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  320. package/out/web/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  321. package/out/web/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  322. package/out/web/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  323. package/out/web/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  324. package/out/web/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  325. package/out/web/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  326. package/out/web/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  327. package/out/web/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  328. package/out/web/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  329. package/out/web/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  330. package/out/web/pdfjs/cmaps/B5-H.bcmap +0 -0
  331. package/out/web/pdfjs/cmaps/B5-V.bcmap +0 -0
  332. package/out/web/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  333. package/out/web/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  334. package/out/web/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  335. package/out/web/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  336. package/out/web/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  337. package/out/web/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  338. package/out/web/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  339. package/out/web/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  340. package/out/web/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  341. package/out/web/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  342. package/out/web/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  343. package/out/web/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  344. package/out/web/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  345. package/out/web/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  346. package/out/web/pdfjs/cmaps/EUC-H.bcmap +0 -0
  347. package/out/web/pdfjs/cmaps/EUC-V.bcmap +0 -0
  348. package/out/web/pdfjs/cmaps/Ext-H.bcmap +0 -0
  349. package/out/web/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  350. package/out/web/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  351. package/out/web/pdfjs/cmaps/Ext-V.bcmap +0 -0
  352. package/out/web/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  353. package/out/web/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  354. package/out/web/pdfjs/cmaps/GB-H.bcmap +4 -0
  355. package/out/web/pdfjs/cmaps/GB-V.bcmap +0 -0
  356. package/out/web/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  357. package/out/web/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  358. package/out/web/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  359. package/out/web/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  360. package/out/web/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  361. package/out/web/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  362. package/out/web/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  363. package/out/web/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  364. package/out/web/pdfjs/cmaps/GBT-H.bcmap +0 -0
  365. package/out/web/pdfjs/cmaps/GBT-V.bcmap +0 -0
  366. package/out/web/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  367. package/out/web/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  368. package/out/web/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  369. package/out/web/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  370. package/out/web/pdfjs/cmaps/H.bcmap +0 -0
  371. package/out/web/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  372. package/out/web/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  373. package/out/web/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  374. package/out/web/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  375. package/out/web/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  376. package/out/web/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  377. package/out/web/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  378. package/out/web/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  379. package/out/web/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  380. package/out/web/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  381. package/out/web/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  382. package/out/web/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  383. package/out/web/pdfjs/cmaps/Hankaku.bcmap +0 -0
  384. package/out/web/pdfjs/cmaps/Hiragana.bcmap +0 -0
  385. package/out/web/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  386. package/out/web/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  387. package/out/web/pdfjs/cmaps/KSC-H.bcmap +0 -0
  388. package/out/web/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  389. package/out/web/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  390. package/out/web/pdfjs/cmaps/KSC-V.bcmap +0 -0
  391. package/out/web/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  392. package/out/web/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  393. package/out/web/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  394. package/out/web/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  395. package/out/web/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  396. package/out/web/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  397. package/out/web/pdfjs/cmaps/Katakana.bcmap +0 -0
  398. package/out/web/pdfjs/cmaps/LICENSE +36 -0
  399. package/out/web/pdfjs/cmaps/NWP-H.bcmap +0 -0
  400. package/out/web/pdfjs/cmaps/NWP-V.bcmap +0 -0
  401. package/out/web/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  402. package/out/web/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  403. package/out/web/pdfjs/cmaps/Roman.bcmap +0 -0
  404. package/out/web/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  405. package/out/web/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  406. package/out/web/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  407. package/out/web/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  408. package/out/web/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  409. package/out/web/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  410. package/out/web/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  411. package/out/web/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  412. package/out/web/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  413. package/out/web/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  414. package/out/web/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  415. package/out/web/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  416. package/out/web/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  417. package/out/web/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  418. package/out/web/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  419. package/out/web/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  420. package/out/web/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  421. package/out/web/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  422. package/out/web/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  423. package/out/web/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  424. package/out/web/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  425. package/out/web/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  426. package/out/web/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  427. package/out/web/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  428. package/out/web/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  429. package/out/web/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  430. package/out/web/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  431. package/out/web/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  432. package/out/web/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  433. package/out/web/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  434. package/out/web/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  435. package/out/web/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  436. package/out/web/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  437. package/out/web/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  438. package/out/web/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  439. package/out/web/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  440. package/out/web/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  441. package/out/web/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  442. package/out/web/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  443. package/out/web/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  444. package/out/web/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  445. package/out/web/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  446. package/out/web/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  447. package/out/web/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  448. package/out/web/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  449. package/out/web/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  450. package/out/web/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  451. package/out/web/pdfjs/cmaps/V.bcmap +0 -0
  452. package/out/web/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  453. package/out/web/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  454. package/out/web/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  455. package/out/web/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  456. package/out/web/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  457. package/out/web/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  458. package/out/web/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  459. package/out/web/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  460. package/out/web/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  461. package/out/web/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  462. package/out/web/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  463. package/out/web/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  464. package/out/web/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
  465. package/out/web/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  466. package/out/web/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  467. package/out/web/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  468. package/out/web/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  469. package/out/web/pdfjs/wasm/LICENSE_JBIG2 +196 -0
  470. package/out/web/pdfjs/wasm/LICENSE_OPENJPEG +39 -0
  471. package/out/web/pdfjs/wasm/LICENSE_PDFJS_JBIG2 +13 -0
  472. package/out/web/pdfjs/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
  473. package/out/web/pdfjs/wasm/LICENSE_PDFJS_QCMS +19 -0
  474. package/out/web/pdfjs/wasm/LICENSE_QCMS +21 -0
  475. package/out/web/pdfjs/wasm/jbig2.wasm +0 -0
  476. package/out/web/pdfjs/wasm/jbig2_nowasm_fallback.js +15 -0
  477. package/out/web/pdfjs/wasm/openjpeg.wasm +0 -0
  478. package/out/web/pdfjs/wasm/openjpeg_nowasm_fallback.js +17 -0
  479. package/out/web/pdfjs/wasm/qcms_bg.wasm +0 -0
  480. package/out/web/pdfjs/wasm/quickjs-eval.js +16 -0
  481. package/out/web/pdfjs/wasm/quickjs-eval.wasm +0 -0
  482. package/package.json +6 -4
  483. package/shared-modules/CODEOWNERS +3 -3
  484. package/shared-modules/SDL2/SDL2_mixer.json +27 -0
  485. package/shared-modules/appstream/README.md +13 -0
  486. package/shared-modules/appstream/appstream-compose.json +111 -0
  487. package/shared-modules/dbus-glib/dbus-glib.json +2 -2
  488. package/shared-modules/libportal/libportal.json +23 -0
  489. package/shared-modules/linux-audio/fluidsynth2-static.json +2 -2
  490. package/shared-modules/linux-audio/fluidsynth2.json +2 -2
  491. package/shared-modules/linux-audio/libinstpatch.json +2 -2
  492. package/shared-modules/linux-audio/liblo-static.json +3 -0
  493. package/shared-modules/luajit/luajit.json +2 -2
  494. package/shared-modules/squashfs-tools/squashfs-tools.json +0 -3
  495. package/slash-commands.json +14 -3
  496. package/src/bin/index.js +4 -1
  497. package/src/bin/pdfjs-assets.mjs +31 -0
  498. package/src/renderer/node_modules/.vite/vitest/CACHEDIR.TAG +3 -0
  499. package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  500. package/src/renderer/shared/agentProgress.ts +62 -5
  501. package/src/renderer/shared/components/Settings/AgentsTab.tsx +70 -6
  502. package/src/renderer/shared/components/Settings/AudioTab.tsx +1 -1
  503. package/src/renderer/shared/components/Settings/AutomationTab.tsx +32 -29
  504. package/src/renderer/shared/components/Settings/AvatarCropModal.tsx +32 -12
  505. package/src/renderer/shared/components/Settings/CustomProviderLogoPicker.test.tsx +65 -0
  506. package/src/renderer/shared/components/Settings/CustomProviderLogoPicker.tsx +456 -0
  507. package/src/renderer/shared/components/Settings/GeneralTab.tsx +65 -94
  508. package/src/renderer/shared/components/Settings/PluginsTab.tsx +101 -24
  509. package/src/renderer/shared/components/Settings/ProfileTab.tsx +1 -1
  510. package/src/renderer/shared/components/Settings/SettingsWindow.tsx +796 -0
  511. package/src/renderer/shared/components/Settings/ThemeTab.test.tsx +45 -0
  512. package/src/renderer/shared/components/Settings/ThemeTab.tsx +119 -4
  513. package/src/renderer/shared/components/activity/AgentActivityDrawer.tsx +270 -0
  514. package/src/renderer/shared/components/activity/AgentActivityTable.tsx +582 -0
  515. package/src/renderer/shared/components/activity/AskUserActivityCard.test.tsx +122 -0
  516. package/src/renderer/shared/components/activity/AskUserActivityCard.tsx +70 -0
  517. package/src/renderer/shared/components/{McpToolResults.tsx → activity/McpToolResults.tsx} +69 -13
  518. package/src/renderer/shared/components/{PlanChecklistWidget.tsx → activity/PlanChecklistWidget.tsx} +2 -2
  519. package/src/renderer/shared/components/activity/RunSummaryDashboard.test.tsx +127 -0
  520. package/src/renderer/shared/components/activity/RunSummaryDashboard.tsx +222 -0
  521. package/src/renderer/shared/components/activity/SubagentDagView.test.ts +123 -0
  522. package/src/renderer/shared/components/{SubagentDagView.tsx → activity/SubagentDagView.tsx} +104 -50
  523. package/src/renderer/shared/components/activity/SubagentStatusStrip.test.tsx +82 -0
  524. package/src/renderer/shared/components/activity/SubagentStatusStrip.tsx +107 -0
  525. package/src/renderer/shared/components/activity/ViewedImages.tsx +179 -0
  526. package/src/renderer/shared/components/{AuthGate.tsx → app/AuthGate.tsx} +3 -3
  527. package/src/renderer/shared/components/{ChunkErrorBoundary.tsx → app/ChunkErrorBoundary.tsx} +13 -13
  528. package/src/renderer/shared/components/{CommandPalette.tsx → app/CommandPalette.tsx} +30 -30
  529. package/src/renderer/shared/components/{DashboardSidebar.tsx → app/DashboardSidebar.tsx} +7 -5
  530. package/src/renderer/shared/components/{DesktopTitlebar.tsx → app/DesktopTitlebar.tsx} +9 -26
  531. package/src/renderer/shared/components/{ErrorNotice.tsx → app/ErrorNotice.tsx} +1 -1
  532. package/src/renderer/shared/components/{MintDashboard.tsx → app/MintDashboard.tsx} +217 -228
  533. package/src/renderer/shared/components/{ModalErrorBoundary.tsx → app/ModalErrorBoundary.tsx} +8 -8
  534. package/src/renderer/shared/components/{CalculationCard.tsx → cards/CalculationCard.tsx} +16 -30
  535. package/src/renderer/shared/components/{ImageGenCard.tsx → cards/ImageGenCard.tsx} +11 -24
  536. package/src/renderer/shared/components/{ImageSearchCard.tsx → cards/ImageSearchCard.tsx} +11 -24
  537. package/src/renderer/shared/components/{MermaidCard.tsx → cards/MermaidCard.tsx} +38 -22
  538. package/src/renderer/shared/components/cards/PlanCard.test.tsx +41 -0
  539. package/src/renderer/shared/components/cards/PlanCard.tsx +32 -0
  540. package/src/renderer/shared/components/cards/ReleaseNotesCard.test.tsx +29 -0
  541. package/src/renderer/shared/components/cards/ReleaseNotesCard.tsx +137 -0
  542. package/src/renderer/shared/components/{StockCard.tsx → cards/StockCard.tsx} +22 -38
  543. package/src/renderer/shared/components/cards/ToolResultCards.tsx +94 -0
  544. package/src/renderer/shared/components/{UiFeatureCard.tsx → cards/UiFeatureCard.tsx} +6 -6
  545. package/src/renderer/shared/components/{UiGridCard.tsx → cards/UiGridCard.tsx} +3 -3
  546. package/src/renderer/shared/components/{UiMockupWidget.tsx → cards/UiMockupWidget.tsx} +4 -4
  547. package/src/renderer/shared/components/{WeatherCard.tsx → cards/WeatherCard.tsx} +6 -6
  548. package/src/renderer/shared/components/{ApprovalCard.test.tsx → chat/ApprovalCard.test.tsx} +12 -1
  549. package/src/renderer/shared/components/{ApprovalCard.tsx → chat/ApprovalCard.tsx} +26 -7
  550. package/src/renderer/shared/components/chat/ArtifactCards.test.tsx +69 -0
  551. package/src/renderer/shared/components/chat/ArtifactCards.tsx +238 -0
  552. package/src/renderer/shared/components/chat/AttachedDocumentCard.test.tsx +39 -0
  553. package/src/renderer/shared/components/chat/AttachedDocumentCard.tsx +220 -0
  554. package/src/renderer/shared/components/chat/ChatCodeBlock.test.tsx +33 -0
  555. package/src/renderer/shared/components/{ChatCodeBlock.tsx → chat/ChatCodeBlock.tsx} +16 -2
  556. package/src/renderer/shared/components/chat/ChatMessageItem.test.tsx +183 -0
  557. package/src/renderer/shared/components/chat/ChatMessageItem.tsx +388 -0
  558. package/src/renderer/shared/components/chat/ChatModeSelector.css +227 -0
  559. package/src/renderer/shared/components/chat/ChatModeSelector.test.tsx +45 -0
  560. package/src/renderer/shared/components/chat/ChatModeSelector.tsx +198 -0
  561. package/src/renderer/shared/components/chat/ChatPanel.test.tsx +53 -0
  562. package/src/renderer/shared/components/{ChatPanel.tsx → chat/ChatPanel.tsx} +462 -537
  563. package/src/renderer/shared/components/{CollapsiblePasteInput.tsx → chat/CollapsiblePasteInput.tsx} +2 -2
  564. package/src/renderer/shared/components/{DiffReviewModal.tsx → chat/DiffReviewModal.tsx} +44 -44
  565. package/src/renderer/shared/components/chat/GeminiLiveOverlay.test.tsx +165 -0
  566. package/src/renderer/shared/components/{GeminiLiveOverlay.tsx → chat/GeminiLiveOverlay.tsx} +47 -5
  567. package/src/renderer/shared/components/{ModelSelectorPopover.tsx → chat/ModelSelectorPopover.tsx} +44 -16
  568. package/src/renderer/shared/components/chat/QueuedMessagesBanner.test.tsx +89 -0
  569. package/src/renderer/shared/components/chat/QueuedMessagesBanner.tsx +201 -0
  570. package/src/renderer/shared/components/{RewindModal.tsx → chat/RewindModal.tsx} +14 -14
  571. package/src/renderer/shared/components/{SlashChoicePanel.tsx → chat/SlashChoicePanel.tsx} +2 -2
  572. package/src/renderer/shared/components/{SlashSuggestions.test.tsx → chat/SlashSuggestions.test.tsx} +14 -0
  573. package/src/renderer/shared/components/{SlashSuggestions.tsx → chat/SlashSuggestions.tsx} +4 -4
  574. package/src/renderer/shared/components/chat/SourcesBlock.test.tsx +53 -0
  575. package/src/renderer/shared/components/{SourcesBlock.tsx → chat/SourcesBlock.tsx} +262 -123
  576. package/src/renderer/shared/components/{ThinkingBlock.tsx → chat/ThinkingBlock.tsx} +1 -1
  577. package/src/renderer/shared/components/chat/TurnFileChanges.test.tsx +130 -0
  578. package/src/renderer/shared/components/chat/TurnFileChanges.tsx +463 -0
  579. package/src/renderer/shared/components/{VoicePill.css → chat/VoicePill.css} +1 -1
  580. package/src/renderer/shared/components/{VoicePill.jsx → chat/VoicePill.jsx} +3 -2
  581. package/src/renderer/shared/components/{CliSessionsView.test.tsx → extensions/CliSessionsView.test.tsx} +2 -2
  582. package/src/renderer/shared/components/{CliSessionsView.tsx → extensions/CliSessionsView.tsx} +19 -16
  583. package/src/renderer/shared/components/{LinkedFoldersView.tsx → extensions/LinkedFoldersView.tsx} +3 -3
  584. package/src/renderer/shared/components/{McpRegistryPicker.tsx → extensions/McpRegistryPicker.tsx} +6 -6
  585. package/src/renderer/shared/components/{McpServersView.tsx → extensions/McpServersView.tsx} +105 -36
  586. package/src/renderer/shared/components/{McpToolAllowlist.tsx → extensions/McpToolAllowlist.tsx} +2 -2
  587. package/src/renderer/shared/components/{ModUi.test.tsx → extensions/ModUi.test.tsx} +9 -4
  588. package/src/renderer/shared/components/{ModsPanel.tsx → extensions/ModsPanel.tsx} +59 -7
  589. package/src/renderer/shared/components/{PluginsView.tsx → extensions/PluginsView.tsx} +6 -6
  590. package/src/renderer/shared/components/{ScheduledTasksView.tsx → extensions/ScheduledTasksView.tsx} +5 -5
  591. package/src/renderer/shared/components/extensions/SkillsView.test.tsx +31 -0
  592. package/src/renderer/shared/components/{SkillsView.tsx → extensions/SkillsView.tsx} +20 -4
  593. package/src/renderer/shared/components/{ImageStudioPanel.tsx → studio/ImageStudioPanel.tsx} +6 -6
  594. package/src/renderer/shared/components/{LibraryItemCard.tsx → studio/LibraryItemCard.tsx} +2 -2
  595. package/src/renderer/shared/components/{LibraryPage.tsx → studio/LibraryPage.tsx} +53 -10
  596. package/src/renderer/shared/components/{LibraryPreview.tsx → studio/LibraryPreview.tsx} +2 -2
  597. package/src/renderer/shared/components/{VeoStudioPanel.tsx → studio/VeoStudioPanel.tsx} +7 -7
  598. package/src/renderer/shared/components/{GlideSelect.css → ui/GlideSelect.css} +7 -6
  599. package/src/renderer/shared/components/ui/ProviderBrandIcon.test.tsx +67 -0
  600. package/src/renderer/shared/components/ui/ProviderBrandIcon.tsx +167 -0
  601. package/src/renderer/shared/components/ui/SelectField.tsx +506 -0
  602. package/src/renderer/shared/components/ui/error-recovery.css +10 -10
  603. package/src/renderer/shared/components/ui/error-recovery.tsx +1 -1
  604. package/src/renderer/shared/components/{ArtifactPreviewPanel.tsx → workspace/ArtifactPreviewPanel.tsx} +374 -118
  605. package/src/renderer/shared/components/workspace/BackgroundTerminals.test.tsx +63 -0
  606. package/src/renderer/shared/components/{BackgroundTerminals.tsx → workspace/BackgroundTerminals.tsx} +40 -9
  607. package/src/renderer/shared/components/workspace/CodeReviewPage.test.tsx +50 -0
  608. package/src/renderer/shared/components/{CodeReviewPage.tsx → workspace/CodeReviewPage.tsx} +124 -24
  609. package/src/renderer/shared/components/{GitBranchSelector.tsx → workspace/GitBranchSelector.tsx} +80 -24
  610. package/src/renderer/shared/components/workspace/SessionSources.tsx +113 -0
  611. package/src/renderer/shared/components/{TerminalDock.tsx → workspace/TerminalDock.tsx} +5 -2
  612. package/src/renderer/shared/components/workspace/ToolSurfacePage.test.tsx +81 -0
  613. package/src/renderer/shared/components/{ToolSurfacePage.tsx → workspace/ToolSurfacePage.tsx} +361 -90
  614. package/src/renderer/shared/components/{ToolsPanelToggle.tsx → workspace/ToolsPanelToggle.tsx} +1 -1
  615. package/src/renderer/shared/components/workspace/WorkspaceFileInfo.tsx +28 -0
  616. package/src/renderer/shared/components/workspace/WorkspaceMediaPreview.tsx +17 -0
  617. package/src/renderer/shared/components/{WorkspacePaneResizer.tsx → workspace/WorkspacePaneResizer.tsx} +1 -1
  618. package/src/renderer/shared/components/workspace/WorkspacePdfPreview.tsx +308 -0
  619. package/src/renderer/shared/components/workspace/WorkspacePreviewActions.test.tsx +101 -0
  620. package/src/renderer/shared/components/{WorkspacePreviewActions.tsx → workspace/WorkspacePreviewActions.tsx} +3 -3
  621. package/src/renderer/shared/components/{WorkspaceSelector.tsx → workspace/WorkspaceSelector.tsx} +99 -7
  622. package/src/renderer/shared/components/{background-terminals.css → workspace/background-terminals.css} +11 -11
  623. package/src/renderer/shared/components/{workspace-selector.css → workspace/workspace-selector.css} +84 -2
  624. package/src/renderer/shared/constants/config.ts +6 -3
  625. package/src/renderer/shared/constants/models.test.ts +51 -0
  626. package/src/renderer/shared/constants/models.ts +139 -32
  627. package/src/renderer/shared/conversation/coordinator.test.ts +46 -0
  628. package/src/renderer/shared/conversation/coordinator.ts +50 -2
  629. package/src/renderer/shared/conversation/lifecycle.test.ts +254 -4
  630. package/src/renderer/shared/conversation/lifecycle.ts +268 -12
  631. package/src/renderer/shared/conversation/progressiveStream.test.ts +83 -0
  632. package/src/renderer/shared/conversation/progressiveStream.ts +219 -0
  633. package/src/renderer/shared/conversation/projectNavigation.test.ts +18 -0
  634. package/src/renderer/shared/conversation/projectNavigation.ts +11 -0
  635. package/src/renderer/shared/conversation/transport.test.ts +20 -0
  636. package/src/renderer/shared/conversation/transport.ts +51 -9
  637. package/src/renderer/shared/conversation/useConversationCoordinator.ts +42 -12
  638. package/src/renderer/shared/css/agent-observability.css +205 -11
  639. package/src/renderer/shared/css/chat-ui-cards.css +48 -48
  640. package/src/renderer/shared/css/code-review.css +139 -110
  641. package/src/renderer/shared/css/code-sessions.css +56 -27
  642. package/src/renderer/shared/css/collapsed-paste.css +1 -1
  643. package/src/renderer/shared/css/error-notice.css +1 -1
  644. package/src/renderer/shared/css/file-changes.css +298 -51
  645. package/src/renderer/shared/css/library.css +105 -10
  646. package/src/renderer/shared/css/management-views.css +79 -38
  647. package/src/renderer/shared/css/mcp-results.css +48 -5
  648. package/src/renderer/shared/css/model-selector.css +18 -18
  649. package/src/renderer/shared/css/mods.css +7 -7
  650. package/src/renderer/shared/css/notification-notice.css +2 -2
  651. package/src/renderer/shared/css/queued-messages.css +221 -0
  652. package/src/renderer/shared/css/session-sources.css +12 -7
  653. package/src/renderer/shared/css/settings/agents.css +2 -2
  654. package/src/renderer/{src → shared}/css/settings/base.css +101 -107
  655. package/src/renderer/shared/css/settings/general.css +397 -100
  656. package/src/renderer/shared/css/settings/plugins.css +8 -8
  657. package/src/renderer/shared/css/settings/profile.css +5 -5
  658. package/src/renderer/shared/css/settings/theme.css +49 -37
  659. package/src/renderer/shared/css/slash-choice.css +2 -2
  660. package/src/renderer/shared/css/slash-suggestions.css +3 -3
  661. package/src/renderer/shared/css/sources-block.css +41 -2
  662. package/src/renderer/shared/css/tools-panel.css +2 -2
  663. package/src/renderer/shared/css/ui-tailwind.css +10 -2
  664. package/src/renderer/shared/css/veo-studio.css +2 -2
  665. package/src/renderer/shared/css/viewed-images.css +93 -4
  666. package/src/renderer/shared/css/workspace-file-info.css +12 -0
  667. package/src/renderer/shared/css/workspace-media-preview.css +13 -0
  668. package/src/renderer/shared/env.d.ts +9 -0
  669. package/src/renderer/shared/platform.test.ts +143 -0
  670. package/src/renderer/shared/platform.ts +12 -5
  671. package/src/renderer/shared/speech/player.ts +160 -0
  672. package/src/renderer/shared/speech/types.ts +11 -0
  673. package/src/renderer/shared/theme/themeManager.test.ts +37 -0
  674. package/src/renderer/shared/theme/themeManager.ts +24 -5
  675. package/src/renderer/shared/theme/themes.ts +71 -4
  676. package/src/renderer/shared/theme/tokens.css +452 -53
  677. package/src/renderer/shared/types.ts +57 -2
  678. package/src/renderer/shared/utils/agentActivity.test.ts +633 -8
  679. package/src/renderer/shared/utils/agentActivity.ts +776 -59
  680. package/src/renderer/shared/utils/artifactBrowser.test.ts +37 -32
  681. package/src/renderer/shared/utils/artifactBrowser.ts +18 -20
  682. package/src/renderer/shared/utils/artifacts.ts +55 -0
  683. package/src/renderer/shared/utils/attachedDocument.test.ts +73 -0
  684. package/src/renderer/shared/utils/attachedDocument.ts +49 -0
  685. package/src/renderer/shared/utils/contextCompaction.test.tsx +1 -1
  686. package/src/renderer/shared/utils/externalLinks.ts +91 -0
  687. package/src/renderer/shared/utils/fileIcons.test.ts +59 -0
  688. package/src/renderer/shared/utils/fileIcons.ts +149 -16
  689. package/src/renderer/shared/utils/lazyWithRetry.ts +13 -0
  690. package/src/renderer/shared/utils/markdown.tsx +238 -51
  691. package/src/renderer/shared/utils/markdown.webImages.test.tsx +140 -2
  692. package/src/renderer/shared/utils/mcpResults.test.tsx +53 -1
  693. package/src/renderer/shared/utils/pdfRange.ts +16 -0
  694. package/src/renderer/shared/utils/previewObjectUrls.ts +20 -0
  695. package/src/renderer/shared/utils/sessionSources.test.ts +41 -1
  696. package/src/renderer/shared/utils/sessionSources.ts +2 -0
  697. package/src/renderer/shared/utils/slashCommandProcessor.ts +7 -1
  698. package/src/renderer/shared/utils/speech.ts +18 -4
  699. package/src/renderer/shared/utils/syntaxHighlight.test.tsx +11 -1
  700. package/src/renderer/shared/utils/syntaxHighlight.tsx +51 -3
  701. package/src/renderer/shared/utils/useGeminiLiveVoice.ts +324 -51
  702. package/src/renderer/shared/utils/useNativeVoiceInput.ts +19 -5
  703. package/src/renderer/shared/utils/useSessionSources.ts +4 -0
  704. package/src/renderer/shared/utils/viewedImages.test.ts +129 -0
  705. package/src/renderer/shared/utils/viewedImages.ts +81 -10
  706. package/src/renderer/shared/utils/workspaceDrag.test.ts +153 -0
  707. package/src/renderer/shared/utils/workspaceDrag.ts +172 -0
  708. package/src/renderer/shared/utils/workspaceImage.ts +17 -0
  709. package/src/renderer/shared/utils/workspaceListPreferences.test.ts +64 -0
  710. package/src/renderer/shared/utils/workspaceListPreferences.ts +54 -0
  711. package/src/renderer/shared/utils/workspaceMedia.ts +49 -0
  712. package/src/renderer/shared/utils/workspacePreview.test.ts +147 -2
  713. package/src/renderer/shared/utils/workspacePreview.ts +34 -3
  714. package/src/renderer/shared/utils/workspaces.ts +3 -2
  715. package/src/renderer/src/App.tsx +20 -16
  716. package/src/renderer/src/agentProgress.ts +1 -0
  717. package/src/renderer/src/components/ChatPanel.tsx +1 -1
  718. package/src/renderer/src/components/DashboardSidebar.tsx +2 -2
  719. package/src/renderer/src/components/ImageStudioPanel.tsx +1 -1
  720. package/src/renderer/src/components/LiveTranslateControls.tsx +1 -1
  721. package/src/renderer/src/components/MintDashboard.tsx +1 -1
  722. package/src/renderer/src/components/ProactiveGlow.tsx +1 -1
  723. package/src/renderer/src/components/ScreenPicker.css +1 -1
  724. package/src/renderer/src/components/ScreenPicker.tsx +1 -1
  725. package/src/renderer/src/components/SettingsWindow.tsx +6 -830
  726. package/src/renderer/src/components/SpotlightWindow.tsx +4 -32
  727. package/src/renderer/src/components/VeoStudioPanel.tsx +1 -1
  728. package/src/renderer/src/components/WorkspacePanel.tsx +49 -15
  729. package/src/renderer/src/components/browser-suggestions-popup.css +8 -8
  730. package/src/renderer/src/css/app-shell.css +26 -106
  731. package/src/renderer/src/css/chat.css +1499 -292
  732. package/src/renderer/src/css/desktop-tools.css +17 -348
  733. package/src/renderer/src/css/sidebar-workspace.css +22 -2
  734. package/src/renderer/src/css/spotlight.css +2 -2
  735. package/src/renderer/src/css/tool-surfaces.css +335 -65
  736. package/src/renderer/src/css/widget.css +6 -5
  737. package/src/renderer/src/env.d.ts +13 -0
  738. package/src/renderer/src/index.css +53 -83
  739. package/src/renderer/src/tauri.ts +99 -13
  740. package/src/renderer/src/voiceInput.ts +3 -1
  741. package/src/renderer/src-web/App.tsx +20 -8
  742. package/src/renderer/src-web/agentProgress.ts +1 -0
  743. package/src/renderer/src-web/components/ChatPanel.tsx +1 -1
  744. package/src/renderer/src-web/components/DashboardSidebar.tsx +2 -2
  745. package/src/renderer/src-web/components/ImageStudioPanel.tsx +1 -1
  746. package/src/renderer/src-web/components/MintDashboard.tsx +1 -1
  747. package/src/renderer/src-web/components/SettingsWindow.tsx +6 -851
  748. package/src/renderer/src-web/components/VeoStudioPanel.tsx +1 -1
  749. package/src/renderer/src-web/css/app-shell.css +20 -104
  750. package/src/renderer/src-web/css/chat.css +1536 -261
  751. package/src/renderer/src-web/css/mobile.css +29 -13
  752. package/src/renderer/src-web/css/settings/mobile.css +2 -2
  753. package/src/renderer/src-web/css/sidebar-workspace.css +21 -1
  754. package/src/renderer/src-web/env.d.ts +14 -0
  755. package/src/renderer/src-web/index.css +53 -83
  756. package/src/renderer/src-web/tauri.ts +93 -15
  757. package/src/renderer/tests/browserArtifacts.browser.html +1 -0
  758. package/src/renderer/tests/browserArtifacts.browser.tsx +68 -0
  759. package/src/renderer/tests/chatEscape.browser.html +1 -0
  760. package/src/renderer/tests/chatEscape.browser.tsx +25 -0
  761. package/src/renderer/tests/chatPerformance.browser.html +1 -1
  762. package/src/renderer/tests/collapsedPaste.browser.html +1 -1
  763. package/src/renderer/tests/composerMenus.browser.html +3 -3
  764. package/src/renderer/tests/contextCompaction.browser.html +1 -1
  765. package/src/renderer/tests/errorRecovery.browser.html +1 -1
  766. package/src/renderer/tests/fixtures/preview.webm +0 -0
  767. package/src/renderer/tests/glideSelect.browser.html +1 -2
  768. package/src/renderer/tests/glideSelect.preview.html +1 -1
  769. package/src/renderer/tests/library.browser.tsx +4 -1
  770. package/src/renderer/tests/liveOrb.browser.html +1 -1
  771. package/src/renderer/tests/liveVoice.browser.html +1 -0
  772. package/src/renderer/tests/mediaFixtures.ts +32 -0
  773. package/src/renderer/tests/modInput.browser.html +1 -1
  774. package/src/renderer/tests/sessionSources.browser.tsx +76 -15
  775. package/src/renderer/tests/toolsPanel.browser.tsx +5 -5
  776. package/src/renderer/tests/viewedImages.browser.tsx +3 -3
  777. package/src/renderer/tests/voiceDictation.browser.html +101 -0
  778. package/src/renderer/tests/voicePill.browser.html +3 -3
  779. package/src/renderer/tests/voicePill.preview.html +1 -1
  780. package/src/renderer/tests/webSources.browser.tsx +2 -98
  781. package/src/renderer/tests/workspaceDrop.browser.html +1 -0
  782. package/src/renderer/tests/workspaceDrop.browser.tsx +183 -0
  783. package/src/renderer/tests/workspaceExpansion.browser.html +1 -0
  784. package/src/renderer/tests/workspaceExpansion.browser.tsx +66 -0
  785. package/src/renderer/tests/workspaceRemoval.browser.html +66 -0
  786. package/src/renderer/tests/workspaceUndo.browser.html +10 -2
  787. package/src-tauri/src/app/lifecycle.rs +45 -15
  788. package/src-tauri/src/background/headless.rs +14 -8
  789. package/src-tauri/src/commands/conversation.rs +137 -73
  790. package/src-tauri/src/commands/integrations.rs +7 -1
  791. package/src-tauri/src/commands/media.rs +7 -0
  792. package/src-tauri/src/commands/workspace.rs +38 -0
  793. package/src-tauri/src/native/mod.rs +0 -1
  794. package/src-tauri/src/native/system.rs +4 -47
  795. package/tsconfig.json +15 -1
  796. package/vite.config.ts +2 -1
  797. package/vite.config.web.ts +2 -0
  798. package/crates/mint-cli/src/interactive/chat_tui.rs +0 -7853
  799. package/crates/mint-core/src/agent/chat.rs +0 -4155
  800. package/crates/mint-core/src/browser/lifecycle.rs +0 -191
  801. package/crates/mint-core/src/browser/logging.rs +0 -20
  802. package/crates/mint-core/src/orchestration/tools/browser.rs +0 -31
  803. package/out/web/assets/CliSessionsView-CtzUJpK_.css +0 -1
  804. package/out/web/assets/CliSessionsView-D7hw0Mgj.js +0 -1
  805. package/out/web/assets/CodeReviewPage-C7bEOJfd.js +0 -4
  806. package/out/web/assets/CodeReviewPage-Dte9uLiL.css +0 -1
  807. package/out/web/assets/CommandPalette-0RrF-AOT.js +0 -1
  808. package/out/web/assets/ImageStudioPanel-CdxkAf_r.js +0 -1
  809. package/out/web/assets/LibraryPage--Qfisp6D.js +0 -2
  810. package/out/web/assets/LibraryPage-DAxUTAg7.css +0 -1
  811. package/out/web/assets/LinkedFoldersView-2nfZbDgN.js +0 -1
  812. package/out/web/assets/McpRegistryPicker-h9uS8_wT.js +0 -1
  813. package/out/web/assets/McpServersView-slfQJzNB.js +0 -1
  814. package/out/web/assets/MintDashboard-BSR5XpXh.js +0 -25
  815. package/out/web/assets/MintDashboard-CWUcCGhd.css +0 -1
  816. package/out/web/assets/PluginsView-l7LSm503.js +0 -1
  817. package/out/web/assets/ScheduledTasksView-CttmLbq1.js +0 -1
  818. package/out/web/assets/SettingsWindow-BCMLYvEV.js +0 -4
  819. package/out/web/assets/SettingsWindow-DcMVmU9u.css +0 -1
  820. package/out/web/assets/SkillsView-rNs1qr_U.js +0 -2
  821. package/out/web/assets/ToolSurfacePage-B9DzEPWN.js +0 -37
  822. package/out/web/assets/ToolSurfacePage-CTfgggF2.css +0 -1
  823. package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +0 -4
  824. package/out/web/assets/WorkspacePanel-CbJ1PFoZ.js +0 -1
  825. package/out/web/assets/WorkspaceSelector-B2xIp04D.js +0 -1
  826. package/out/web/assets/WorkspaceSelector-Ca8uJOsS.css +0 -1
  827. package/out/web/assets/abnfDiagram-VCTEODGH-CD0CjoGl.js +0 -1
  828. package/out/web/assets/architecture-7GRP2DOG-RKV83OeZ.js +0 -1
  829. package/out/web/assets/architectureDiagram-5GKGNRK7-nN_HAFct.js +0 -36
  830. package/out/web/assets/c4Diagram-UCG6FXSJ-DTdV8_zE.js +0 -38
  831. package/out/web/assets/chunk-2Q5K7J3B-Dmqrq8Tp.js +0 -1
  832. package/out/web/assets/chunk-75Z2AOVW-_M0z5olV.js +0 -2
  833. package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +0 -2
  834. package/out/web/assets/chunk-CLGD4ZFX-D54yGvGS.js +0 -1
  835. package/out/web/assets/chunk-CacB07dV.js +0 -1
  836. package/out/web/assets/chunk-DSNCTWBM-C-gvT2ru.js +0 -2
  837. package/out/web/assets/chunk-DU6HZSFF-CnFngIhW.js +0 -128
  838. package/out/web/assets/chunk-F27PBJKO-BqtWrnEO.js +0 -1
  839. package/out/web/assets/chunk-FOHPRMQF-BaVC1uA7.js +0 -161
  840. package/out/web/assets/chunk-G27WJ6UU-Ckoq5mi2.js +0 -231
  841. package/out/web/assets/chunk-JQ64N6SF-CF8T7GiZ.js +0 -1
  842. package/out/web/assets/chunk-JWPE2WC7-BwtYOHqU.js +0 -1
  843. package/out/web/assets/chunk-LNGE3PJU-AdBoOWw2.js +0 -34
  844. package/out/web/assets/chunk-OBVCFTLP-CRIkunUB.js +0 -1
  845. package/out/web/assets/chunk-P2QGCYS3-UFEU6BxZ.js +0 -1
  846. package/out/web/assets/chunk-POPQ4Y6H-CQcrNbjr.js +0 -1
  847. package/out/web/assets/chunk-PWAF6VOD-Cc2uVDsG.js +0 -1
  848. package/out/web/assets/chunk-R7TYR2AO-DiCxzdAY.js +0 -10
  849. package/out/web/assets/chunk-RHFEMEQ7-b7hnPmrR.js +0 -168
  850. package/out/web/assets/chunk-XXDRQBXY-DnJkbUaw.js +0 -1
  851. package/out/web/assets/chunk-Y2CYZVJY-C9o-s6OY.js +0 -1
  852. package/out/web/assets/classDiagram-DTDB5LWJ-RnC2mYO4.js +0 -1
  853. package/out/web/assets/classDiagram-v2-JRS7N3AN-RnC2mYO4.js +0 -1
  854. package/out/web/assets/config-CnvCChUM.js +0 -2
  855. package/out/web/assets/config-DM6oIVO3.css +0 -1
  856. package/out/web/assets/core-DsKkQ7ig.js +0 -1
  857. package/out/web/assets/cose-bilkent-JH36ORCC--UN4aw5-.js +0 -1
  858. package/out/web/assets/cynefin-OW5HDTMX-CnzQfOGp.js +0 -1
  859. package/out/web/assets/cynefinDiagram-5FMLGOSQ-DVtQnfpm.js +0 -62
  860. package/out/web/assets/cytoscape.esm-Df1UN4Y1.js +0 -321
  861. package/out/web/assets/dagre-3AP2YEHR-DG76_k5_.js +0 -4
  862. package/out/web/assets/dagre-BWadQu2F.js +0 -1
  863. package/out/web/assets/diagram-S7CK7UJ4-CaouUoze.js +0 -30
  864. package/out/web/assets/diagram-UQ7AKVKN-B4bEc26B.js +0 -41
  865. package/out/web/assets/diagram-VX7I27RA-7hH5IPYf.js +0 -24
  866. package/out/web/assets/diagram-Z3DM3KII-CCM4clo8.js +0 -24
  867. package/out/web/assets/dist-BoTOASLF.js +0 -1
  868. package/out/web/assets/dist-js-BkYNznHX.js +0 -1
  869. package/out/web/assets/ebnfDiagram-PWID7BFC-Da7WAM3k.js +0 -1
  870. package/out/web/assets/event-Cdt7Byyj.js +0 -1
  871. package/out/web/assets/eventmodeling-NTZA5JFV-xcfsA0XD.js +0 -1
  872. package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +0 -1
  873. package/out/web/assets/ganttDiagram-EL5Y4UJY-B3ClFGmL.js +0 -292
  874. package/out/web/assets/gitGraph-4MIJSDKK-BZ_y_cDU.js +0 -1
  875. package/out/web/assets/gitGraphDiagram-WWUBYQGX-drhRSYm3.js +0 -106
  876. package/out/web/assets/graphlib-CTR5ZhLf.js +0 -1
  877. package/out/web/assets/index-BZ9xgmMP.css +0 -1
  878. package/out/web/assets/index-Ca8cCS4h.js +0 -168
  879. package/out/web/assets/info-A6RAGUB7-B7I3K0F1.js +0 -1
  880. package/out/web/assets/infoDiagram-RXCK75RN-deX_1MPh.js +0 -2
  881. package/out/web/assets/journeyDiagram-EYS64GPL-CZn2kB8b.js +0 -139
  882. package/out/web/assets/jsx-runtime-DN4NhQUK.js +0 -1
  883. package/out/web/assets/katex-O3jvqgnU.js +0 -257
  884. package/out/web/assets/markdown-CMhYIcWB.js +0 -39
  885. package/out/web/assets/mermaid-parser.core-Whu2rlJC.js +0 -7
  886. package/out/web/assets/mermaid.core-CKyPo8VH.js +0 -11
  887. package/out/web/assets/modelManager-CUaGWMWu.js +0 -2
  888. package/out/web/assets/oauthManager-DlNhXJr6.js +0 -1
  889. package/out/web/assets/packet-AYTQ26CC-CEeIRKRG.js +0 -1
  890. package/out/web/assets/pegDiagram-XKGWAZYB-BYadI-KO.js +0 -1
  891. package/out/web/assets/pie-WAS4IAKB-D8uf4dh5.js +0 -1
  892. package/out/web/assets/pieDiagram-E7YTZNPT-CjSDy4hO.js +0 -39
  893. package/out/web/assets/radar-RG4KPBEZ-DZJxnokY.js +0 -1
  894. package/out/web/assets/railroad-74A4TZTK-DBysUiUi.js +0 -1
  895. package/out/web/assets/railroad-abnf-HS5TGJTU-CHWxoJYg.js +0 -1
  896. package/out/web/assets/railroad-ebnf-LZEXJU2U-DDv7X6bY.js +0 -1
  897. package/out/web/assets/railroad-peg-WCYAUIDC-DpfcYYNJ.js +0 -1
  898. package/out/web/assets/railroadDiagram-O6MQD6OU-CYtyv0t3.js +0 -1
  899. package/out/web/assets/rough.esm-DFbTUy8a.js +0 -1
  900. package/out/web/assets/sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js +0 -40
  901. package/out/web/assets/sequenceDiagram-WJ2MYXX4-BvFLKtPd.js +0 -162
  902. package/out/web/assets/sizeCapture-X5ZJPWSS-DKeOCaN2.js +0 -1
  903. package/out/web/assets/src-DnfeXQPr.js +0 -1
  904. package/out/web/assets/stateDiagram-HBIQ2CUA-Bx0GWeaY.js +0 -1
  905. package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +0 -1
  906. package/out/web/assets/studio-B1mk40wD.js +0 -1
  907. package/out/web/assets/swimlanes-XN3QIQJK-CCma0T7L.js +0 -1
  908. package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +0 -8
  909. package/out/web/assets/timeline-definition-24CTP7MA-iCRhhJ7C.js +0 -120
  910. package/out/web/assets/treeView-Q6P3EWNA-DZ-y08qp.js +0 -1
  911. package/out/web/assets/treemap-WGGIJYW6-De0CxzMx.js +0 -1
  912. package/out/web/assets/vennDiagram-4TSXK5OY-w_7aZ6xe.js +0 -34
  913. package/out/web/assets/wardley-WFR3VGLG-DT0y0xJ4.js +0 -1
  914. package/out/web/assets/window-BJCVtyET.js +0 -1
  915. package/shared-modules/libsecret/libsecret.json +0 -23
  916. package/shared-modules/libusb/libusb.json +0 -27
  917. package/shared-modules/lzo/lzo.json +0 -27
  918. package/src/renderer/shared/components/AgentActivityDrawer.tsx +0 -204
  919. package/src/renderer/shared/components/AgentActivityTable.tsx +0 -301
  920. package/src/renderer/shared/components/ChatMessageItem.test.tsx +0 -68
  921. package/src/renderer/shared/components/ChatMessageItem.tsx +0 -326
  922. package/src/renderer/shared/components/ChatPanel.test.tsx +0 -21
  923. package/src/renderer/shared/components/FormattedMessage.tsx +0 -11
  924. package/src/renderer/shared/components/GeminiLiveOverlay.test.tsx +0 -24
  925. package/src/renderer/shared/components/GlideSelect.d.ts +0 -31
  926. package/src/renderer/shared/components/GlideSelect.jsx +0 -266
  927. package/src/renderer/shared/components/InlineThoughtNote.tsx +0 -27
  928. package/src/renderer/shared/components/ModSessionControls.tsx +0 -8
  929. package/src/renderer/shared/components/ModUi.tsx +0 -26
  930. package/src/renderer/shared/components/ProgressActivity.tsx +0 -17
  931. package/src/renderer/shared/components/ReviewHistory.tsx +0 -42
  932. package/src/renderer/shared/components/RunSummaryDashboard.tsx +0 -143
  933. package/src/renderer/shared/components/SelectField.tsx +0 -38
  934. package/src/renderer/shared/components/SessionSources.tsx +0 -48
  935. package/src/renderer/shared/components/SessionSourcesPopover.tsx +0 -61
  936. package/src/renderer/shared/components/ToolSurfacePage.test.tsx +0 -32
  937. package/src/renderer/shared/components/ViewedImages.tsx +0 -36
  938. package/src/renderer/shared/components/WorkspaceContextPopover.tsx +0 -138
  939. package/src/renderer/shared/components/WorkspacePreviewActions.test.tsx +0 -44
  940. package/src/renderer/shared/components/ui/demo.tsx +0 -26
  941. package/src/renderer/shared/css/session-sources-popover.css +0 -9
  942. package/src/renderer/src/components/BrowserShell.tsx +0 -108
  943. package/src/renderer/src/components/BrowserSuggestionsPopup.tsx +0 -91
  944. package/src/renderer/src/components/CalculationCard.tsx +0 -3
  945. package/src/renderer/src/components/ImageGenCard.tsx +0 -2
  946. package/src/renderer/src/components/ImageSearchCard.tsx +0 -2
  947. package/src/renderer/src/components/MermaidCard.tsx +0 -1
  948. package/src/renderer/src/components/PicturesLibrary.tsx +0 -2
  949. package/src/renderer/src/components/Settings/AgentsTab.tsx +0 -4
  950. package/src/renderer/src/components/Settings/AudioTab.tsx +0 -3
  951. package/src/renderer/src/components/Settings/AutomationTab.tsx +0 -3
  952. package/src/renderer/src/components/Settings/GeneralTab.tsx +0 -3
  953. package/src/renderer/src/components/Settings/MemoryTab.tsx +0 -3
  954. package/src/renderer/src/components/Settings/PluginsTab.tsx +0 -3
  955. package/src/renderer/src/components/Settings/ProfileTab.tsx +0 -3
  956. package/src/renderer/src/components/Settings/ShortcutsTab.tsx +0 -3
  957. package/src/renderer/src/components/Settings/ThemeTab.tsx +0 -3
  958. package/src/renderer/src/components/StockCard.tsx +0 -3
  959. package/src/renderer/src/components/WeatherCard.tsx +0 -3
  960. package/src/renderer/src/components/browser-shell.css +0 -185
  961. package/src/renderer/src/css/pictures.css +0 -2
  962. package/src/renderer/src-web/components/PicturesLibrary.tsx +0 -2
  963. package/src/renderer/src-web/components/Settings/AgentsTab.tsx +0 -4
  964. package/src/renderer/src-web/components/Settings/AudioTab.tsx +0 -3
  965. package/src/renderer/src-web/components/Settings/AutomationTab.tsx +0 -3
  966. package/src/renderer/src-web/components/Settings/GeneralTab.tsx +0 -3
  967. package/src/renderer/src-web/components/Settings/MemoryTab.tsx +0 -3
  968. package/src/renderer/src-web/components/Settings/PluginsTab.tsx +0 -3
  969. package/src/renderer/src-web/components/Settings/ProfileTab.tsx +0 -3
  970. package/src/renderer/src-web/components/Settings/ShortcutsTab.tsx +0 -3
  971. package/src/renderer/src-web/components/Settings/ThemeTab.tsx +0 -3
  972. package/src/renderer/src-web/css/pictures.css +0 -2
  973. package/src/renderer/src-web/css/settings/base.css +0 -1266
  974. package/src/renderer/src-web/css/spotlight.css +0 -102
  975. package/src/renderer/src-web/css/widget.css +0 -213
  976. package/src-tauri/src/native/browser.rs +0 -252
  977. /package/src/renderer/shared/components/{ContextCompactionStatus.tsx → chat/ContextCompactionStatus.tsx} +0 -0
  978. /package/src/renderer/shared/components/{GeminiLiveOverlay.css → chat/GeminiLiveOverlay.css} +0 -0
  979. /package/src/renderer/shared/components/{VirtualChatHistory.tsx → chat/VirtualChatHistory.tsx} +0 -0
  980. /package/src/renderer/shared/components/{VoicePill.d.ts → chat/VoicePill.d.ts} +0 -0
  981. /package/src/renderer/shared/components/{VoicePill.test.tsx → chat/VoicePill.test.tsx} +0 -0
  982. /package/src/renderer/shared/components/{ScreenCaptureDialog.css → studio/ScreenCaptureDialog.css} +0 -0
  983. /package/src/renderer/shared/components/{ScreenCaptureDialog.tsx → studio/ScreenCaptureDialog.tsx} +0 -0
  984. /package/src/renderer/shared/components/{SelectField.test.tsx → ui/SelectField.test.tsx} +0 -0
@@ -20,7 +20,13 @@ pub(super) fn render_messages_as_text(messages: &[ChatMessage]) -> String {
20
20
  ContentBlock::ToolUse { name, input, .. } => {
21
21
  format!("Called {name} with {input}")
22
22
  }
23
- ContentBlock::ToolResult { content, .. } => format!("Result: {content}"),
23
+ ContentBlock::ToolResult { content, .. } => {
24
+ let truncated = super::truncation::head_tail_truncate(
25
+ content,
26
+ super::truncation::TruncationConfig::COMPACT,
27
+ );
28
+ format!("Result: {truncated}")
29
+ }
24
30
  ContentBlock::Image { .. } => "[image]".to_string(),
25
31
  ContentBlock::Audio { .. } => "[audio]".to_string(),
26
32
  ContentBlock::Video { .. } => "[video]".to_string(),
@@ -45,44 +51,46 @@ pub(super) fn render_messages_as_text(messages: &[ChatMessage]) -> String {
45
51
  /// special-casing needed elsewhere.
46
52
  ///
47
53
  /// `Ok(None)` means there was nothing worth compacting yet (too little history)
48
- /// — not a failure, just a no-op. `Err` means compaction was attempted but the
49
- /// summarization call itself failed; compaction is a best-effort optimization,
50
- /// so callers should fall back to the uncompacted messages rather than failing
51
- /// the agent run, but may want to surface the failure differently than a
52
- /// routine no-op.
54
+ /// — not a failure, just a no-op.
53
55
  ///
54
- /// `Ok(Some((_, fallback_provider)))`'s second element names the provider
55
- /// actually used to generate the summary when it differs from the caller's
56
- /// primary (`send_chat_with_fallback` silently retries on another configured
57
- /// provider if the primary fails) — surfaced rather than discarded so a
58
- /// summary quietly written by a different model isn't invisible to the user.
56
+ /// If LLM-based summarization fails (e.g. timeout, rate limit, provider error),
57
+ /// this function falls back to deterministic structural truncation via
58
+ /// [`hard_truncate_native_messages`] to guarantee that context is reduced and
59
+ /// the agent loop does not crash from context overflow.
59
60
  pub(super) async fn compact_native_messages(
60
61
  config: &MintConfig,
61
62
  messages: &[ChatMessage],
63
+ history_prefix_len: usize,
62
64
  ) -> Result<Option<(Vec<ChatMessage>, Option<String>)>, ChatError> {
63
- let step_pairs = messages.len().saturating_sub(1) / 2;
64
- if step_pairs <= COMPACTION_KEEP_RECENT_STEPS || messages.is_empty() {
65
+ let step_start = history_prefix_len + 1;
66
+ if messages.len() <= step_start {
67
+ return Ok(None);
68
+ }
69
+ let step_pairs = (messages.len() - step_start) / 2;
70
+ if step_pairs <= COMPACTION_KEEP_RECENT_STEPS {
65
71
  return Ok(None);
66
72
  }
67
73
  let compact_pairs = step_pairs - COMPACTION_KEEP_RECENT_STEPS;
68
74
  let compact_message_count = compact_pairs * 2;
69
- let compacted_range = &messages[1..1 + compact_message_count];
75
+ let compacted_range = &messages[step_start..step_start + compact_message_count];
70
76
 
71
77
  let transcript = render_messages_as_text(compacted_range);
72
78
  let summary_prompt = format!(
73
- "Summarize the following part of an autonomous coding agent's work log concisely but \
74
- completely. Preserve: exact file paths touched and their resulting state, exact \
75
- commands run and whether they succeeded, key findings from searches/reads, and any \
76
- decisions or open threads still relevant to finishing the task. Omit verbose \
77
- stdout/stderr detail that isn't load-bearing. Write it as dense prose, not a copy of \
78
- the log.\n\n{transcript}"
79
+ "Compress the following execution log of an autonomous coding agent into a high-density, \
80
+ structured milestone summary. Format your summary strictly under these markdown headings:\n\
81
+ ### Milestone Summary (Steps 1-{compact_pairs})\n\
82
+ - **Core Intent & Scope**: The user's original objective and requirements.\n\
83
+ - **Files Modified & Validated**: Exact file paths modified, created, or tested with outcomes.\n\
84
+ - **Key Discoveries & Decisions**: Architectural decisions made, bugs identified, approaches tried and dismissed.\n\
85
+ - **Pending / Next Steps**: Tasks remaining to be completed.\n\n\
86
+ Omit raw stdout/stderr logs and redundant command boilerplate. Focus strictly on facts and state.\n\n{transcript}"
79
87
  );
80
88
 
81
- let (summary_response, fallback_provider) = send_chat_with_fallback(
89
+ let summary_result = send_chat_with_fallback(
82
90
  config,
83
91
  &ChatRequest {
84
92
  message: summary_prompt,
85
- system_instruction: "You compress agent work logs into dense, factual summaries."
93
+ system_instruction: "You compress agent work logs into dense, structured milestone summaries retaining all critical paths, decisions, and pending tasks."
86
94
  .into(),
87
95
  chat_id: None,
88
96
  image_data_uri: None,
@@ -99,34 +107,132 @@ pub(super) async fn compact_native_messages(
99
107
  ..Default::default()
100
108
  },
101
109
  )
102
- .await?;
110
+ .await;
111
+
112
+ match summary_result {
113
+ Ok((summary_response, fallback_provider)) => {
114
+ let mut compacted = Vec::with_capacity(messages.len() - compact_message_count + 3);
115
+ if messages.len() > history_prefix_len {
116
+ compacted.extend_from_slice(&messages[..history_prefix_len]);
117
+ compacted.push(messages[history_prefix_len].clone());
118
+ } else {
119
+ compacted.extend_from_slice(messages);
120
+ }
121
+ compacted.push(ChatMessage {
122
+ role: ChatRole::Assistant,
123
+ content: vec![ContentBlock::Text {
124
+ text: format!(
125
+ "[Summary of earlier steps 1-{compact_pairs}, compacted to save context]\n{}",
126
+ summary_response.text.trim()
127
+ ),
128
+ }],
129
+ });
130
+ compacted.push(ChatMessage {
131
+ role: ChatRole::User,
132
+ content: vec![ContentBlock::Text {
133
+ text: "Continue the task using the summary above and the recent steps below."
134
+ .into(),
135
+ }],
136
+ });
137
+ compacted.extend_from_slice(&messages[step_start + compact_message_count..]);
138
+ Ok(Some((compacted, fallback_provider)))
139
+ }
140
+ Err(err) => {
141
+ // LLM summarization failed (timeout, rate limit 429, provider offline, or context limit).
142
+ // Rather than returning Err and leaving native_messages uncompacted (which causes the next
143
+ // agent turn to crash with context window exceeded), fall back to deterministic hard-truncation.
144
+ let truncated = hard_truncate_native_messages(
145
+ messages,
146
+ history_prefix_len,
147
+ compact_pairs,
148
+ &err.to_string(),
149
+ );
150
+ Ok(Some((
151
+ truncated,
152
+ Some(format!("hard-truncate fallback ({err})")),
153
+ )))
154
+ }
155
+ }
156
+ }
157
+
158
+ pub(super) fn hard_truncate_native_messages(
159
+ messages: &[ChatMessage],
160
+ history_prefix_len: usize,
161
+ compact_pairs: usize,
162
+ error_reason: &str,
163
+ ) -> Vec<ChatMessage> {
164
+ let step_start = history_prefix_len + 1;
165
+ let compact_message_count = compact_pairs * 2;
166
+ let compacted_range = if messages.len() > step_start {
167
+ let end = (step_start + compact_message_count).min(messages.len());
168
+ &messages[step_start..end]
169
+ } else {
170
+ &[]
171
+ };
172
+
173
+ let mut actions = Vec::new();
174
+ for chunk in compacted_range.chunks(2) {
175
+ if let Some(assistant_msg) = chunk.get(0) {
176
+ for block in &assistant_msg.content {
177
+ if let ContentBlock::ToolUse { name, input, .. } = block {
178
+ let input_summary = match input {
179
+ serde_json::Value::Object(map) => {
180
+ if let Some(path) = map.get("path").and_then(|v| v.as_str()) {
181
+ format!("path: {path}")
182
+ } else if let Some(cmd) = map.get("command").and_then(|v| v.as_str()) {
183
+ format!("command: {cmd}")
184
+ } else if let Some(query) = map.get("query").and_then(|v| v.as_str()) {
185
+ format!("query: {query}")
186
+ } else {
187
+ let s = input.to_string();
188
+ truncate_for_context(&s, 60)
189
+ }
190
+ }
191
+ _ => {
192
+ let s = input.to_string();
193
+ truncate_for_context(&s, 60)
194
+ }
195
+ };
196
+ actions.push(format!("- {name} ({input_summary})"));
197
+ }
198
+ }
199
+ }
200
+ }
201
+
202
+ let actions_text = if actions.is_empty() {
203
+ "(no explicit tool calls recorded)".to_string()
204
+ } else {
205
+ actions.join("\n")
206
+ };
103
207
 
104
- let mut compacted = Vec::with_capacity(messages.len() - compact_message_count + 3);
105
- compacted.push(messages[0].clone());
208
+ let summary_content = format!(
209
+ "[Summary of steps 1-{compact_pairs} — compacted via deterministic hard-truncation fallback due to summarization failure: {error_reason}]\nActions performed in earlier steps:\n{actions_text}\n[Detailed tool outputs omitted to preserve context window. Recent steps continue below.]"
210
+ );
211
+
212
+ let mut compacted =
213
+ Vec::with_capacity(messages.len().saturating_sub(compact_message_count) + 3);
214
+ if messages.len() > history_prefix_len {
215
+ compacted.extend_from_slice(&messages[..history_prefix_len]);
216
+ compacted.push(messages[history_prefix_len].clone());
217
+ } else {
218
+ compacted.extend_from_slice(messages);
219
+ }
106
220
  compacted.push(ChatMessage {
107
221
  role: ChatRole::Assistant,
108
- content: vec![ContentBlock::ToolUse {
109
- id: "call_compacted_summary".into(),
110
- name: "conversation_summary".into(),
111
- input: serde_json::json!({
112
- "summary": format!("Summary of steps 1-{compact_pairs}")
113
- }),
114
- thought_signature: None,
222
+ content: vec![ContentBlock::Text {
223
+ text: summary_content,
115
224
  }],
116
225
  });
117
226
  compacted.push(ChatMessage {
118
- role: ChatRole::Tool,
119
- content: vec![ContentBlock::ToolResult {
120
- tool_use_id: "call_compacted_summary".into(),
121
- content: format!(
122
- "[Summary of steps 1-{compact_pairs}, compacted to save context]\n{}",
123
- summary_response.text.trim()
124
- ),
125
- is_error: false,
227
+ role: ChatRole::User,
228
+ content: vec![ContentBlock::Text {
229
+ text: "Continue the task using the summary above and the recent steps below.".into(),
126
230
  }],
127
231
  });
128
- compacted.extend_from_slice(&messages[1 + compact_message_count..]);
129
- Ok(Some((compacted, fallback_provider)))
232
+ if messages.len() > step_start + compact_message_count {
233
+ compacted.extend_from_slice(&messages[step_start + compact_message_count..]);
234
+ }
235
+ compacted
130
236
  }
131
237
 
132
238
  pub(super) fn initial_observation(task: &str, root: &Path, skills: &str) -> String {
@@ -164,9 +270,32 @@ pub(super) fn initial_observation(task: &str, root: &Path, skills: &str) -> Stri
164
270
  observation
165
271
  }
166
272
 
273
+ /// Compacts an older trajectory step's verbose observation into a single line preview
274
+ /// to prevent `observation` buffer bloat across long-running tasks.
275
+ fn compact_trajectory_step_preview(step_str: &str) -> String {
276
+ if let Some(obs_idx) = step_str.find("\n- Observation:") {
277
+ let prefix = &step_str[..obs_idx + "\n- Observation:".len()];
278
+ let obs_text = step_str[obs_idx + "\n- Observation:".len()..].trim();
279
+ if obs_text.chars().count() > 120 {
280
+ let first_line = obs_text
281
+ .lines()
282
+ .find(|l| !l.trim().is_empty())
283
+ .unwrap_or("");
284
+ let truncated = if first_line.chars().count() > 80 {
285
+ format!("{}...", &first_line[..77])
286
+ } else {
287
+ first_line.to_string()
288
+ };
289
+ return format!("{prefix} {truncated} (details collapsed for earlier step)");
290
+ }
291
+ }
292
+ step_str.to_string()
293
+ }
294
+
167
295
  /// Rebuilds the `observation` string buffer from the current trajectory in-place,
168
296
  /// reusing the underlying allocation across agent-loop steps to avoid repeated
169
297
  /// heap re-allocations and redundant copies.
298
+ /// Preserves full detail for the most recent 5 steps while compacting older observations.
170
299
  pub(super) fn rebuild_observation(
171
300
  task: &str,
172
301
  root: &Path,
@@ -185,11 +314,17 @@ pub(super) fn rebuild_observation(
185
314
  "Task: {task}\nWorkspace: {}\n\nHere is the history of what you have done so far in this agent loop:\n\n",
186
315
  root_display
187
316
  );
317
+ let recent_cutoff = trajectory.len().saturating_sub(5);
188
318
  for (i, step) in trajectory.iter().enumerate() {
189
319
  if i > 0 {
190
320
  target.push_str("\n\n");
191
321
  }
192
- target.push_str(step);
322
+ if i < recent_cutoff {
323
+ let compacted = compact_trajectory_step_preview(step);
324
+ target.push_str(&compacted);
325
+ } else {
326
+ target.push_str(step);
327
+ }
193
328
  }
194
329
  target.push_str(
195
330
  "\n\nProceed to the next step. If you have completed the task, use the 'finish' action.",
@@ -215,6 +350,215 @@ pub(super) fn format_trajectory_step(
215
350
  s
216
351
  }
217
352
 
353
+ /// Keeps full `ContentBlock::Image` payloads only for the most recent
354
+ /// `max_retained_steps` tool turns. Older tool turns have their `ContentBlock::Image`
355
+ /// removed and their tool result text updated to indicate historical pixels
356
+ /// were pruned to reduce prompt cache and token bloat.
357
+ ///
358
+ /// Returns the number of `ContentBlock::Image` entries pruned.
359
+ pub(super) fn prune_historic_images_from_native_messages(
360
+ messages: &mut [ChatMessage],
361
+ max_retained_steps: usize,
362
+ ) -> usize {
363
+ if messages.is_empty() {
364
+ return 0;
365
+ }
366
+ let mut tool_count = 0;
367
+ let mut pruned_count = 0;
368
+
369
+ for message in messages.iter_mut().rev() {
370
+ if message.role == ChatRole::Tool {
371
+ tool_count += 1;
372
+ if tool_count > max_retained_steps {
373
+ let had_image = message
374
+ .content
375
+ .iter()
376
+ .any(|block| matches!(block, ContentBlock::Image { .. }));
377
+ if had_image {
378
+ message.content.retain(|block| {
379
+ if matches!(block, ContentBlock::Image { .. }) {
380
+ pruned_count += 1;
381
+ false
382
+ } else {
383
+ true
384
+ }
385
+ });
386
+ for block in &mut message.content {
387
+ if let ContentBlock::ToolResult { content, .. } = block {
388
+ if content.contains("— see attached image") {
389
+ *content = content.replace(
390
+ "— see attached image",
391
+ "— historical image pixels pruned from context",
392
+ );
393
+ } else if !content.contains("pruned from context") {
394
+ content.push_str(" [historical image pixels pruned from context]");
395
+ }
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+ pruned_count
403
+ }
404
+
405
+ /// Progressively ages older `ContentBlock::ToolResult` entries out of prompt memory
406
+ /// using a Three-Tier Retention Policy (Cursor / Claude Code pattern):
407
+ /// - Hot Zone (most recent `hot_steps` tool turns): Preserves full output verbatim.
408
+ /// - Warm Zone (turns between `hot_steps + 1` and `hot_steps + warm_steps`):
409
+ /// Truncates verbose outputs (> 500 chars) to initial lines + omission note.
410
+ /// - Cold Zone (older than `hot_steps + warm_steps`):
411
+ /// Collapses output into a 1-line tombstone summary.
412
+ ///
413
+ /// Returns the number of tool results compacted.
414
+ pub(super) fn prune_historic_tool_results_from_native_messages(
415
+ messages: &mut [ChatMessage],
416
+ hot_steps: usize,
417
+ warm_steps: usize,
418
+ ) -> usize {
419
+ if messages.is_empty() {
420
+ return 0;
421
+ }
422
+ let mut tool_count = 0;
423
+ let mut compacted_count = 0;
424
+
425
+ for message in messages.iter_mut().rev() {
426
+ if message.role == ChatRole::Tool {
427
+ tool_count += 1;
428
+ if tool_count <= hot_steps {
429
+ // Hot zone: keep full detail
430
+ continue;
431
+ } else if tool_count <= hot_steps + warm_steps {
432
+ // Warm zone: compress if long
433
+ for block in &mut message.content {
434
+ if let ContentBlock::ToolResult { content, .. } = block {
435
+ if content.chars().count() > 500
436
+ && !content.starts_with("[Tool Result:")
437
+ && !content.starts_with("[read_file")
438
+ {
439
+ let lines: Vec<&str> = content.lines().collect();
440
+ if lines.len() > 12 {
441
+ let head = lines[..8].join("\n");
442
+ let omitted = lines.len() - 10;
443
+ let tail = lines[lines.len() - 2..].join("\n");
444
+ *content = format!(
445
+ "{head}\n\n[... {omitted} lines collapsed for earlier turn ...]\n{tail}"
446
+ );
447
+ compacted_count += 1;
448
+ }
449
+ }
450
+ }
451
+ }
452
+ } else {
453
+ // Cold zone: collapse to 1-line tombstone
454
+ for block in &mut message.content {
455
+ if let ContentBlock::ToolResult {
456
+ content, is_error, ..
457
+ } = block
458
+ {
459
+ if !content.starts_with("[Tool Result:")
460
+ && !content.starts_with("[read_file")
461
+ {
462
+ if *is_error {
463
+ let err_line = content
464
+ .lines()
465
+ .find(|l| !l.trim().is_empty())
466
+ .unwrap_or("Failed");
467
+ let trimmed_err = if err_line.len() > 70 {
468
+ format!("{}...", &err_line[..67])
469
+ } else {
470
+ err_line.to_string()
471
+ };
472
+ *content = format!(
473
+ "[Tool Result: Failed ({trimmed_err}) — log collapsed for past step]"
474
+ );
475
+ } else {
476
+ *content =
477
+ "[Tool Result: Succeeded — output collapsed for past step]"
478
+ .to_string();
479
+ }
480
+ compacted_count += 1;
481
+ }
482
+ }
483
+ }
484
+ }
485
+ }
486
+ }
487
+ compacted_count
488
+ }
489
+
490
+ /// When a file edit succeeds in the agent loop, scans earlier `ChatMessage` history
491
+ /// for prior `read_file` tool results targeting any of `modified_paths`.
492
+ /// Collapses their bodies into a concise note indicating their content is superseded.
493
+ /// Prevents the model from reading obsolete code states and saves tokens.
494
+ ///
495
+ /// Returns the number of read_file results superseded.
496
+ pub(super) fn supersede_stale_file_reads(
497
+ messages: &mut [ChatMessage],
498
+ modified_paths: &[String],
499
+ current_step: usize,
500
+ ) -> usize {
501
+ if messages.is_empty() || modified_paths.is_empty() {
502
+ return 0;
503
+ }
504
+
505
+ // Map tool_use_id -> file path for any read_file ToolUse targeting modified_paths
506
+ let mut superseded_call_ids: std::collections::HashMap<String, String> =
507
+ std::collections::HashMap::new();
508
+
509
+ for message in messages.iter() {
510
+ if message.role == ChatRole::Assistant {
511
+ for block in &message.content {
512
+ if let ContentBlock::ToolUse {
513
+ id, name, input, ..
514
+ } = block
515
+ {
516
+ if name == "read_file" {
517
+ if let Some(target_path) = input.get("path").and_then(|p| p.as_str()) {
518
+ if modified_paths.iter().any(|m| {
519
+ m == target_path
520
+ || target_path.ends_with(m.as_str())
521
+ || m.ends_with(target_path)
522
+ }) {
523
+ superseded_call_ids.insert(id.clone(), target_path.to_string());
524
+ }
525
+ }
526
+ }
527
+ }
528
+ }
529
+ }
530
+ }
531
+
532
+ if superseded_call_ids.is_empty() {
533
+ return 0;
534
+ }
535
+
536
+ let mut superseded_count = 0;
537
+ for message in messages.iter_mut() {
538
+ if message.role == ChatRole::Tool {
539
+ for block in &mut message.content {
540
+ if let ContentBlock::ToolResult {
541
+ tool_use_id,
542
+ content,
543
+ ..
544
+ } = block
545
+ {
546
+ if let Some(path) = superseded_call_ids.get(tool_use_id) {
547
+ if !content.starts_with("[read_file") {
548
+ *content = format!(
549
+ "[read_file \"{path}\": Content superseded by file modifications at Step {current_step}]"
550
+ );
551
+ superseded_count += 1;
552
+ }
553
+ }
554
+ }
555
+ }
556
+ }
557
+ }
558
+
559
+ superseded_count
560
+ }
561
+
218
562
  /// Sends a lifecycle around the actual summarizer await; callers retain the
219
563
  /// original messages on failure. Short histories do not enter this UI state.
220
564
  pub(super) async fn report_context_compaction<F>(
@@ -240,7 +584,13 @@ where
240
584
  Ok(Some((_, fallback))) => {
241
585
  let fallback_note = fallback
242
586
  .as_ref()
243
- .map(|p| format!("; summary generated via fallback provider {p}"))
587
+ .map(|p| {
588
+ if p.starts_with("hard-truncate") {
589
+ format!("; {p}")
590
+ } else {
591
+ format!("; summary generated via fallback provider {p}")
592
+ }
593
+ })
244
594
  .unwrap_or_default();
245
595
  (
246
596
  "completed",
@@ -317,4 +667,488 @@ mod compaction_progress_tests {
317
667
  matches!(&events.borrow()[1], AgentProgress::ContextCompaction { status, message, .. } if status == "failed" && message.contains("offline") && message.contains("original context"))
318
668
  );
319
669
  }
670
+
671
+ #[test]
672
+ fn test_prune_historic_images_empty_messages() {
673
+ let mut messages = Vec::new();
674
+ assert_eq!(
675
+ prune_historic_images_from_native_messages(&mut messages, 2),
676
+ 0
677
+ );
678
+ }
679
+
680
+ #[test]
681
+ fn test_prune_historic_images_keeps_within_retention_window() {
682
+ let mut messages = vec![
683
+ ChatMessage {
684
+ role: ChatRole::User,
685
+ content: vec![ContentBlock::Text {
686
+ text: "task".into(),
687
+ }],
688
+ },
689
+ ChatMessage {
690
+ role: ChatRole::Assistant,
691
+ content: vec![ContentBlock::Text {
692
+ text: "call 1".into(),
693
+ }],
694
+ },
695
+ ChatMessage {
696
+ role: ChatRole::Tool,
697
+ content: vec![
698
+ ContentBlock::ToolResult {
699
+ tool_use_id: "c1".into(),
700
+ content: "[Image loaded — see attached image]".into(),
701
+ is_error: false,
702
+ },
703
+ ContentBlock::Image {
704
+ data_uri: "data:image/png;base64,img1".into(),
705
+ },
706
+ ],
707
+ },
708
+ ChatMessage {
709
+ role: ChatRole::Assistant,
710
+ content: vec![ContentBlock::Text {
711
+ text: "call 2".into(),
712
+ }],
713
+ },
714
+ ChatMessage {
715
+ role: ChatRole::Tool,
716
+ content: vec![
717
+ ContentBlock::ToolResult {
718
+ tool_use_id: "c2".into(),
719
+ content: "[Image loaded — see attached image]".into(),
720
+ is_error: false,
721
+ },
722
+ ContentBlock::Image {
723
+ data_uri: "data:image/png;base64,img2".into(),
724
+ },
725
+ ],
726
+ },
727
+ ];
728
+
729
+ // Retention is 2, and there are 2 tool messages, so none should be pruned.
730
+ let pruned = prune_historic_images_from_native_messages(&mut messages, 2);
731
+ assert_eq!(pruned, 0);
732
+ assert_eq!(messages[2].content.len(), 2);
733
+ assert_eq!(messages[4].content.len(), 2);
734
+ }
735
+
736
+ #[test]
737
+ fn test_prune_historic_images_prunes_older_than_retention_window() {
738
+ let mut messages = vec![
739
+ ChatMessage {
740
+ role: ChatRole::User,
741
+ content: vec![ContentBlock::Text {
742
+ text: "task".into(),
743
+ }],
744
+ },
745
+ // Step 1
746
+ ChatMessage {
747
+ role: ChatRole::Assistant,
748
+ content: vec![ContentBlock::Text {
749
+ text: "step 1".into(),
750
+ }],
751
+ },
752
+ ChatMessage {
753
+ role: ChatRole::Tool,
754
+ content: vec![
755
+ ContentBlock::ToolResult {
756
+ tool_use_id: "c1".into(),
757
+ content: "[Image loaded — see attached image]".into(),
758
+ is_error: false,
759
+ },
760
+ ContentBlock::Image {
761
+ data_uri: "data:image/png;base64,img1".into(),
762
+ },
763
+ ],
764
+ },
765
+ // Step 2
766
+ ChatMessage {
767
+ role: ChatRole::Assistant,
768
+ content: vec![ContentBlock::Text {
769
+ text: "step 2".into(),
770
+ }],
771
+ },
772
+ ChatMessage {
773
+ role: ChatRole::Tool,
774
+ content: vec![
775
+ ContentBlock::ToolResult {
776
+ tool_use_id: "c2".into(),
777
+ content: "[Image loaded — see attached image]".into(),
778
+ is_error: false,
779
+ },
780
+ ContentBlock::Image {
781
+ data_uri: "data:image/png;base64,img2".into(),
782
+ },
783
+ ],
784
+ },
785
+ // Step 3
786
+ ChatMessage {
787
+ role: ChatRole::Assistant,
788
+ content: vec![ContentBlock::Text {
789
+ text: "step 3".into(),
790
+ }],
791
+ },
792
+ ChatMessage {
793
+ role: ChatRole::Tool,
794
+ content: vec![
795
+ ContentBlock::ToolResult {
796
+ tool_use_id: "c3".into(),
797
+ content: "[Image loaded — see attached image]".into(),
798
+ is_error: false,
799
+ },
800
+ ContentBlock::Image {
801
+ data_uri: "data:image/png;base64,img3".into(),
802
+ },
803
+ ],
804
+ },
805
+ ];
806
+
807
+ // Retention is 2: Step 3 (most recent) and Step 2 are kept; Step 1 is pruned.
808
+ let pruned = prune_historic_images_from_native_messages(&mut messages, 2);
809
+ assert_eq!(pruned, 1);
810
+
811
+ // Step 1: Image removed, ToolResult updated
812
+ assert_eq!(messages[2].content.len(), 1);
813
+ match &messages[2].content[0] {
814
+ ContentBlock::ToolResult { content, .. } => {
815
+ assert!(content.contains("historical image pixels pruned from context"));
816
+ assert!(!content.contains("— see attached image"));
817
+ }
818
+ _ => panic!("Expected ToolResult block"),
819
+ }
820
+
821
+ // Step 2: Image kept
822
+ assert_eq!(messages[4].content.len(), 2);
823
+ assert!(matches!(messages[4].content[1], ContentBlock::Image { .. }));
824
+
825
+ // Step 3: Image kept
826
+ assert_eq!(messages[6].content.len(), 2);
827
+ assert!(matches!(messages[6].content[1], ContentBlock::Image { .. }));
828
+ }
829
+
830
+ fn sample_step_pair(index: usize) -> [ChatMessage; 2] {
831
+ [
832
+ ChatMessage {
833
+ role: ChatRole::Assistant,
834
+ content: vec![ContentBlock::ToolUse {
835
+ id: format!("call{index}"),
836
+ name: "read_file".into(),
837
+ input: serde_json::json!({"path": format!("file{index}.rs")}),
838
+ thought_signature: None,
839
+ }],
840
+ },
841
+ ChatMessage {
842
+ role: ChatRole::Tool,
843
+ content: vec![ContentBlock::ToolResult {
844
+ tool_use_id: format!("call{index}"),
845
+ content: format!("contents of file{index}.rs"),
846
+ is_error: false,
847
+ }],
848
+ },
849
+ ]
850
+ }
851
+
852
+ #[test]
853
+ fn render_messages_as_text_truncates_oversized_tool_results() {
854
+ let long_content = "x".repeat(10_000);
855
+ let messages = vec![
856
+ ChatMessage {
857
+ role: ChatRole::User,
858
+ content: vec![ContentBlock::Text {
859
+ text: "task".into(),
860
+ }],
861
+ },
862
+ ChatMessage {
863
+ role: ChatRole::Assistant,
864
+ content: vec![ContentBlock::ToolUse {
865
+ id: "c1".into(),
866
+ name: "cat_huge_file".into(),
867
+ input: serde_json::json!({}),
868
+ thought_signature: None,
869
+ }],
870
+ },
871
+ ChatMessage {
872
+ role: ChatRole::Tool,
873
+ content: vec![ContentBlock::ToolResult {
874
+ tool_use_id: "c1".into(),
875
+ content: long_content,
876
+ is_error: false,
877
+ }],
878
+ },
879
+ ];
880
+ let rendered = render_messages_as_text(&messages);
881
+ assert!(rendered.contains("Truncated"));
882
+ assert!(rendered.len() < 3000);
883
+ }
884
+
885
+ #[test]
886
+ fn hard_truncate_native_messages_preserves_task_and_role_alternation() {
887
+ let mut messages = vec![ChatMessage::text(ChatRole::User, "initial task")];
888
+ for i in 0..5 {
889
+ messages.extend(sample_step_pair(i));
890
+ }
891
+ // 5 step pairs total (11 messages). Compact 2 pairs (steps 0 and 1), keeping steps 2, 3, 4 (3 pairs = 6 msgs).
892
+ let truncated = hard_truncate_native_messages(&messages, 0, 2, "mock provider failure");
893
+
894
+ assert_eq!(truncated.len(), 1 + 2 + 6);
895
+ assert_eq!(truncated[0].role, ChatRole::User);
896
+ assert_eq!(truncated[1].role, ChatRole::Assistant);
897
+ assert_eq!(truncated[2].role, ChatRole::User);
898
+
899
+ // Verify summary contains key info
900
+ match &truncated[1].content[0] {
901
+ ContentBlock::Text { text } => {
902
+ assert!(text.contains("mock provider failure"));
903
+ assert!(text.contains("read_file"));
904
+ assert!(text.contains("file0.rs"));
905
+ assert!(text.contains("file1.rs"));
906
+ }
907
+ _ => panic!("Expected Text block in summary"),
908
+ }
909
+
910
+ // Verify role sequence after compaction:
911
+ // [0] User (initial task)
912
+ // [1] Assistant (compacted summary)
913
+ // [2] User (continuation prompt)
914
+ // [3..] Alternating Assistant (ToolUse) and Tool (ToolResult)
915
+ for (i, msg) in truncated.iter().enumerate().skip(3) {
916
+ let expected_role = if i % 2 == 1 {
917
+ ChatRole::Assistant
918
+ } else {
919
+ ChatRole::Tool
920
+ };
921
+ assert_eq!(msg.role, expected_role);
922
+ }
923
+ }
924
+
925
+ #[tokio::test]
926
+ async fn compact_native_messages_falls_back_to_hard_truncate_on_error() {
927
+ let mut messages = vec![ChatMessage::text(ChatRole::User, "initial task")];
928
+ // 5 step pairs = 2 to compact (since KEEP_RECENT = 3)
929
+ for i in 0..5 {
930
+ messages.extend(sample_step_pair(i));
931
+ }
932
+ let config = MintConfig {
933
+ ai_provider: "non_existent_provider_that_will_fail".into(),
934
+ ..Default::default()
935
+ };
936
+ let result = compact_native_messages(&config, &messages, 0)
937
+ .await
938
+ .unwrap();
939
+ assert!(result.is_some());
940
+ let (compacted, fallback) = result.unwrap();
941
+ assert_eq!(compacted.len(), 1 + 2 + 6);
942
+ assert_eq!(compacted[1].role, ChatRole::Assistant);
943
+ assert_eq!(compacted[2].role, ChatRole::User);
944
+ assert!(fallback.as_deref().unwrap_or("").contains("hard-truncate"));
945
+ }
946
+
947
+ #[tokio::test]
948
+ async fn compact_native_messages_preserves_conversation_history_prefix() {
949
+ // Build 2 historical conversation turns (4 messages: User, Assistant, User, Assistant)
950
+ let mut messages = vec![
951
+ ChatMessage::text(ChatRole::User, "ประวัติคุยรอบ 1"),
952
+ ChatMessage::text(ChatRole::Assistant, "ตอบประวัติรอบ 1"),
953
+ ChatMessage::text(ChatRole::User, "ประวัติคุยรอบ 2"),
954
+ ChatMessage::text(ChatRole::Assistant, "ตอบประวัติรอบ 2"),
955
+ ];
956
+ let history_prefix_len = messages.len();
957
+
958
+ // Current agent turn initial observation
959
+ messages.push(ChatMessage::text(ChatRole::User, "งานปัจจุบันรอบ 3"));
960
+
961
+ // Current turn execution steps: 5 step pairs (10 messages)
962
+ for i in 0..5 {
963
+ messages.extend(sample_step_pair(i));
964
+ }
965
+
966
+ let config = MintConfig {
967
+ ai_provider: "non_existent_provider_that_will_fail".into(),
968
+ ..Default::default()
969
+ };
970
+
971
+ let result = compact_native_messages(&config, &messages, history_prefix_len)
972
+ .await
973
+ .unwrap();
974
+ assert!(result.is_some());
975
+ let (compacted, _) = result.unwrap();
976
+
977
+ // Expected structure:
978
+ // [0..4] Historical conversation messages intact
979
+ // [4] Current turn initial task intact
980
+ // [5] Assistant compacted summary of steps 1-2
981
+ // [6] User continuation prompt
982
+ // [7..13] Recent 3 step pairs (6 messages)
983
+ assert_eq!(compacted.len(), 4 + 1 + 2 + 6);
984
+
985
+ // Verify history messages remain identical
986
+ assert_eq!(compacted[0].role, ChatRole::User);
987
+ assert_eq!(
988
+ compacted[0].content,
989
+ vec![ContentBlock::Text {
990
+ text: "ประวัติคุยรอบ 1".into()
991
+ }]
992
+ );
993
+ assert_eq!(compacted[1].role, ChatRole::Assistant);
994
+ assert_eq!(
995
+ compacted[1].content,
996
+ vec![ContentBlock::Text {
997
+ text: "ตอบประวัติรอบ 1".into()
998
+ }]
999
+ );
1000
+ assert_eq!(compacted[2].role, ChatRole::User);
1001
+ assert_eq!(
1002
+ compacted[2].content,
1003
+ vec![ContentBlock::Text {
1004
+ text: "ประวัติคุยรอบ 2".into()
1005
+ }]
1006
+ );
1007
+ assert_eq!(compacted[3].role, ChatRole::Assistant);
1008
+ assert_eq!(
1009
+ compacted[3].content,
1010
+ vec![ContentBlock::Text {
1011
+ text: "ตอบประวัติรอบ 2".into()
1012
+ }]
1013
+ );
1014
+
1015
+ // Verify current turn initial task intact
1016
+ assert_eq!(compacted[4].role, ChatRole::User);
1017
+ assert_eq!(
1018
+ compacted[4].content,
1019
+ vec![ContentBlock::Text {
1020
+ text: "งานปัจจุบันรอบ 3".into()
1021
+ }]
1022
+ );
1023
+
1024
+ // Verify summary block
1025
+ assert_eq!(compacted[5].role, ChatRole::Assistant);
1026
+ match &compacted[5].content[0] {
1027
+ ContentBlock::Text { text } => {
1028
+ assert!(text.contains("Summary of steps 1-2"));
1029
+ assert!(text.contains("file0.rs"));
1030
+ assert!(text.contains("file1.rs"));
1031
+ }
1032
+ _ => panic!("Expected Text block in summary"),
1033
+ }
1034
+
1035
+ // Verify continuation prompt
1036
+ assert_eq!(compacted[6].role, ChatRole::User);
1037
+
1038
+ // Verify recent step pairs preserved
1039
+ assert_eq!(compacted[7].role, ChatRole::Assistant);
1040
+ assert_eq!(compacted[8].role, ChatRole::Tool);
1041
+ }
1042
+
1043
+ #[test]
1044
+ fn test_prune_historic_tool_results_progressive_aging() {
1045
+ let mut messages = vec![ChatMessage::text(ChatRole::User, "initial task")];
1046
+ // Create 15 steps with verbose outputs (> 500 chars)
1047
+ for i in 0..15 {
1048
+ let verbose_log =
1049
+ format!("Line 1 of step {i}: compiler diagnostic message\n").repeat(30);
1050
+ messages.push(ChatMessage {
1051
+ role: ChatRole::Assistant,
1052
+ content: vec![ContentBlock::ToolUse {
1053
+ id: format!("call{i}"),
1054
+ name: "run_shell".into(),
1055
+ input: serde_json::json!({"cmd": "cargo check"}),
1056
+ thought_signature: None,
1057
+ }],
1058
+ });
1059
+ messages.push(ChatMessage {
1060
+ role: ChatRole::Tool,
1061
+ content: vec![ContentBlock::ToolResult {
1062
+ tool_use_id: format!("call{i}"),
1063
+ content: verbose_log,
1064
+ is_error: false,
1065
+ }],
1066
+ });
1067
+ }
1068
+
1069
+ // 3 hot steps, 7 warm steps
1070
+ let compacted = prune_historic_tool_results_from_native_messages(&mut messages, 3, 7);
1071
+ assert!(compacted > 0);
1072
+
1073
+ // Tool messages are at indices 2, 4, 6, ..., 30.
1074
+ // Step 14 is index 30 (hot, tool_count = 1) -> full text
1075
+ // Step 13 is index 28 (hot, tool_count = 2) -> full text
1076
+ // Step 12 is index 26 (hot, tool_count = 3) -> full text
1077
+ let msg_hot = &messages[30];
1078
+ if let ContentBlock::ToolResult { content, .. } = &msg_hot.content[0] {
1079
+ assert!(content.contains("Line 1 of step 14"));
1080
+ assert!(!content.contains("collapsed"));
1081
+ }
1082
+
1083
+ // Step 11 is index 24 (warm, tool_count = 4) -> warm collapsed
1084
+ let msg_warm = &messages[24];
1085
+ if let ContentBlock::ToolResult { content, .. } = &msg_warm.content[0] {
1086
+ assert!(content.contains("lines collapsed for earlier turn"));
1087
+ }
1088
+
1089
+ // Step 0 is index 2 (cold, tool_count = 15) -> tombstone
1090
+ let msg_cold = &messages[2];
1091
+ if let ContentBlock::ToolResult { content, .. } = &msg_cold.content[0] {
1092
+ assert_eq!(
1093
+ content,
1094
+ "[Tool Result: Succeeded — output collapsed for past step]"
1095
+ );
1096
+ }
1097
+ }
1098
+
1099
+ #[test]
1100
+ fn test_supersede_stale_file_reads() {
1101
+ let mut messages = vec![ChatMessage::text(ChatRole::User, "initial task")];
1102
+ // Step 1: read_file "src/main.rs"
1103
+ messages.push(ChatMessage {
1104
+ role: ChatRole::Assistant,
1105
+ content: vec![ContentBlock::ToolUse {
1106
+ id: "call_read_1".into(),
1107
+ name: "read_file".into(),
1108
+ input: serde_json::json!({"path": "src/main.rs"}),
1109
+ thought_signature: None,
1110
+ }],
1111
+ });
1112
+ messages.push(ChatMessage {
1113
+ role: ChatRole::Tool,
1114
+ content: vec![ContentBlock::ToolResult {
1115
+ tool_use_id: "call_read_1".into(),
1116
+ content: "fn main() { println!(\"old code\"); }".into(),
1117
+ is_error: false,
1118
+ }],
1119
+ });
1120
+
1121
+ // Step 2: edit src/main.rs
1122
+ let superseded = supersede_stale_file_reads(&mut messages, &["src/main.rs".to_string()], 2);
1123
+ assert_eq!(superseded, 1);
1124
+
1125
+ if let ContentBlock::ToolResult { content, .. } = &messages[2].content[0] {
1126
+ assert!(content.contains("Content superseded by file modifications at Step 2"));
1127
+ assert!(!content.contains("old code"));
1128
+ }
1129
+ }
1130
+
1131
+ #[test]
1132
+ fn test_rebuild_observation_compacts_older_trajectory_steps() {
1133
+ let root = Path::new("/workspace");
1134
+ let task = "Build project";
1135
+ let mut trajectory = Vec::new();
1136
+ for i in 1..=8 {
1137
+ let obs = format!("Long compiler output line for step {i}\n").repeat(10);
1138
+ trajectory.push(format_trajectory_step(
1139
+ i,
1140
+ "Checking code",
1141
+ "run_shell",
1142
+ &obs,
1143
+ ));
1144
+ }
1145
+
1146
+ let mut buffer = String::new();
1147
+ rebuild_observation(task, root, &trajectory, &mut buffer);
1148
+
1149
+ // Step 1 is older than 5 steps back -> compacted
1150
+ assert!(buffer.contains("details collapsed for earlier step"));
1151
+ // Step 8 is recent -> full observation intact
1152
+ assert!(buffer.contains("Long compiler output line for step 8"));
1153
+ }
320
1154
  }