@markusylisiurunen/tau 0.3.78 → 0.3.80
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.
- package/dist/code_mode/images.d.ts +3 -0
- package/dist/code_mode/images.js +37 -0
- package/dist/code_mode/images.js.map +1 -0
- package/dist/code_mode/output.d.ts +22 -0
- package/dist/code_mode/output.js +109 -0
- package/dist/code_mode/output.js.map +1 -0
- package/dist/code_mode/runtime.d.ts +2 -1
- package/dist/code_mode/runtime.js +92 -12
- package/dist/code_mode/runtime.js.map +1 -1
- package/dist/core/agent/agent_runtime.js +68 -76
- package/dist/core/agent/agent_runtime.js.map +1 -1
- package/dist/core/auth/auth_manager.js +3 -7
- package/dist/core/auth/auth_manager.js.map +1 -1
- package/dist/core/auth/auth_messages.js +1 -1
- package/dist/core/auth/auth_messages.js.map +1 -1
- package/dist/core/auth/auth_storage.js +71 -7
- package/dist/core/auth/auth_storage.js.map +1 -1
- package/dist/core/auth/cli.js +8 -7
- package/dist/core/auth/cli.js.map +1 -1
- package/dist/core/auth/credential_store.js +88 -186
- package/dist/core/auth/credential_store.js.map +1 -1
- package/dist/core/auth/index.js +1 -1
- package/dist/core/auth/index.js.map +1 -1
- package/dist/core/auth/providers/openai_codex.js +51 -229
- package/dist/core/auth/providers/openai_codex.js.map +1 -1
- package/dist/core/cli.js +1 -2
- package/dist/core/cli.js.map +1 -1
- package/dist/core/client_tools/command_client_tools.js +2 -2
- package/dist/core/commands/registry.js +16 -1
- package/dist/core/commands/registry.js.map +1 -1
- package/dist/core/config/content_loader.js +30 -131
- package/dist/core/config/content_loader.js.map +1 -1
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/mcp.js +68 -0
- package/dist/core/config/mcp.js.map +1 -0
- package/dist/core/config/paths.js +0 -1
- package/dist/core/config/paths.js.map +1 -1
- package/dist/core/config/runtime.js +3 -2
- package/dist/core/config/runtime.js.map +1 -1
- package/dist/core/config/runtime_config_snapshot.js +23 -9
- package/dist/core/config/runtime_config_snapshot.js.map +1 -1
- package/dist/core/config/schema.js +39 -73
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/config/skills_loader.js +6 -2
- package/dist/core/config/skills_loader.js.map +1 -1
- package/dist/core/debug.js +1 -16
- package/dist/core/debug.js.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/mcp/manager.js +245 -0
- package/dist/core/mcp/manager.js.map +1 -0
- package/dist/core/mcp/search.js +77 -0
- package/dist/core/mcp/search.js.map +1 -0
- package/dist/core/models/catalog.js +2 -239
- package/dist/core/models/catalog.js.map +1 -1
- package/dist/core/personas.js +2 -15
- package/dist/core/personas.js.map +1 -1
- package/dist/core/runtime/agent_model.js +0 -3
- package/dist/core/runtime/agent_model.js.map +1 -1
- package/dist/core/runtime/chat_runtime.js +19 -13
- package/dist/core/runtime/chat_runtime.js.map +1 -1
- package/dist/core/runtime/runtime_bootstrap.js +12 -59
- package/dist/core/runtime/runtime_bootstrap.js.map +1 -1
- package/dist/core/session/auto_compaction_archive.js +1 -1
- package/dist/core/session/auto_compaction_archive.js.map +1 -1
- package/dist/core/session/compaction.js +79 -506
- package/dist/core/session/compaction.js.map +1 -1
- package/dist/core/static/code_mode/mcp/documentation.md +113 -0
- package/dist/core/static/code_mode/sandbox_runner.mjs +58 -3
- package/dist/core/static/tau_docs/client-tools.md +32 -30
- package/dist/core/static/tau_docs/config-reference.md +60 -38
- package/dist/core/static/tau_docs/configuration.md +3 -16
- package/dist/core/static/tau_docs/credentials.md +20 -50
- package/dist/core/static/tau_docs/index.md +2 -1
- package/dist/core/static/tau_docs/manifest.json +1 -0
- package/dist/core/static/tau_docs/models.md +8 -159
- package/dist/core/static/tau_docs/node-sdk.md +4 -2
- package/dist/core/static/tau_docs/openrouter.md +165 -0
- package/dist/core/static/tau_docs/ownership-and-scope.md +5 -3
- package/dist/core/static/tau_docs/personas.md +11 -43
- package/dist/core/static/tau_docs/prompts-and-project-context.md +10 -44
- package/dist/core/static/tau_docs/remote-sessions.md +6 -7
- package/dist/core/static/tau_docs/security.md +17 -6
- package/dist/core/static/tau_docs/session-protocol-methods.md +8 -4
- package/dist/core/static/tau_docs/session-protocol.md +12 -10
- package/dist/core/static/tau_docs/sessions.md +8 -6
- package/dist/core/static/tau_docs/skills.md +8 -32
- package/dist/core/static/tau_docs/subagents.md +4 -3
- package/dist/core/static/tau_docs/telegram.md +2 -2
- package/dist/core/static/tau_docs/tools.md +22 -6
- package/dist/core/static/tau_docs/troubleshooting.md +11 -12
- package/dist/core/static/tau_docs/tui.md +10 -3
- package/dist/core/subagents/agent_supervisor.js +1 -2
- package/dist/core/subagents/agent_supervisor.js.map +1 -1
- package/dist/core/subagents/registry.js +2 -1
- package/dist/core/subagents/registry.js.map +1 -1
- package/dist/core/subagents/types.js +2 -1
- package/dist/core/subagents/types.js.map +1 -1
- package/dist/core/telegram/adapter.js +1 -1
- package/dist/core/telegram/adapter.js.map +1 -1
- package/dist/core/tool/cli.js +10 -2
- package/dist/core/tool/cli.js.map +1 -1
- package/dist/core/tool/openrouter.js +291 -0
- package/dist/core/tool/openrouter.js.map +1 -0
- package/dist/core/tool/openrouter_decisions.js +97 -0
- package/dist/core/tool/openrouter_decisions.js.map +1 -0
- package/dist/core/tool/openrouter_media.js +180 -0
- package/dist/core/tool/openrouter_media.js.map +1 -0
- package/dist/core/tools/catalog.js +14 -2
- package/dist/core/tools/catalog.js.map +1 -1
- package/dist/core/tools/code_mode.js +5 -2
- package/dist/core/tools/code_mode.js.map +1 -1
- package/dist/core/tools/code_mode_worker.js +33 -1
- package/dist/core/tools/code_mode_worker.js.map +1 -1
- package/dist/core/tools/history.js +1 -1
- package/dist/core/tools/history.js.map +1 -1
- package/dist/core/tools/mcp.js +167 -0
- package/dist/core/tools/mcp.js.map +1 -0
- package/dist/core/tools/nook.js +1 -1
- package/dist/core/tools/nook.js.map +1 -1
- package/dist/core/tools/spawn_agent.js +1 -0
- package/dist/core/tools/spawn_agent.js.map +1 -1
- package/dist/core/tools/tau_docs.js +1 -0
- package/dist/core/tools/tau_docs.js.map +1 -1
- package/dist/core/tools/tool_names.js +2 -0
- package/dist/core/tools/tool_names.js.map +1 -1
- package/dist/core/tools/view_image.js +1 -105
- package/dist/core/tools/view_image.js.map +1 -1
- package/dist/core/tools/web.js +1 -1
- package/dist/core/tools/web.js.map +1 -1
- package/dist/core/utils/bm25.js +74 -0
- package/dist/core/utils/bm25.js.map +1 -0
- package/dist/core/utils/model_image.js +106 -0
- package/dist/core/utils/model_image.js.map +1 -0
- package/dist/core/utils/model_stream.js +47 -34
- package/dist/core/utils/model_stream.js.map +1 -1
- package/dist/core/utils/user_metadata.js +2 -27
- package/dist/core/utils/user_metadata.js.map +1 -1
- package/dist/core/version.js +2 -2
- package/dist/core/version.js.map +1 -1
- package/dist/diff_tool/app/dist/assets/{ada-C5qYipkI.js → ada-X3Y2mlq2.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{ahk-CA9gdOdF.js → ahk-DwADkxyd.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{angular-html-CnO8qept.js → angular-html-BbLgbIhq.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{angular-ts-DPXUio9Z.js → angular-ts-DXk17TRM.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{apl-X8YsymsQ.js → apl-BsvksCXR.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{astro-BQ9k8AQ0.js → astro-DH775E4V.js} +1 -1
- package/dist/diff_tool/app/dist/assets/beancount-C2IN4Vk8.js +1 -0
- package/dist/diff_tool/app/dist/assets/{blade-DZ1LYIzB.js → blade-Ck99Rm59.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{c-VLTwNh7z.js → c-DJpHqu5J.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{chapel-5s-sGN8D.js → chapel-Owff0Csy.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{cobol-C9RzwrVu.js → cobol-Cv2gZuhO.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{coffee-BHvjZ343.js → coffee-Bji0YCf_.js} +1 -1
- package/dist/diff_tool/app/dist/assets/coq-CGaSfhwR.js +1 -0
- package/dist/diff_tool/app/dist/assets/{cpp-CBTVXbBp.js → cpp-DTjA_yFF.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{crystal-DQJua4y4.js → crystal-Dd00NOeb.js} +1 -1
- package/dist/diff_tool/app/dist/assets/csharp-dmMxLVLW.js +1 -0
- package/dist/diff_tool/app/dist/assets/css-D44TN1V6.js +1 -0
- package/dist/diff_tool/app/dist/assets/dart-CHZY9Xhz.js +1 -0
- package/dist/diff_tool/app/dist/assets/dotenv-CuH5my32.js +1 -0
- package/dist/diff_tool/app/dist/assets/{edge-BmdmXGH4.js → edge-CVmGSi2m.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{elixir-oiOLs98L.js → elixir-B8Mq7no2.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{elm-BgYuiU4E.js → elm-CXS0I3Z2.js} +1 -1
- package/dist/diff_tool/app/dist/assets/emacs-lisp-DR2vtWaj.js +1 -0
- package/dist/diff_tool/app/dist/assets/{erb-CvFrXpyY.js → erb-B9oDKaUo.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{git-rebase-D3Zo1BLH.js → git-rebase-DT-YFebH.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{glimmer-js-B4-8E3lJ.js → glimmer-js-s0DXlNjq.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{glimmer-ts-CtKkD0t_.js → glimmer-ts-QgEB5S2z.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{glsl-BAqforx_.js → glsl-NA0icwbY.js} +1 -1
- package/dist/diff_tool/app/dist/assets/gn-CAXYAgV-.js +1 -0
- package/dist/diff_tool/app/dist/assets/{graphql-DuE1RMyL.js → graphql-0_dOlfV0.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{hack-CHBcXjz1.js → hack-D-mr7l1l.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{haml-DAs2z3tD.js → haml-B0-oQmz7.js} +1 -1
- package/dist/diff_tool/app/dist/assets/handlebars-Yq9bXpWN.js +1 -0
- package/dist/diff_tool/app/dist/assets/{html-D5co0BLD.js → html-B8bMmdRK.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{html-derivative-BZaWEmAT.js → html-derivative-BpxSlQb_.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{http-Cii5MjJE.js → http-hS_53mxt.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{hurl-Bur-XdJO.js → hurl-B2ST1kwl.js} +1 -1
- package/dist/diff_tool/app/dist/assets/index-CBT_sNIz.js +340 -0
- package/dist/diff_tool/app/dist/assets/{java-DN39wI4w.js → java-D4mj0lZJ.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{javascript-VUReF1H4.js → javascript-wC7rrKiV.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{jinja-BcrfV1JB.js → jinja-DbQ3o87F.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{jison-Bez5Mtmy.js → jison-CrE9FdvP.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{json-ChV8m0Le.js → json-xjicDyWN.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{jsx-D0SXNtM0.js → jsx-m28lXojQ.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{julia-DvhpcBwG.js → julia-19xkOmop.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{just-BGwe8S6x.js → just-Cf7OorTr.js} +1 -1
- package/dist/diff_tool/app/dist/assets/latex-DDb7GQOy.js +1 -0
- package/dist/diff_tool/app/dist/assets/{liquid-UdnqDjKz.js → liquid-DHOuQ0rf.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{lua-CjDHeHEr.js → lua-BGyIvonw.js} +1 -1
- package/dist/diff_tool/app/dist/assets/luau-VGWVLoqX.js +1 -0
- package/dist/diff_tool/app/dist/assets/marko-DB5OqI1C.js +1 -0
- package/dist/diff_tool/app/dist/assets/{mdc-BOLj6Oyq.js → mdc-DTyNMupO.js} +1 -1
- package/dist/diff_tool/app/dist/assets/monokai-BscAjiQZ.js +1 -0
- package/dist/diff_tool/app/dist/assets/moonbit-D9W784E_.js +1 -0
- package/dist/diff_tool/app/dist/assets/nextflow-CSgcYZcx.js +1 -0
- package/dist/diff_tool/app/dist/assets/{nextflow-groovy-DJMQeKeT.js → nextflow-groovy-D7IRt6Pp.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{nginx-5r5xPc2T.js → nginx-DfF0fMYD.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{nim-9exKQYMz.js → nim-BbwsXuZD.js} +1 -1
- package/dist/diff_tool/app/dist/assets/nushell--0fT3PI1.js +1 -0
- package/dist/diff_tool/app/dist/assets/one-dark-pro-C6YyR8OD.js +1 -0
- package/dist/diff_tool/app/dist/assets/{org-B2fpAlbt.js → org-BkOBBl1f.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{perl-DV2fcwyY.js → perl-BTXTOl4K.js} +1 -1
- package/dist/diff_tool/app/dist/assets/php-DIMVQWiA.js +1 -0
- package/dist/diff_tool/app/dist/assets/{powershell-CCSX75yM.js → powershell-QtSnmXcu.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{pug-DuKcQxFj.js → pug-B_nrb4dJ.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{qml-C16b4SYx.js → qml-1PXi8G8Z.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{r-B1ZldnJf.js → r-CJrAkc2Z.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{razor-TYmslaAB.js → razor-DgPUftNd.js} +1 -1
- package/dist/diff_tool/app/dist/assets/red-CYlAq2b0.js +1 -0
- package/dist/diff_tool/app/dist/assets/{regexp-dWCffmDD.js → regexp-C2hS8XvL.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{rst-DEkLr2YR.js → rst-CDouhKnc.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{ruby-BJnJzr4u.js → ruby-CAjKW1uO.js} +1 -1
- package/dist/diff_tool/app/dist/assets/rust-DpiIf5JO.js +1 -0
- package/dist/diff_tool/app/dist/assets/{sas-DeRsDbUE.js → sas-qAHkHLc1.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{scss-SGV_CwKm.js → scss-Bfx2Ydid.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{shellscript-BI7khmmR.js → shellscript-Bu76R8y2.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{shellsession-Nupw_Vvw.js → shellsession-BU8BL0oL.js} +1 -1
- package/dist/diff_tool/app/dist/assets/solarized-dark-b97czJOk.js +1 -0
- package/dist/diff_tool/app/dist/assets/solarized-light-DFPxpIYQ.js +1 -0
- package/dist/diff_tool/app/dist/assets/{soy-B96cBzxv.js → soy-FRl8ozP-.js} +1 -1
- package/dist/diff_tool/app/dist/assets/sql-BacQgsEs.js +1 -0
- package/dist/diff_tool/app/dist/assets/{stata-Dnq48cE6.js → stata-B9kkG-ET.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{surrealql-D6lw4TiD.js → surrealql-qvETr7iY.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{svelte-ChVoq9tB.js → svelte-B0z1MgHc.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{templ-Dh1EXuHD.js → templ-DTnPshKb.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{tex-KTYusNFe.js → tex-Cosab9_H.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{ts-tags-DC2RU1_R.js → ts-tags-DNYvLFUH.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{tsx-DtIM39Jy.js → tsx-Dstq6j1a.js} +1 -1
- package/dist/diff_tool/app/dist/assets/twig-BzqZdwaX.js +1 -0
- package/dist/diff_tool/app/dist/assets/{typescript-BGAE5iuw.js → typescript-YOQ_oE25.js} +1 -1
- package/dist/diff_tool/app/dist/assets/typespec-BGhR2SqG.js +1 -0
- package/dist/diff_tool/app/dist/assets/{typst-nWoGZ22y.js → typst-DTffwfpc.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{vue-iyHf-l4z.js → vue-D4OMj_C5.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{vue-html-prNdIjLu.js → vue-html-kT4WrHGK.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{vue-vine-KSSlnVeg.js → vue-vine-CxeapeMO.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{xml-DdCC83Xd.js → xml-DWVpuurg.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{xsl-DSqZxsez.js → xsl-C0ciup5a.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{yaml-CZcBUWvf.js → yaml-98Fvyfpc.js} +1 -1
- package/dist/diff_tool/app/dist/index.html +1 -1
- package/dist/execution/execution_environment.js.map +1 -1
- package/dist/execution/fly_sprite_execution_environment.js +5 -10
- package/dist/execution/fly_sprite_execution_environment.js.map +1 -1
- package/dist/execution/tool_backend_execution_environment.js +0 -2
- package/dist/execution/tool_backend_execution_environment.js.map +1 -1
- package/dist/host/client_tool_broker.js +1 -1
- package/dist/host/client_tool_broker.js.map +1 -1
- package/dist/host/execution_runtime.js +5 -4
- package/dist/host/execution_runtime.js.map +1 -1
- package/dist/host/hosted_ephemeral_agent_session.js +0 -2
- package/dist/host/hosted_ephemeral_agent_session.js.map +1 -1
- package/dist/host/local_session_host.js +26 -32
- package/dist/host/local_session_host.js.map +1 -1
- package/dist/host/session_host.js.map +1 -1
- package/dist/main.js +15 -29
- package/dist/main.js.map +1 -1
- package/dist/protocol/session_protocol.d.ts +14 -12
- package/dist/protocol/session_protocol.js +30 -7
- package/dist/protocol/session_protocol.js.map +1 -1
- package/dist/sdk/client_tool_command.d.ts +12 -11
- package/dist/sdk/client_tool_command.js +8 -8
- package/dist/sdk/client_tool_command.js.map +1 -1
- package/dist/sdk/code_mode.js +1 -1
- package/dist/sdk/code_mode.js.map +1 -1
- package/dist/sdk/local_client.js +4 -3
- package/dist/sdk/local_client.js.map +1 -1
- package/dist/sdk/session.js +1 -1
- package/dist/sdk/session.js.map +1 -1
- package/dist/sdk/types.d.ts +2 -1
- package/dist/store/session_snapshot_migrations.js +28 -1
- package/dist/store/session_snapshot_migrations.js.map +1 -1
- package/dist/tui/chat_view.js +3 -1
- package/dist/tui/chat_view.js.map +1 -1
- package/dist/tui/session_chat_app.js +2 -4
- package/dist/tui/session_chat_app.js.map +1 -1
- package/dist/tui/session_chat_controller.js +121 -6
- package/dist/tui/session_chat_controller.js.map +1 -1
- package/dist/tui/ui/custom_editor.js +49 -10
- package/dist/tui/ui/custom_editor.js.map +1 -1
- package/dist/tui/ui/footer.js +4 -2
- package/dist/tui/ui/footer.js.map +1 -1
- package/dist/tui/ui/slash_autocomplete.js +5 -1
- package/dist/tui/ui/slash_autocomplete.js.map +1 -1
- package/package.json +10 -9
- package/dist/diff_tool/app/dist/assets/beancount-D-usSTwE.js +0 -1
- package/dist/diff_tool/app/dist/assets/coq-DuBRPxYg.js +0 -1
- package/dist/diff_tool/app/dist/assets/csharp-oqKa8noW.js +0 -1
- package/dist/diff_tool/app/dist/assets/css-BQflXFb6.js +0 -1
- package/dist/diff_tool/app/dist/assets/dart-CnvKMtbv.js +0 -1
- package/dist/diff_tool/app/dist/assets/dotenv-_5a1GRtc.js +0 -1
- package/dist/diff_tool/app/dist/assets/emacs-lisp-c_oH4hRZ.js +0 -1
- package/dist/diff_tool/app/dist/assets/gn-ilITqXS6.js +0 -1
- package/dist/diff_tool/app/dist/assets/handlebars-CfAla6QK.js +0 -1
- package/dist/diff_tool/app/dist/assets/index-CZUi_I-p.js +0 -340
- package/dist/diff_tool/app/dist/assets/latex-pWSag83P.js +0 -1
- package/dist/diff_tool/app/dist/assets/luau-C2pBCSgt.js +0 -1
- package/dist/diff_tool/app/dist/assets/marko-yLX6iW68.js +0 -1
- package/dist/diff_tool/app/dist/assets/monokai-B_bV9PQ9.js +0 -1
- package/dist/diff_tool/app/dist/assets/moonbit-DgjMoLWr.js +0 -1
- package/dist/diff_tool/app/dist/assets/nextflow-BJtWHP5T.js +0 -1
- package/dist/diff_tool/app/dist/assets/nushell-DHYfO66s.js +0 -1
- package/dist/diff_tool/app/dist/assets/one-dark-pro-CLwyXe_n.js +0 -1
- package/dist/diff_tool/app/dist/assets/php-D-AthX_E.js +0 -1
- package/dist/diff_tool/app/dist/assets/red-DX1BQOs8.js +0 -1
- package/dist/diff_tool/app/dist/assets/rust-Cfkwpbl8.js +0 -1
- package/dist/diff_tool/app/dist/assets/solarized-dark-UdsmMDCL.js +0 -1
- package/dist/diff_tool/app/dist/assets/solarized-light-C1IUL_tW.js +0 -1
- package/dist/diff_tool/app/dist/assets/sql-CsIdKfaO.js +0 -1
- package/dist/diff_tool/app/dist/assets/twig-C6D_TA3n.js +0 -1
- package/dist/diff_tool/app/dist/assets/typespec-BRdr0IET.js +0 -1
|
@@ -1,465 +1,97 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
1
|
import { isSystemCompactionContinuation } from "../../protocol/system_message.js";
|
|
3
|
-
import { buildCompactionUserMessage
|
|
2
|
+
import { buildCompactionUserMessage } from "../utils/compact.js";
|
|
4
3
|
import { extractAssistantText } from "../utils/messages.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
const
|
|
9
|
-
const RETAINED_TOOL_RESULT_MAX_TOKENS = 8_192;
|
|
10
|
-
const PRESERVED_USER_MESSAGE_IDS_OPEN_TAG = "<preserved-user-message-ids>";
|
|
11
|
-
const PRESERVED_USER_MESSAGE_IDS_CLOSE_TAG = "</preserved-user-message-ids>";
|
|
12
|
-
export const COMPACTION_SUMMARIZATION_SYSTEM_PROMPT = "You are a context compaction assistant. Your output will replace the conversation history for another assistant. Do not continue the conversation. Do not answer any conversation questions. Only output a structured handoff summary followed by the required preserved user message id block.";
|
|
13
|
-
const COMPACTION_SUMMARIZATION_PROMPT = `The messages above are a conversation to compact. Create an information-dense context checkpoint summary that will replace the full conversation history. Another assistant should be able to continue the session from this summary as if the original conversation were still available.
|
|
4
|
+
import { estimateMessageTokens } from "../utils/token.js";
|
|
5
|
+
import { formatTauUserText, getSummaryCompactionMetadataFromMessage, hasAutoCompactionContinuationMetadata, hasToolRecoveryMetadata, } from "../utils/user_metadata.js";
|
|
6
|
+
import { AUTO_COMPACTION_ARCHIVE_DOCUMENTATION, } from "./auto_compaction_archive.js";
|
|
7
|
+
const COMPACTION_SUMMARIZATION_PROMPT = `You are pausing your current work to compact your own conversation and free space in your context window. The conversation you can see now will be replaced with the compaction summary you write. After that, you will continue as the same agent in the same session, working on the same task, but without the full earlier conversation available.
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
Write a compaction summary of the conversation: what the user asked for, what has been done and learned, and what remains to be done. It should also give you the handoff you will need to resume that work as smoothly as possible. Your next continuation should be able to understand what the user wants, where the work stands, and what to do next from the compaction summary alone. Think through what you would otherwise forget: important constraints, evidence, decisions and their rationale, unresolved questions, and unfinished work. Preserve what will let you continue without reconstructing the conversation, repeating completed work, or asking the user to explain it again. Recent messages may also remain, but treat them as additional detail rather than something your compaction summary depends on. Some overlap is expected.
|
|
16
10
|
|
|
17
|
-
|
|
11
|
+
Preserve continuity-critical information in compact form:
|
|
12
|
+
- The current objective, still-relevant original requests, and user constraints, preferences, and corrections.
|
|
13
|
+
- Confirmed progress, current work, blockers, and the next concrete actions.
|
|
14
|
+
- Decisions and their useful rationale, including rejected approaches when they matter for continuation.
|
|
15
|
+
- Evidence needed to resume: exact paths, identifiers, commands, important errors, and verification status.
|
|
16
|
+
- Uncertainties, unverified assumptions, pending validation, and the difference between attempted work and confirmed outcomes.
|
|
17
|
+
- For unfinished tool work, the request being pursued, results already received, and what remains to interpret or do. Do not repeat completed tool calls just because the earlier exchange is no longer visible.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
[What the user is currently trying to accomplish. If the goal changed, briefly note the shift.]
|
|
19
|
+
Incorporate still-relevant information from any previous compaction summary. Remove information that is clearly obsolete or superseded. Collapse tangents and repetition unless they affect the work. When a detail may matter later, preserve it concisely rather than omitting it solely for brevity.
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
- [Constraints, preferences, or requirements from the user]
|
|
24
|
-
- [Use "(none)" when nothing explicit exists]
|
|
21
|
+
Choose the structure that best supports your continuation. Goal, Constraints, Progress, Decisions, Next actions, and Critical context can be useful headings, but are not a required form. Record actionable conclusions and rationale, not a transcript of internal thinking. The base system instructions remain available separately; do not spend the compaction summary reproducing them.
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
### Done
|
|
28
|
-
- [x] [Completed tasks and confirmed outcomes]
|
|
23
|
+
Do not include large verbatim chunks from user messages, pasted documents, or tool output. Summarize the relevant requirements and findings.
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
- [ ] [Current work in progress]
|
|
25
|
+
Output only the compaction summary.
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
1. [Ordered next action]
|
|
41
|
-
|
|
42
|
-
## Critical Context
|
|
43
|
-
- [Concrete details needed to resume: file paths, function names, commands, errors, test/build status, assumptions]
|
|
44
|
-
|
|
45
|
-
<preserved-user-message-ids>
|
|
46
|
-
[JSON array of history entry id strings for user messages to copy verbatim into the compaction summary. Use [] when no candidate should be copied verbatim.]
|
|
47
|
-
</preserved-user-message-ids>
|
|
48
|
-
|
|
49
|
-
Rules:
|
|
50
|
-
- Preserve as much continuity-critical context as possible while removing tokens.
|
|
51
|
-
- Optimize for continuing the work, not retrospectively describing the conversation.
|
|
52
|
-
- The Goal section must preserve the user's current objective and any still-relevant original request, even if it appears early in the conversation.
|
|
53
|
-
- Keep each section information-dense and focused; do not omit useful details solely for brevity.
|
|
54
|
-
- When unsure whether a detail may matter later, preserve it in compact form.
|
|
55
|
-
- Preserve the current state of the work: files touched, commands run, test/build status, known failures, unverified assumptions, and pending validation.
|
|
56
|
-
- Distinguish attempted work from confirmed outcomes.
|
|
57
|
-
- If goals evolved over time, capture the current goal and briefly note the change.
|
|
58
|
-
- Collapse tangents, retries, and pleasantries unless they materially affect decisions, blockers, or next steps.
|
|
59
|
-
- Select preserved user message ids only from <user-message-candidates>. The candidates with source "conversation" are identified inline in <conversation> by matching [User id="..."] markers. Select user messages whose exact wording is likely needed to continue, such as standing goals, constraints, corrections, explicit instructions, and recent actionable requests. Omit resolved, repetitive, superseded, or conversational messages. Keep the selected messages under roughly 20,000 tokens total.
|
|
60
|
-
- Preserve exact file paths, function names, commands, and error messages.
|
|
61
|
-
- Treat the suggested headings as a checklist, not a form to fill mechanically. Add project-specific sections, combine or omit empty subsections, and use prose or tables when they communicate the handoff more clearly.`;
|
|
62
|
-
const COMPACTION_UPDATE_SUMMARIZATION_PROMPT = `The messages above are new conversation messages to incorporate into the existing summary in <previous-summary> tags. The updated summary will replace the prior summary plus these new messages as the session's continuity context.
|
|
63
|
-
|
|
64
|
-
If a [System prompt] block is present, use it as context for interpreting the new conversation messages. Do not summarize it as part of the conversation history.
|
|
65
|
-
|
|
66
|
-
Update the existing structured summary with these rules:
|
|
67
|
-
- Preserve all still-relevant information from the previous summary.
|
|
68
|
-
- Add new progress, decisions, and context from the new messages.
|
|
69
|
-
- Move items from In Progress to Done when completed.
|
|
70
|
-
- Update Next Steps based on the current state.
|
|
71
|
-
- Remove only information that is clearly obsolete, superseded, or irrelevant to continuing the session.
|
|
72
|
-
|
|
73
|
-
Use the previous summary's structure when it remains clear, but reorganize it when the conversation has changed enough that another structure would produce a better handoff. Preserve the same continuity-critical concerns. You may combine, omit, or add sections, use project-specific headings, and mix concise prose with lists. The <preserved-user-message-ids> block remains required and must appear exactly once at the end.
|
|
74
|
-
|
|
75
|
-
## Goal
|
|
76
|
-
[Preserve and extend goals as needed. If the goal shifted, reflect the latest goal and note the change briefly.]
|
|
77
|
-
|
|
78
|
-
## Constraints & Preferences
|
|
79
|
-
- [Preserve and extend constraints]
|
|
80
|
-
|
|
81
|
-
## Progress
|
|
82
|
-
### Done
|
|
83
|
-
- [x] [Previously done and newly completed]
|
|
84
|
-
|
|
85
|
-
### In Progress
|
|
86
|
-
- [ ] [Current work]
|
|
87
|
-
|
|
88
|
-
### Blocked
|
|
89
|
-
- [Current blockers, or "(none)"]
|
|
90
|
-
|
|
91
|
-
## Key Decisions
|
|
92
|
-
- **[Decision]**: [Brief rationale]
|
|
93
|
-
|
|
94
|
-
## Next Steps
|
|
95
|
-
1. [Updated ordered actions]
|
|
96
|
-
|
|
97
|
-
## Critical Context
|
|
98
|
-
- [Concrete details needed to resume: file paths, function names, commands, errors, test/build status, assumptions]
|
|
99
|
-
|
|
100
|
-
<preserved-user-message-ids>
|
|
101
|
-
[JSON array of history entry id strings for user messages to copy verbatim into the compaction summary. Use [] when no candidate should be copied verbatim.]
|
|
102
|
-
</preserved-user-message-ids>
|
|
103
|
-
|
|
104
|
-
Rules:
|
|
105
|
-
- Preserve as much continuity-critical context as possible while removing tokens.
|
|
106
|
-
- Optimize for continuing the work, not retrospectively describing the conversation.
|
|
107
|
-
- The Goal section must preserve the user's current objective and any still-relevant original request, even if it appears early in the conversation.
|
|
108
|
-
- Keep each section information-dense and focused; do not omit useful details solely for brevity.
|
|
109
|
-
- When unsure whether a detail may matter later, preserve it in compact form.
|
|
110
|
-
- Preserve the current state of the work: files touched, commands run, test/build status, known failures, unverified assumptions, and pending validation.
|
|
111
|
-
- Distinguish attempted work from confirmed outcomes.
|
|
112
|
-
- If goals evolved over time, capture the current goal and briefly note the change.
|
|
113
|
-
- Collapse tangents, retries, and pleasantries unless they materially affect decisions, blockers, or next steps.
|
|
114
|
-
- Select preserved user message ids only from <user-message-candidates>. The candidates with source "conversation" are identified inline in <conversation> by matching [User id="..."] markers. Select user messages whose exact wording is likely needed to continue, such as standing goals, constraints, corrections, explicit instructions, and recent actionable requests. Omit resolved, repetitive, superseded, or conversational messages. Keep the selected messages under roughly 20,000 tokens total.
|
|
115
|
-
- Preserve exact file paths, function names, commands, and error messages.
|
|
116
|
-
- Treat the suggested headings as a checklist, not a form to fill mechanically. Add project-specific sections, combine or omit empty subsections, and use prose or tables when they communicate the handoff more clearly.`;
|
|
117
|
-
export function prepareSessionCompaction(entries, options) {
|
|
118
|
-
const latestCompaction = findLatestCompactionEntry(entries);
|
|
119
|
-
const entriesToSummarize = entries
|
|
120
|
-
.slice(latestCompaction.index + 1)
|
|
121
|
-
.filter((entry) => !isCompactionContinuation(entry.message));
|
|
122
|
-
const messagesToSummarize = entriesToSummarize.map((entry) => entry.message);
|
|
123
|
-
const historyEntryIds = buildHistoryEntryIdMap(entriesToSummarize);
|
|
124
|
-
const formattedConversation = formatHistoryForCompaction(messagesToSummarize, {
|
|
125
|
-
historyEntryIds,
|
|
126
|
-
});
|
|
127
|
-
if (!formattedConversation) {
|
|
27
|
+
Do not answer the latest request, perform more work, or call tools.`;
|
|
28
|
+
export function prepareSessionCompaction(entries) {
|
|
29
|
+
const latestCompactionIndex = findLatestCompactionIndex(entries);
|
|
30
|
+
const activeEntries = entries.filter((entry) => !isCompactionContinuation(entry.message));
|
|
31
|
+
if (!entries
|
|
32
|
+
.slice(latestCompactionIndex + 1)
|
|
33
|
+
.some((entry) => !isCompactionContinuation(entry.message))) {
|
|
128
34
|
return undefined;
|
|
129
35
|
}
|
|
130
|
-
const formattedHistory = formatHistoryForCompaction(messagesToSummarize, {
|
|
131
|
-
systemPrompt: options.systemPrompt,
|
|
132
|
-
historyEntryIds,
|
|
133
|
-
});
|
|
134
36
|
return {
|
|
135
|
-
|
|
136
|
-
messagesToSummarize,
|
|
137
|
-
formattedHistory,
|
|
138
|
-
userMessageCandidates: collectUserMessageCandidates(entriesToSummarize, latestCompaction.preservedUserMessages),
|
|
37
|
+
messagesToSummarize: activeEntries.map((entry) => entry.message),
|
|
139
38
|
};
|
|
140
39
|
}
|
|
141
|
-
export function buildSessionCompactionPrompt(args) {
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
summaryPrompt += `<previous-summary>\n${preparation.previousSummary.trim()}\n</previous-summary>\n\n`;
|
|
146
|
-
}
|
|
147
|
-
if (preparation.userMessageCandidates.length > 0) {
|
|
148
|
-
summaryPrompt += `<user-message-candidates>\n${formatUserMessageCandidates(preparation.userMessageCandidates)}\n</user-message-candidates>\n\n`;
|
|
149
|
-
}
|
|
150
|
-
summaryPrompt += preparation.previousSummary
|
|
151
|
-
? COMPACTION_UPDATE_SUMMARIZATION_PROMPT
|
|
40
|
+
export function buildSessionCompactionPrompt(args = {}) {
|
|
41
|
+
const guidance = args.guidance?.trim();
|
|
42
|
+
return guidance
|
|
43
|
+
? `${COMPACTION_SUMMARIZATION_PROMPT}\n\nAdditional compaction summary focus: ${guidance}`
|
|
152
44
|
: COMPACTION_SUMMARIZATION_PROMPT;
|
|
153
|
-
const guidanceBlock = guidance?.trim();
|
|
154
|
-
if (guidanceBlock) {
|
|
155
|
-
summaryPrompt += `\n\nAdditional focus: ${guidanceBlock}`;
|
|
156
|
-
}
|
|
157
|
-
return summaryPrompt;
|
|
158
45
|
}
|
|
159
46
|
export function buildSessionCompactionMessage(args) {
|
|
160
47
|
const lastAssistantMessage = args.mode === "with-last-assistant"
|
|
161
48
|
? extractLastAssistantMessage(args.messagesToSummarize)
|
|
162
49
|
: undefined;
|
|
163
|
-
const summary = buildCompactionSummary({
|
|
164
|
-
summary: args.summary,
|
|
165
|
-
preservedUserMessages: args.preservedUserMessages,
|
|
166
|
-
});
|
|
167
50
|
return {
|
|
168
51
|
compactionMessage: buildCompactionUserMessage({
|
|
169
|
-
summary,
|
|
52
|
+
summary: args.summary,
|
|
170
53
|
lastAssistantMessage,
|
|
171
54
|
}),
|
|
172
55
|
includedLastAssistant: Boolean(lastAssistantMessage),
|
|
173
56
|
};
|
|
174
57
|
}
|
|
175
|
-
export function
|
|
176
|
-
const
|
|
177
|
-
if (
|
|
178
|
-
return summary;
|
|
179
|
-
}
|
|
180
|
-
const preserved = args.preservedUserMessages
|
|
181
|
-
.map((message) => `<user-message id="${escapeXmlAttribute(message.id)}">\n${message.text}\n</user-message>`)
|
|
182
|
-
.join("\n\n");
|
|
183
|
-
return `${summary}\n\n## Preserved User Messages\nUse these original user messages as verbatim continuity anchors. Treat them as preserved user intent selected from the compacted history by history entry id.\n\n<preserved-user-messages>\n${preserved}\n</preserved-user-messages>`;
|
|
184
|
-
}
|
|
185
|
-
export function parseCompactionSummaryResponse(args) {
|
|
186
|
-
const { summary, selectedIds } = extractSelectedUserMessageIds(args.response, {
|
|
187
|
-
requireSelectionBlock: args.userMessageCandidates.length > 0,
|
|
188
|
-
});
|
|
189
|
-
if (!summary) {
|
|
190
|
-
throw new Error("compaction summary response did not include a summary");
|
|
191
|
-
}
|
|
192
|
-
const candidatesById = new Map(args.userMessageCandidates.map((message) => [message.id, message]));
|
|
193
|
-
const seenIds = new Set();
|
|
194
|
-
const selectedCandidates = [];
|
|
195
|
-
for (const id of selectedIds) {
|
|
196
|
-
const candidate = candidatesById.get(id);
|
|
197
|
-
if (!candidate) {
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
if (seenIds.has(id)) {
|
|
201
|
-
throw new Error(`compaction summary selected duplicate preserved user message id '${id}'`);
|
|
202
|
-
}
|
|
203
|
-
seenIds.add(id);
|
|
204
|
-
selectedCandidates.push(candidate);
|
|
205
|
-
}
|
|
206
|
-
return {
|
|
207
|
-
summary,
|
|
208
|
-
preservedUserMessages: fitPreservedUserMessages(selectedCandidates),
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
function extractSelectedUserMessageIds(response, options) {
|
|
212
|
-
const text = response.trim();
|
|
213
|
-
const start = text.indexOf(PRESERVED_USER_MESSAGE_IDS_OPEN_TAG);
|
|
214
|
-
if (start < 0) {
|
|
215
|
-
if (options.requireSelectionBlock) {
|
|
216
|
-
throw new Error("compaction summary response did not include preserved user message ids");
|
|
217
|
-
}
|
|
218
|
-
return { summary: text, selectedIds: [] };
|
|
219
|
-
}
|
|
220
|
-
const contentStart = start + PRESERVED_USER_MESSAGE_IDS_OPEN_TAG.length;
|
|
221
|
-
const end = text.indexOf(PRESERVED_USER_MESSAGE_IDS_CLOSE_TAG, contentStart);
|
|
222
|
-
if (end < 0) {
|
|
223
|
-
throw new Error("compaction summary response did not close preserved user message ids");
|
|
224
|
-
}
|
|
225
|
-
if (text.indexOf(PRESERVED_USER_MESSAGE_IDS_OPEN_TAG, contentStart) >= 0) {
|
|
226
|
-
throw new Error("compaction summary response included multiple preserved user message id blocks");
|
|
227
|
-
}
|
|
228
|
-
const before = text.slice(0, start).trimEnd();
|
|
229
|
-
const after = text.slice(end + PRESERVED_USER_MESSAGE_IDS_CLOSE_TAG.length).trimStart();
|
|
230
|
-
const summary = [before, after].filter(Boolean).join("\n\n").trim();
|
|
231
|
-
let parsed;
|
|
232
|
-
try {
|
|
233
|
-
parsed = JSON.parse(text.slice(contentStart, end).trim());
|
|
234
|
-
}
|
|
235
|
-
catch (error) {
|
|
236
|
-
throw new Error(`invalid preserved user message id selection: ${error.message}`);
|
|
237
|
-
}
|
|
238
|
-
if (!Array.isArray(parsed) || parsed.some((id) => typeof id !== "string")) {
|
|
239
|
-
throw new Error("invalid preserved user message id selection: expected a JSON string array");
|
|
240
|
-
}
|
|
241
|
-
return { summary, selectedIds: parsed };
|
|
242
|
-
}
|
|
243
|
-
function fitPreservedUserMessages(candidates) {
|
|
244
|
-
const tokenCounts = candidates.map((candidate) => estimateTextTokens(candidate.text));
|
|
245
|
-
const totalTokens = tokenCounts.reduce((total, tokens) => total + tokens, 0);
|
|
246
|
-
if (totalTokens <= PRESERVED_USER_MESSAGE_MAX_TOKENS) {
|
|
247
|
-
return candidates.map((candidate) => ({ id: candidate.id, text: candidate.text }));
|
|
248
|
-
}
|
|
249
|
-
const targets = tokenCounts.map((tokens) => Math.max(1, Math.floor((tokens / totalTokens) * PRESERVED_USER_MESSAGE_MAX_TOKENS)));
|
|
250
|
-
let targetTotal = targets.reduce((total, tokens) => total + tokens, 0);
|
|
251
|
-
while (targetTotal > PRESERVED_USER_MESSAGE_MAX_TOKENS) {
|
|
252
|
-
let largestIndex = 0;
|
|
253
|
-
for (let index = 1; index < targets.length; index += 1) {
|
|
254
|
-
if (targets[index] > targets[largestIndex]) {
|
|
255
|
-
largestIndex = index;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
if (targets[largestIndex] <= 1) {
|
|
259
|
-
break;
|
|
260
|
-
}
|
|
261
|
-
targets[largestIndex] = targets[largestIndex] - 1;
|
|
262
|
-
targetTotal -= 1;
|
|
263
|
-
}
|
|
264
|
-
return candidates.map((candidate, index) => {
|
|
265
|
-
const maxTokens = targets[index];
|
|
266
|
-
return {
|
|
267
|
-
id: candidate.id,
|
|
268
|
-
text: truncateForTokens(candidate.text, { maxTokens, strategy: "middle" }).content,
|
|
269
|
-
};
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
function buildHistoryEntryIdMap(entries) {
|
|
273
|
-
return new Map(entries.map((entry) => [entry.message, entry.id]));
|
|
274
|
-
}
|
|
275
|
-
function isAutoCompactionArchiveEntry(entry) {
|
|
276
|
-
const message = entry.message;
|
|
277
|
-
return !(message.role === "assistant" &&
|
|
278
|
-
(message.stopReason === "error" || message.stopReason === "aborted"));
|
|
279
|
-
}
|
|
280
|
-
function collectUserMessageCandidates(entries, previousMessages) {
|
|
281
|
-
const candidates = new Map();
|
|
282
|
-
for (const message of previousMessages) {
|
|
283
|
-
candidates.set(message.id, {
|
|
284
|
-
id: message.id,
|
|
285
|
-
text: message.text,
|
|
286
|
-
source: "previous-preserved",
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
for (const entry of entries) {
|
|
290
|
-
const text = extractPreservableUserText(entry.message);
|
|
291
|
-
if (!text) {
|
|
292
|
-
continue;
|
|
293
|
-
}
|
|
294
|
-
candidates.set(entry.id, { id: entry.id, text, source: "conversation" });
|
|
295
|
-
}
|
|
296
|
-
return [...candidates.values()];
|
|
297
|
-
}
|
|
298
|
-
function formatUserMessageCandidates(candidates) {
|
|
299
|
-
const records = candidates.map((message) => {
|
|
300
|
-
if (message.source === "conversation") {
|
|
301
|
-
return { id: message.id, source: message.source };
|
|
302
|
-
}
|
|
303
|
-
return { id: message.id, source: message.source, text: message.text };
|
|
304
|
-
});
|
|
305
|
-
return JSON.stringify(records, null, 2).replaceAll("<", "\\u003c");
|
|
306
|
-
}
|
|
307
|
-
function extractPreservableUserText(message) {
|
|
308
|
-
if (message.role !== "user") {
|
|
309
|
-
return undefined;
|
|
310
|
-
}
|
|
311
|
-
if (getSummaryCompactionMetadataFromMessage(message) ||
|
|
312
|
-
isCompactionContinuation(message) ||
|
|
313
|
-
hasToolRecoveryMetadata(message)) {
|
|
58
|
+
export function prepareAutoCompaction(entries, settings) {
|
|
59
|
+
const preparation = prepareSessionCompaction(entries);
|
|
60
|
+
if (!preparation) {
|
|
314
61
|
return undefined;
|
|
315
62
|
}
|
|
316
|
-
const
|
|
317
|
-
return text.trim() ? text : undefined;
|
|
318
|
-
}
|
|
319
|
-
function extractUserText(message) {
|
|
320
|
-
if (typeof message.content === "string") {
|
|
321
|
-
return stripTauUserMetadata(message.content);
|
|
322
|
-
}
|
|
323
|
-
const parts = [];
|
|
324
|
-
for (const block of message.content) {
|
|
325
|
-
if (typeof block === "string") {
|
|
326
|
-
parts.push(block);
|
|
327
|
-
}
|
|
328
|
-
else if (block.type === "text") {
|
|
329
|
-
parts.push(block.text ?? "");
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return stripTauUserMetadata(parts.join("\n"));
|
|
333
|
-
}
|
|
334
|
-
function escapeXmlAttribute(value) {
|
|
335
|
-
return value
|
|
336
|
-
.replaceAll("&", "&")
|
|
337
|
-
.replaceAll('"', """)
|
|
338
|
-
.replaceAll("<", "<")
|
|
339
|
-
.replaceAll(">", ">");
|
|
340
|
-
}
|
|
341
|
-
function estimateTextTokens(text) {
|
|
342
|
-
return Math.max(1, bytesToTokens(Buffer.byteLength(text, "utf8")));
|
|
343
|
-
}
|
|
344
|
-
function boundRetainedEntry(entry) {
|
|
345
|
-
const message = structuredClone(entry.message);
|
|
346
|
-
if (message.role === "user" && hasToolRecoveryMetadata(message)) {
|
|
347
|
-
if (typeof message.content === "string") {
|
|
348
|
-
message.content = truncateToolRecoveryResults(message.content, RETAINED_TOOL_RESULT_MAX_TOKENS);
|
|
349
|
-
}
|
|
350
|
-
else {
|
|
351
|
-
for (const block of message.content) {
|
|
352
|
-
if (block.type === "text") {
|
|
353
|
-
block.text = truncateToolRecoveryResults(block.text, RETAINED_TOOL_RESULT_MAX_TOKENS);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return { id: entry.id, message };
|
|
358
|
-
}
|
|
359
|
-
if (message.role !== "toolResult") {
|
|
360
|
-
return { id: entry.id, message };
|
|
361
|
-
}
|
|
362
|
-
const toolResult = message;
|
|
363
|
-
const text = toolResult.content
|
|
364
|
-
.filter((content) => content.type === "text")
|
|
365
|
-
.map((content) => content.text)
|
|
366
|
-
.join("\n");
|
|
367
|
-
const truncated = truncateForTokens(text, {
|
|
368
|
-
maxTokens: RETAINED_TOOL_RESULT_MAX_TOKENS,
|
|
369
|
-
strategy: "middle",
|
|
370
|
-
});
|
|
371
|
-
if (!truncated.truncated) {
|
|
372
|
-
return { id: entry.id, message };
|
|
373
|
-
}
|
|
374
|
-
const content = [];
|
|
375
|
-
let replacedText = false;
|
|
376
|
-
for (const block of toolResult.content) {
|
|
377
|
-
if (block.type !== "text") {
|
|
378
|
-
content.push(block);
|
|
379
|
-
continue;
|
|
380
|
-
}
|
|
381
|
-
if (!replacedText) {
|
|
382
|
-
content.push({ ...block, text: truncated.content });
|
|
383
|
-
replacedText = true;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return {
|
|
387
|
-
id: entry.id,
|
|
388
|
-
message: { ...toolResult, content },
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
export function prepareAutoCompaction(entries, settings) {
|
|
392
|
-
const latestCompaction = findLatestCompactionEntry(entries);
|
|
63
|
+
const latestCompactionIndex = findLatestCompactionIndex(entries);
|
|
393
64
|
const cut = selectAutoCompactionCut(entries, {
|
|
394
|
-
startIndex:
|
|
65
|
+
startIndex: latestCompactionIndex + 1,
|
|
395
66
|
keepRecentTokens: settings.keepRecentTokens,
|
|
396
67
|
});
|
|
397
68
|
if (!cut) {
|
|
398
69
|
return undefined;
|
|
399
70
|
}
|
|
400
|
-
const entriesToSummarize = entries
|
|
401
|
-
.slice(latestCompaction.index + 1, cut.startIndex)
|
|
402
|
-
.filter((entry) => !isCompactionContinuation(entry.message));
|
|
403
|
-
const messagesToSummarize = entriesToSummarize.map((entry) => entry.message);
|
|
404
|
-
const historyEntryIds = buildHistoryEntryIdMap(entriesToSummarize.filter(isAutoCompactionArchiveEntry));
|
|
405
|
-
const formattedConversation = formatHistoryForCompaction(messagesToSummarize, {
|
|
406
|
-
historyEntryIds,
|
|
407
|
-
});
|
|
408
|
-
if (!formattedConversation) {
|
|
409
|
-
return undefined;
|
|
410
|
-
}
|
|
411
|
-
const formattedHistory = formatHistoryForCompaction(messagesToSummarize, {
|
|
412
|
-
systemPrompt: settings.systemPrompt,
|
|
413
|
-
historyEntryIds,
|
|
414
|
-
});
|
|
415
|
-
const retainedEntries = entries
|
|
416
|
-
.slice(cut.startIndex)
|
|
417
|
-
.filter((entry) => !isCompactionContinuation(entry.message))
|
|
418
|
-
.map(boundRetainedEntry);
|
|
419
|
-
if (retainedEntries.length === 0) {
|
|
420
|
-
return undefined;
|
|
421
|
-
}
|
|
422
71
|
return {
|
|
423
|
-
|
|
424
|
-
retainedEntries
|
|
72
|
+
...preparation,
|
|
73
|
+
retainedEntries: entries
|
|
74
|
+
.slice(cut.startIndex)
|
|
75
|
+
.filter((entry) => !isCompactionContinuation(entry.message))
|
|
76
|
+
.map((entry) => structuredClone(entry)),
|
|
425
77
|
cutType: cut.cutType,
|
|
426
|
-
formattedHistory,
|
|
427
|
-
userMessageCandidates: collectUserMessageCandidates(entriesToSummarize, latestCompaction.preservedUserMessages),
|
|
428
78
|
};
|
|
429
79
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
Keep the summary independently useful. State continuity-critical goals, constraints, decisions, current state, blockers, and next steps directly. When exact or bulky details would be wasteful to reproduce, you may mention the relevant id as an auto-compaction archive entry id so the continuing assistant knows to use the supplied files, not the separate history tool. This is useful for long tool output, diagnostic logs, exact errors, payloads, and large code excerpts. Use such references sparingly and only for ids shown in the conversation.
|
|
433
|
-
|
|
434
|
-
Good pattern: "The key failure is a missing RuntimeConfig field; the complete compiler output is in auto-compaction archive entry 'ARCHIVE_ENTRY_ID'."
|
|
435
|
-
Bad pattern: "See archive entry 'ARCHIVE_ENTRY_ID' for what happened."`;
|
|
436
|
-
export function buildAutoCompactionPrompt(preparation) {
|
|
437
|
-
const retainedContextGuidance = preparation.cutType === "split-turn"
|
|
438
|
-
? `The retained context will begin in the middle of the latest assistant/tool turn. Add a "## Current Turn Handoff" section that clearly captures:
|
|
439
|
-
- the original user request for this turn
|
|
440
|
-
- work completed before the retained suffix
|
|
441
|
-
- tool state and findings at the cut boundary
|
|
442
|
-
- what the first retained message is continuing and what remains unresolved
|
|
443
|
-
|
|
444
|
-
Place the section wherever it makes the handoff clearest. Preserve earlier session context elsewhere in the summary without duplicating the retained suffix.`
|
|
445
|
-
: "The retained context will include recent messages. Ensure the summary complements that retained context without duplicating unnecessary detail.";
|
|
446
|
-
const boundedRetainedContextGuidance = "Individual textual tool results and tool-recovery payloads in the retained context may be middle-truncated above the retention limit. Do not describe the retained context as exact or verbatim. When the pre-compaction archive is available, the continuing assistant can recover omitted output through a targeted lookup.";
|
|
80
|
+
export function buildAutoCompactionPrompt() {
|
|
447
81
|
return buildSessionCompactionPrompt({
|
|
448
|
-
|
|
449
|
-
guidance: `${retainedContextGuidance}\n\n${boundedRetainedContextGuidance}\n\n${AUTO_COMPACTION_ARCHIVE_REFERENCE_GUIDANCE}`,
|
|
82
|
+
guidance: "After this compaction summary, some recent complete messages may remain, or there may be no retained messages. Do not rely on a particular retention boundary. After compaction, you will have access to a transcript archive of the conversation before this compaction: a readable .txt transcript, a structured .json snapshot, and an archive guide. The text transcript may truncate large tool results; the JSON snapshot retains full archived results but excludes assistant thinking. You can refer to this transcript archive for exact wording or bulky evidence instead of copying it into the summary. Include targeted instructions to revisit a relevant user message or other evidence when useful, explaining what to look for and why it matters. Use distinctive details such as the topic of a user request, a file path, a tool name, or an error. The continuation supplies the actual paths, so do not invent paths or entry IDs. Keep the essential context in the summary; the transcript archive is an additional way to recover details, not a substitute for a useful summary. This transcript archive is separate from the history tool's collection.",
|
|
450
83
|
});
|
|
451
84
|
}
|
|
85
|
+
export const COMPACTION_CONTINUATION_GUIDANCE = `Your earlier conversation was compacted to keep this same session within the context limit, not to start a new task.
|
|
86
|
+
The compaction summary supplies continuity. Any retained recent messages supply additional detail and may overlap with it. Compaction does not mean that work completed or that the user request changed.
|
|
87
|
+
Resume from the compaction summary and any retained messages without repeating completed work. Recover missing evidence when it matters rather than guessing or asking the user to repeat information.`;
|
|
452
88
|
export function buildAutoCompactionContinuationMessage(args) {
|
|
453
|
-
const lines = [
|
|
454
|
-
"The conversation context before this point has been compacted.",
|
|
455
|
-
"Earlier context is summarized in the compaction message above. Recent messages are retained after that summary, but large textual tool results and tool-recovery payloads may be middle-truncated.",
|
|
456
|
-
"Continue from the summary and retained context without asking the user to repeat information.",
|
|
457
|
-
];
|
|
89
|
+
const lines = [COMPACTION_CONTINUATION_GUIDANCE];
|
|
458
90
|
if (args.cutType === "split-turn") {
|
|
459
|
-
lines.push("The retained
|
|
91
|
+
lines.push("The retained suffix may begin partway through a user turn, or be empty. Use the compaction summary to understand earlier requests, prior tool work, and unfinished actions that are no longer visible.");
|
|
460
92
|
}
|
|
461
93
|
if (args.archive) {
|
|
462
|
-
lines.push("The summary and retained context should normally be sufficient.
|
|
94
|
+
lines.push("The summary and retained context should normally be sufficient. The transcript archive from before this compaction is also available:", `- archive guide: ${args.archive.documentationPath}`, `- transcript archive (.txt): ${args.archive.textPath}`, `- transcript archive (.json): ${args.archive.jsonPath}`, "The archive guide is included below and remains available at the path above.", "For details removed from this session by automatic compaction, use this transcript archive rather than the separate history tool, whose collection may be stale, remotely replicated, truncated, or unavailable.", "The guide describes the archive format and adaptable, bounded lookup examples, including how to inspect earlier numbered pairs when needed.", "<transcript-archive-guide>", AUTO_COMPACTION_ARCHIVE_DOCUMENTATION, "</transcript-archive-guide>");
|
|
463
95
|
}
|
|
464
96
|
const hiddenSystemMessages = [...(args.systemMessages ?? []), lines.join("\n")];
|
|
465
97
|
return {
|
|
@@ -481,109 +113,50 @@ export function selectAutoCompactionCut(entries, args) {
|
|
|
481
113
|
if (entries.length === 0 || args.startIndex >= entries.length) {
|
|
482
114
|
return undefined;
|
|
483
115
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const latestTurnTokens = estimateEntriesTokens(entries.slice(latestTurnStart));
|
|
490
|
-
if (latestTurnTokens <= args.keepRecentTokens) {
|
|
491
|
-
if (turnStarts.length === 0) {
|
|
492
|
-
return undefined;
|
|
116
|
+
let retainedTokens = 0;
|
|
117
|
+
let startIndex = entries.length;
|
|
118
|
+
for (let index = entries.length - 1; index >= args.startIndex; index -= 1) {
|
|
119
|
+
if (isCompactionContinuation(entries[index].message)) {
|
|
120
|
+
continue;
|
|
493
121
|
}
|
|
494
|
-
let
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
122
|
+
let groupStart = index;
|
|
123
|
+
if (entries[index].message.role === "toolResult") {
|
|
124
|
+
while (groupStart > args.startIndex) {
|
|
125
|
+
groupStart -= 1;
|
|
126
|
+
const message = entries[groupStart].message;
|
|
127
|
+
if (message.role === "assistant") {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (message.role !== "toolResult" && !isCompactionContinuation(message)) {
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (entries[groupStart].message.role !== "assistant") {
|
|
501
135
|
break;
|
|
502
136
|
}
|
|
503
|
-
firstKeptTurn = turnStart;
|
|
504
|
-
totalTokens += turnTokens;
|
|
505
137
|
}
|
|
506
|
-
|
|
507
|
-
|
|
138
|
+
const groupTokens = estimateEntriesTokens(entries.slice(groupStart, index + 1));
|
|
139
|
+
if (retainedTokens + groupTokens > args.keepRecentTokens) {
|
|
140
|
+
break;
|
|
508
141
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
turnStart: latestTurnStart,
|
|
513
|
-
keepRecentTokens: args.keepRecentTokens,
|
|
514
|
-
});
|
|
515
|
-
if (splitStart === undefined) {
|
|
516
|
-
return latestTurnStart > args.startIndex
|
|
517
|
-
? { startIndex: latestTurnStart, cutType: "turn-boundary" }
|
|
518
|
-
: undefined;
|
|
142
|
+
retainedTokens += groupTokens;
|
|
143
|
+
startIndex = groupStart;
|
|
144
|
+
index = groupStart;
|
|
519
145
|
}
|
|
520
|
-
if (
|
|
146
|
+
if (startIndex <= args.startIndex) {
|
|
521
147
|
return undefined;
|
|
522
148
|
}
|
|
523
|
-
|
|
149
|
+
const message = entries[startIndex]?.message;
|
|
150
|
+
const cutType = message?.role === "user" && !hasToolRecoveryMetadata(message) ? "turn-boundary" : "split-turn";
|
|
151
|
+
return { startIndex, cutType };
|
|
524
152
|
}
|
|
525
|
-
function
|
|
153
|
+
function findLatestCompactionIndex(entries) {
|
|
526
154
|
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
527
|
-
|
|
528
|
-
if (metadata) {
|
|
529
|
-
const preservedUserMessages = metadata.preservedUserMessages.map((message) => ({
|
|
530
|
-
id: message.id,
|
|
531
|
-
text: message.text,
|
|
532
|
-
}));
|
|
533
|
-
return {
|
|
534
|
-
index,
|
|
535
|
-
summary: metadata.summary,
|
|
536
|
-
preservedUserMessages,
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
return { index: -1, preservedUserMessages: [] };
|
|
541
|
-
}
|
|
542
|
-
function collectTurnStarts(entries, startIndex) {
|
|
543
|
-
const starts = [];
|
|
544
|
-
for (let index = Math.max(0, startIndex); index < entries.length; index += 1) {
|
|
545
|
-
const message = entries[index].message;
|
|
546
|
-
if (message.role !== "user") {
|
|
547
|
-
continue;
|
|
548
|
-
}
|
|
549
|
-
if (getSummaryCompactionMetadataFromMessage(message) ||
|
|
550
|
-
isCompactionContinuation(message) ||
|
|
551
|
-
hasToolRecoveryMetadata(message)) {
|
|
552
|
-
continue;
|
|
553
|
-
}
|
|
554
|
-
starts.push(index);
|
|
555
|
-
}
|
|
556
|
-
return starts;
|
|
557
|
-
}
|
|
558
|
-
function findOngoingTurnStart(entries, startIndex) {
|
|
559
|
-
for (let index = Math.max(0, startIndex); index < entries.length; index += 1) {
|
|
560
|
-
if (!isCompactionContinuation(entries[index].message)) {
|
|
155
|
+
if (getSummaryCompactionMetadataFromMessage(entries[index].message)) {
|
|
561
156
|
return index;
|
|
562
157
|
}
|
|
563
158
|
}
|
|
564
|
-
return
|
|
565
|
-
}
|
|
566
|
-
function selectLatestTurnSplitStart(entries, args) {
|
|
567
|
-
let retainedTokens = 0;
|
|
568
|
-
let latestAssistantBoundary;
|
|
569
|
-
let crossedBudget = false;
|
|
570
|
-
for (let index = entries.length - 1; index >= args.turnStart; index -= 1) {
|
|
571
|
-
const entry = entries[index];
|
|
572
|
-
if (isCompactionContinuation(entry.message)) {
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
retainedTokens += estimateMessageTokens(entry.message);
|
|
576
|
-
if (entry.message.role === "assistant") {
|
|
577
|
-
latestAssistantBoundary = index;
|
|
578
|
-
}
|
|
579
|
-
if (retainedTokens > args.keepRecentTokens) {
|
|
580
|
-
crossedBudget = true;
|
|
581
|
-
}
|
|
582
|
-
if (crossedBudget && latestAssistantBoundary !== undefined) {
|
|
583
|
-
return latestAssistantBoundary;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
return latestAssistantBoundary;
|
|
159
|
+
return -1;
|
|
587
160
|
}
|
|
588
161
|
function estimateEntriesTokens(entries) {
|
|
589
162
|
return entries.reduce((total, entry) => isCompactionContinuation(entry.message)
|