@markusylisiurunen/tau 0.3.32 → 0.3.34
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/README.md +15 -20
- package/dist/core/agent/agent_runtime.js +1551 -0
- package/dist/core/agent/agent_runtime.js.map +1 -0
- package/dist/core/agent/events.js +2 -0
- package/dist/core/agent/events.js.map +1 -0
- package/dist/core/commands/registry.js +0 -42
- package/dist/core/commands/registry.js.map +1 -1
- package/dist/core/config/content_loader.js +7 -3
- package/dist/core/config/content_loader.js.map +1 -1
- package/dist/core/index.js +3 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/models/catalog.js +7 -1
- package/dist/core/models/catalog.js.map +1 -1
- package/dist/core/models/tau_model_overrides.js +10 -0
- package/dist/core/models/tau_model_overrides.js.map +1 -0
- package/dist/core/modes/index.js.map +1 -1
- package/dist/core/personas.js +4 -2
- package/dist/core/personas.js.map +1 -1
- package/dist/core/runtime/agent_model.js +50 -0
- package/dist/core/runtime/agent_model.js.map +1 -0
- package/dist/core/runtime/chat_runtime.js +175 -63
- package/dist/core/runtime/chat_runtime.js.map +1 -1
- package/dist/core/runtime/model_executor.js +2 -0
- package/dist/core/runtime/model_executor.js.map +1 -0
- package/dist/core/runtime/model_sampler.js +21 -0
- package/dist/core/runtime/model_sampler.js.map +1 -0
- package/dist/core/session/auto_compaction_archive.js +239 -0
- package/dist/core/session/auto_compaction_archive.js.map +1 -0
- package/dist/core/session/compaction.js +97 -29
- package/dist/core/session/compaction.js.map +1 -1
- package/dist/core/session/direct_bash.js.map +1 -1
- package/dist/core/session/message_accumulator.js +3 -5
- package/dist/core/session/message_accumulator.js.map +1 -1
- package/dist/core/session/runner.js +274 -102
- package/dist/core/session/runner.js.map +1 -1
- package/dist/core/subagents/agent_supervisor.js +378 -0
- package/dist/core/subagents/agent_supervisor.js.map +1 -0
- package/dist/core/subagents/format.js +101 -0
- package/dist/core/subagents/format.js.map +1 -0
- package/dist/core/subagents/registry.js +3 -1
- package/dist/core/subagents/registry.js.map +1 -1
- package/dist/core/subagents/types.js +1 -0
- package/dist/core/subagents/types.js.map +1 -1
- package/dist/core/tools/activity.js +2 -0
- package/dist/core/tools/activity.js.map +1 -0
- package/dist/core/tools/bash.js +64 -67
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/catalog.js +49 -25
- package/dist/core/tools/catalog.js.map +1 -1
- package/dist/core/tools/code_mode.js +65 -58
- package/dist/core/tools/code_mode.js.map +1 -1
- package/dist/core/tools/edit.js +11 -12
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/interrupt_agent.js +119 -0
- package/dist/core/tools/interrupt_agent.js.map +1 -0
- package/dist/core/tools/list_agents.js +64 -0
- package/dist/core/tools/list_agents.js.map +1 -0
- package/dist/core/tools/nook.js +3 -2
- package/dist/core/tools/nook.js.map +1 -1
- package/dist/core/tools/registry.js +27 -13
- package/dist/core/tools/registry.js.map +1 -1
- package/dist/core/tools/send_input_to_agent.js +77 -93
- package/dist/core/tools/send_input_to_agent.js.map +1 -1
- package/dist/core/tools/spawn_agent.js +94 -114
- package/dist/core/tools/spawn_agent.js.map +1 -1
- package/dist/core/tools/tool_names.js +4 -2
- package/dist/core/tools/tool_names.js.map +1 -1
- package/dist/core/tools/view_image.js +11 -16
- package/dist/core/tools/view_image.js.map +1 -1
- package/dist/core/tools/wait_for_agents.js +76 -137
- package/dist/core/tools/wait_for_agents.js.map +1 -1
- package/dist/core/tools/web.js +3 -3
- package/dist/core/tools/web.js.map +1 -1
- package/dist/core/tools/write.js +10 -11
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/usage/logs.js.map +1 -1
- package/dist/core/utils/compact.js +19 -10
- package/dist/core/utils/compact.js.map +1 -1
- package/dist/core/utils/subagent_utils.js.map +1 -1
- package/dist/core/version.js +1 -1
- package/dist/diff_tool/app/dist/assets/actionscript-3-Cs6JJXT5.js +1 -0
- package/dist/diff_tool/app/dist/assets/ahk-CA9gdOdF.js +1 -0
- package/dist/diff_tool/app/dist/assets/ahk2-_6rzW9BS.js +1 -0
- package/dist/diff_tool/app/dist/assets/{angular-html-DbgxQryr.js → angular-html-vSIwre92.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{angular-ts-Dzjq8SvI.js → angular-ts-B9yWa-IT.js} +1 -1
- package/dist/diff_tool/app/dist/assets/apex-KFGFyKwG.js +1 -0
- package/dist/diff_tool/app/dist/assets/{apl-6AmEMJr-.js → apl-CBg9ewu1.js} +1 -1
- package/dist/diff_tool/app/dist/assets/asciidoc-SCjQUq34.js +1 -0
- package/dist/diff_tool/app/dist/assets/{astro-BM8EbfIg.js → astro-BVjxSYjj.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{bat-Bo4NYOV-.js → bat-qdxAdBWQ.js} +1 -1
- package/dist/diff_tool/app/dist/assets/bird2-CYIUgYqB.js +1 -0
- package/dist/diff_tool/app/dist/assets/{blade-DiKMnN3e.js → blade-jvqV5kiv.js} +1 -1
- package/dist/diff_tool/app/dist/assets/bsl-_VjlB9mv.js +1 -0
- package/dist/diff_tool/app/dist/assets/{c-DMT5X-u9.js → c-DDAfW08c.js} +1 -1
- package/dist/diff_tool/app/dist/assets/c3-D0apG41V.js +1 -0
- package/dist/diff_tool/app/dist/assets/catppuccin-frappe-C9Q5zVZY.js +1 -0
- package/dist/diff_tool/app/dist/assets/catppuccin-latte-CtsyrtPq.js +1 -0
- package/dist/diff_tool/app/dist/assets/catppuccin-macchiato-R8nAf1vR.js +1 -0
- package/dist/diff_tool/app/dist/assets/catppuccin-mocha-DjuaAJKi.js +1 -0
- package/dist/diff_tool/app/dist/assets/chapel-Qflwfgbt.js +1 -0
- package/dist/diff_tool/app/dist/assets/clarity-CtfBBspg.js +1 -0
- package/dist/diff_tool/app/dist/assets/{cobol-CACNMc1O.js → cobol-4iJI1LUg.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{coffee-D_WUFE0g.js → coffee-C9LbGGO3.js} +1 -1
- package/dist/diff_tool/app/dist/assets/coq-DuBRPxYg.js +1 -0
- package/dist/diff_tool/app/dist/assets/cpp-B-x6veTx.js +1 -0
- package/dist/diff_tool/app/dist/assets/{crystal-wh93mtUe.js → crystal-S06EUmKn.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{css-CCfuUqEr.js → css-DA4RYriG.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{edge-DP-spcJf.js → edge-7dx6BjGp.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{elixir-BXBkaEtJ.js → elixir-DPywG97a.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{elm-BXr8OwKP.js → elm-Dgo_WnqC.js} +1 -1
- package/dist/diff_tool/app/dist/assets/emacs-lisp-c_oH4hRZ.js +1 -0
- package/dist/diff_tool/app/dist/assets/{erb-Cu5Zacs_.js → erb-CVW4PjFl.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{gdresource-C0sCabJj.js → gdresource-xMC7jr7x.js} +1 -1
- package/dist/diff_tool/app/dist/assets/gdscript-DYvRD3hg.js +1 -0
- package/dist/diff_tool/app/dist/assets/{git-rebase-DO8LWld4.js → git-rebase-CtU0gmBJ.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{glimmer-js-Bh-OAIDW.js → glimmer-js-twAYiPP2.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{glimmer-ts-DI9lHU4q.js → glimmer-ts-BfNoXayN.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{glsl--zoY4RCO.js → glsl-D_XrtFF7.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{graphql-C8h2T_SC.js → graphql-B_GeapzM.js} +1 -1
- package/dist/diff_tool/app/dist/assets/hack-BCaCVoSX.js +1 -0
- package/dist/diff_tool/app/dist/assets/{haml-C2BBBsDW.js → haml-z9Mz7I1O.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{handlebars-cZMztphK.js → handlebars-D0FVYagc.js} +1 -1
- package/dist/diff_tool/app/dist/assets/haxe-C8oCnwJJ.js +1 -0
- package/dist/diff_tool/app/dist/assets/{html-BtccomkJ.js → html-BOM4tb7u.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{html-derivative-qjeUe52-.js → html-derivative-CsSlhJgr.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{http-Dv8OQO33.js → http-Cjy9oaQn.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{hurl-B6Fnr2ae.js → hurl-CjLQ7ql5.js} +1 -1
- package/dist/diff_tool/app/dist/assets/hxml-Dcm88srW.js +1 -0
- package/dist/diff_tool/app/dist/assets/index-QO81yN6b.js +1550 -0
- package/dist/diff_tool/app/dist/assets/{java-BuadWMcp.js → java-cn8DiFD8.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{javascript-BIKxmHeL.js → javascript-CEnHZaZM.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{jinja-Cm_guvgu.js → jinja-DIp6kVk7.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{jison-Sst29gJb.js → jison-Dx116ito.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{json-Bg6l2vym.js → json-C6B9h0n5.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{jsx-BiREAxkr.js → jsx-CDEGT2B2.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{julia-DAhrWFzr.js → julia-CsIJA3Km.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{just-xBwbf5aT.js → just-DZRYvkQw.js} +1 -1
- package/dist/diff_tool/app/dist/assets/kanagawa-dragon-Bozd7klA.js +1 -0
- package/dist/diff_tool/app/dist/assets/kanagawa-lotus-BmuOG9ZW.js +1 -0
- package/dist/diff_tool/app/dist/assets/kanagawa-wave-BML5mF2J.js +1 -0
- package/dist/diff_tool/app/dist/assets/latex-CeR-RQOI.js +1 -0
- package/dist/diff_tool/app/dist/assets/{liquid-BTsCzVvF.js → liquid-Dhf8N4mn.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{llvm-Cm23YOpf.js → llvm-DqHOMS-s.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{lua-BJt9x0JP.js → lua-zVTVaJzn.js} +1 -1
- package/dist/diff_tool/app/dist/assets/luau-C2pBCSgt.js +1 -0
- package/dist/diff_tool/app/dist/assets/{marko-CWdJkbvC.js → marko-BGPq5r3o.js} +1 -1
- package/dist/diff_tool/app/dist/assets/mdc-D8K78bym.js +1 -0
- package/dist/diff_tool/app/dist/assets/mermaid-BxpfTIzt.js +1 -0
- package/dist/diff_tool/app/dist/assets/mojo-CFuIV2fl.js +1 -0
- package/dist/diff_tool/app/dist/assets/monokai-B_bV9PQ9.js +1 -0
- package/dist/diff_tool/app/dist/assets/moonbit-DgjMoLWr.js +1 -0
- package/dist/diff_tool/app/dist/assets/move-BYnGhZoM.js +1 -0
- package/dist/diff_tool/app/dist/assets/{nginx-BwS0G4IK.js → nginx-Bo-bEa75.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{nim-B2VFbcs9.js → nim-Bfy5M54r.js} +1 -1
- package/dist/diff_tool/app/dist/assets/nsis-CjNLYCLg.js +1 -0
- package/dist/diff_tool/app/dist/assets/nushell-DHYfO66s.js +1 -0
- package/dist/diff_tool/app/dist/assets/org-BKetN7sT.js +1 -0
- package/dist/diff_tool/app/dist/assets/{perl-BTeqR-l8.js → perl-WiwTOQTV.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{php-Crua7nbA.js → php-CM2FzhGV.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{powershell-DshXNtvi.js → powershell-CCSX75yM.js} +1 -1
- package/dist/diff_tool/app/dist/assets/prisma-DMgNhnYS.js +1 -0
- package/dist/diff_tool/app/dist/assets/{pug-CUlgPjMU.js → pug-D2WvUHZ-.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{qml-DI0IjNUw.js → qml-DGPbc6TL.js} +1 -1
- package/dist/diff_tool/app/dist/assets/r-CCFYJ_KM.js +1 -0
- package/dist/diff_tool/app/dist/assets/{razor-DrkKtFm5.js → razor-D1JuQWQz.js} +1 -1
- package/dist/diff_tool/app/dist/assets/rbs-C0MpOrj4.js +1 -0
- package/dist/diff_tool/app/dist/assets/red-DX1BQOs8.js +1 -0
- package/dist/diff_tool/app/dist/assets/{regexp-DRmxJil7.js → regexp-zTiHwMow.js} +1 -1
- package/dist/diff_tool/app/dist/assets/rose-pine-aMsaMD1D.js +1 -0
- package/dist/diff_tool/app/dist/assets/rose-pine-dawn-8PwUyIlP.js +1 -0
- package/dist/diff_tool/app/dist/assets/rose-pine-moon-DO-qXg-I.js +1 -0
- package/dist/diff_tool/app/dist/assets/{rst-DiRke36z.js → rst-CuUAArfH.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{ruby-t7r9jzAg.js → ruby-DznrLCoG.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{sas-CR7Z4kg-.js → sas-D2hJmLva.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{scala-DKOlJaKm.js → scala-BiFt_7mu.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{scss--CnPWaDv.js → scss-Cjb3p_6n.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{shellscript-Bz7H5174.js → shellscript-BtwI-tfX.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{shellsession-mlKnHJfN.js → shellsession-BYirS1xP.js} +1 -1
- package/dist/diff_tool/app/dist/assets/smalltalk-BHpQb5nM.js +1 -0
- package/dist/diff_tool/app/dist/assets/smithy-Dgaz7aur.js +1 -0
- package/dist/diff_tool/app/dist/assets/solarized-dark-UdsmMDCL.js +1 -0
- package/dist/diff_tool/app/dist/assets/solarized-light-C1IUL_tW.js +1 -0
- package/dist/diff_tool/app/dist/assets/solidity-Bj7E1mRn.js +1 -0
- package/dist/diff_tool/app/dist/assets/{soy-CKu9y9G1.js → soy-D4Ndk7-j.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{sql-DcvKi3Jj.js → sql-DbLQ5SJl.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{stata-Yo25QZyV.js → stata-BXoNBosJ.js} +1 -1
- package/dist/diff_tool/app/dist/assets/surrealql-toyTYnAL.js +1 -0
- package/dist/diff_tool/app/dist/assets/{svelte-BIhEVbnP.js → svelte-BEpa7pAW.js} +1 -1
- package/dist/diff_tool/app/dist/assets/swift-CyEgAFGc.js +1 -0
- package/dist/diff_tool/app/dist/assets/system-verilog-Dh5ihWbf.js +1 -0
- package/dist/diff_tool/app/dist/assets/{templ-D6FrV4mZ.js → templ-CZfW_RJI.js} +1 -1
- package/dist/diff_tool/app/dist/assets/tex-COemmIIu.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-B5HubD5i.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-BTK0wyKj.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-BTUlzJFw.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-BURFlYfV.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-BVZjihoZ.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-BWSkzMBn.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-BchIqPOb.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-CeLfRn2P.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-DMjwMSwU.js +1 -0
- package/dist/diff_tool/app/dist/assets/theming-QWGGdlwd.js +1 -0
- package/dist/diff_tool/app/dist/assets/{ts-tags-Kqn1PP6m.js → ts-tags-CMVUY_BA.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{tsx-L3TEJWGL.js → tsx-BTvP6uzd.js} +1 -1
- package/dist/diff_tool/app/dist/assets/twig-DzP5RjJc.js +1 -0
- package/dist/diff_tool/app/dist/assets/{typescript-Dvc5RX4H.js → typescript-CQaGlMoX.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{v-DETTlOr0.js → v-DBj4K9d_.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{vb-Djn5o6TS.js → vb-DOwzaHZ0.js} +1 -1
- package/dist/diff_tool/app/dist/assets/verilog-B2gwz-sJ.js +1 -0
- package/dist/diff_tool/app/dist/assets/{vue-X1uI3I2A.js → vue-DaVWTtvb.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{vue-html-BMpHEoeQ.js → vue-html-BA_OH0Xt.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{vue-vine-DnTGaA4r.js → vue-vine-C_H4XbNR.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{xml-QlPQXP0d.js → xml-1JLzpunp.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{xsl-JpRU16Li.js → xsl-GtZi0Erj.js} +1 -1
- package/dist/diff_tool/app/dist/assets/{yaml-Djukn3_s.js → yaml-LueTtDDo.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/tool_backend_execution_environment.js +1 -7
- package/dist/execution/tool_backend_execution_environment.js.map +1 -1
- package/dist/host/client_tool_broker.js +28 -21
- package/dist/host/client_tool_broker.js.map +1 -1
- package/dist/host/hosted_ephemeral_agent_session.js +109 -167
- package/dist/host/hosted_ephemeral_agent_session.js.map +1 -1
- package/dist/host/local_session_host.js +340 -248
- package/dist/host/local_session_host.js.map +1 -1
- package/dist/host/session_host.js.map +1 -1
- package/dist/host/session_protocol_handler.js +125 -105
- package/dist/host/session_protocol_handler.js.map +1 -1
- package/dist/main.js +10 -2
- package/dist/main.js.map +1 -1
- package/dist/protocol/index.d.ts +1 -1
- package/dist/protocol/session_protocol.d.ts +70 -36
- package/dist/protocol/session_protocol.js +235 -80
- package/dist/protocol/session_protocol.js.map +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/session.js +8 -25
- package/dist/sdk/session.js.map +1 -1
- package/dist/sdk/types.d.ts +4 -9
- package/dist/starter/prompts/approval-review-branch.md +7 -0
- package/dist/starter/prompts/approval-review-current-changes.md +7 -0
- package/dist/starter/prompts/approval-review-last-commit.md +7 -0
- package/dist/starter/skills/approval-review/SKILL.md +219 -0
- package/dist/store/file_session_store.js +13 -9
- package/dist/store/file_session_store.js.map +1 -1
- package/dist/store/session_snapshot_migrations.js +152 -0
- package/dist/store/session_snapshot_migrations.js.map +1 -0
- package/dist/tui/chat_controller/command_hints.js +0 -6
- package/dist/tui/chat_controller/command_hints.js.map +1 -1
- package/dist/tui/chat_view.js +19 -12
- package/dist/tui/chat_view.js.map +1 -1
- package/dist/tui/session_chat_app.js +0 -8
- package/dist/tui/session_chat_app.js.map +1 -1
- package/dist/tui/session_chat_controller.js +122 -178
- package/dist/tui/session_chat_controller.js.map +1 -1
- package/dist/tui/tool_ui_router.js +12 -226
- package/dist/tui/tool_ui_router.js.map +1 -1
- package/dist/tui/ui/bash_execution.js +3 -3
- package/dist/tui/ui/bash_execution.js.map +1 -1
- package/dist/tui/ui/chat_message_model.js +2 -2
- package/dist/tui/ui/chat_message_model.js.map +1 -1
- package/dist/tui/ui/subagent_panel.js +59 -26
- package/dist/tui/ui/subagent_panel.js.map +1 -1
- package/dist/tui/ui/tool_ui_model.js +2 -0
- package/dist/tui/ui/tool_ui_model.js.map +1 -0
- package/dist/tui/ui/tool_ui_registry.js +310 -36
- package/dist/tui/ui/tool_ui_registry.js.map +1 -1
- package/package.json +4 -4
- package/dist/core/events/types.js +0 -2
- package/dist/core/events/types.js.map +0 -1
- package/dist/core/modes/mode_adapter.js +0 -2
- package/dist/core/modes/mode_adapter.js.map +0 -1
- package/dist/core/runtime/conversation_turn_runtime.js +0 -88
- package/dist/core/runtime/conversation_turn_runtime.js.map +0 -1
- package/dist/core/session/core_session.js +0 -86
- package/dist/core/session/core_session.js.map +0 -1
- package/dist/core/session/pruning.js +0 -587
- package/dist/core/session/pruning.js.map +0 -1
- package/dist/core/session/session_engine.js +0 -1246
- package/dist/core/session/session_engine.js.map +0 -1
- package/dist/core/subagents/control_plane.js +0 -339
- package/dist/core/subagents/control_plane.js.map +0 -1
- package/dist/core/subagents/subagent_engine.js +0 -258
- package/dist/core/subagents/subagent_engine.js.map +0 -1
- package/dist/core/tools/terminate_agent.js +0 -162
- package/dist/core/tools/terminate_agent.js.map +0 -1
- package/dist/diff_tool/app/dist/assets/actionscript-3--17pq3dv.js +0 -1
- package/dist/diff_tool/app/dist/assets/apex-VAyPSnFM.js +0 -1
- package/dist/diff_tool/app/dist/assets/asciidoc-DE70LPWp.js +0 -1
- package/dist/diff_tool/app/dist/assets/bird2-C6vDhewU.js +0 -1
- package/dist/diff_tool/app/dist/assets/bsl-BkkzgIyY.js +0 -1
- package/dist/diff_tool/app/dist/assets/c3-BFHwR3_K.js +0 -1
- package/dist/diff_tool/app/dist/assets/catppuccin-frappe-3VR1Za6u.js +0 -1
- package/dist/diff_tool/app/dist/assets/catppuccin-latte-DwIHMF0Q.js +0 -1
- package/dist/diff_tool/app/dist/assets/catppuccin-macchiato-DYnBP6_5.js +0 -1
- package/dist/diff_tool/app/dist/assets/catppuccin-mocha-DYhrFGRu.js +0 -1
- package/dist/diff_tool/app/dist/assets/clarity-SemFz856.js +0 -1
- package/dist/diff_tool/app/dist/assets/coq-BrsZFFmf.js +0 -1
- package/dist/diff_tool/app/dist/assets/cpp-BcU9r9kv.js +0 -1
- package/dist/diff_tool/app/dist/assets/emacs-lisp-B4R74twV.js +0 -1
- package/dist/diff_tool/app/dist/assets/gdscript-Cp2uCuqX.js +0 -1
- package/dist/diff_tool/app/dist/assets/hack-DAsjGmmw.js +0 -1
- package/dist/diff_tool/app/dist/assets/haxe-OTjmBuCE.js +0 -1
- package/dist/diff_tool/app/dist/assets/hxml-B0Qn7Nwc.js +0 -1
- package/dist/diff_tool/app/dist/assets/index-U7G4V3LV.js +0 -1579
- package/dist/diff_tool/app/dist/assets/kanagawa-dragon-CXtmUGW6.js +0 -1
- package/dist/diff_tool/app/dist/assets/kanagawa-lotus-BN08jTvb.js +0 -1
- package/dist/diff_tool/app/dist/assets/kanagawa-wave-CTweb8Dz.js +0 -1
- package/dist/diff_tool/app/dist/assets/latex-Bydg2zYo.js +0 -1
- package/dist/diff_tool/app/dist/assets/luau-FMPmPwt6.js +0 -1
- package/dist/diff_tool/app/dist/assets/mdc-B6ddHTKx.js +0 -1
- package/dist/diff_tool/app/dist/assets/mermaid-Bk4SNUv9.js +0 -1
- package/dist/diff_tool/app/dist/assets/mojo-BgCJLMeH.js +0 -1
- package/dist/diff_tool/app/dist/assets/monokai-CdkpiU2Y.js +0 -1
- package/dist/diff_tool/app/dist/assets/moonbit-CaWjb8XO.js +0 -1
- package/dist/diff_tool/app/dist/assets/move-B1IS1UjX.js +0 -1
- package/dist/diff_tool/app/dist/assets/nushell-DcLAeLz5.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-dark-CpLgRqie.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-dark-soft-kZQmAZld.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-dark-tritanopia-CpjhbsIL.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-dark-vibrant-CpQYzh95.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-light-CoaEpmwp.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-light-soft-lWLdNTOI.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-light-tritanopia-CEbqgOJL.js +0 -1
- package/dist/diff_tool/app/dist/assets/pierre-light-vibrant-D80Fkn33.js +0 -1
- package/dist/diff_tool/app/dist/assets/prisma-BsRQq5mF.js +0 -1
- package/dist/diff_tool/app/dist/assets/r-DRexFFDh.js +0 -1
- package/dist/diff_tool/app/dist/assets/red-CJ3rzSJv.js +0 -1
- package/dist/diff_tool/app/dist/assets/rose-pine-BthvhNj6.js +0 -1
- package/dist/diff_tool/app/dist/assets/rose-pine-dawn-Dg85fqjY.js +0 -1
- package/dist/diff_tool/app/dist/assets/rose-pine-moon-hon4tzzS.js +0 -1
- package/dist/diff_tool/app/dist/assets/smalltalk-B16xEiuN.js +0 -1
- package/dist/diff_tool/app/dist/assets/solarized-dark-DV17i1UV.js +0 -1
- package/dist/diff_tool/app/dist/assets/solarized-light-DSh2HLQt.js +0 -1
- package/dist/diff_tool/app/dist/assets/solidity-CKzVLygQ.js +0 -1
- package/dist/diff_tool/app/dist/assets/surrealql-CUddZ4Qk.js +0 -1
- package/dist/diff_tool/app/dist/assets/swift-DonLKvLd.js +0 -1
- package/dist/diff_tool/app/dist/assets/system-verilog-DJ5XKQeo.js +0 -1
- package/dist/diff_tool/app/dist/assets/tex-BOTYELrL.js +0 -1
- package/dist/diff_tool/app/dist/assets/twig-BpzmhnWz.js +0 -1
- package/dist/diff_tool/app/dist/assets/verilog-CiiDBU1e.js +0 -1
|
@@ -2,9 +2,12 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { isDeepStrictEqual } from "node:util";
|
|
3
3
|
import { resolvePromptTemplateWithBackend } from "../core/config/index.js";
|
|
4
4
|
import { ChatRuntime } from "../core/runtime/chat_runtime.js";
|
|
5
|
+
import { SUBAGENT_ACTIVITY_FACET_KIND } from "../core/subagents/types.js";
|
|
6
|
+
import { appendUsageLogEntry, getUsageCostTotal, getUsageTotals, } from "../core/usage/logs.js";
|
|
5
7
|
import { filterProjectPathAutocompleteEntries, loadProjectPathAutocompleteEntriesWithBackend, } from "../core/utils/project_files.js";
|
|
6
8
|
import { hasAutoCompactionContinuationMetadata, isTauUserMessageHidden, } from "../core/utils/user_metadata.js";
|
|
7
9
|
import { applySessionProtocolDelta, createSessionProtocolDeltaMessage, createSessionProtocolEphemeralMessage, } from "../protocol/session_protocol.js";
|
|
10
|
+
import { LEGACY_SESSION_CONTEXT_EPOCH } from "../store/session_snapshot_migrations.js";
|
|
8
11
|
import { ClientToolBroker } from "./client_tool_broker.js";
|
|
9
12
|
import { createExecutionEnvironmentSubagentRuntimeResolver } from "./execution_runtime.js";
|
|
10
13
|
import { HostedEphemeralAgentSession } from "./hosted_ephemeral_agent_session.js";
|
|
@@ -61,12 +64,20 @@ export class LocalSessionHost {
|
|
|
61
64
|
try {
|
|
62
65
|
const recovered = normalizeRecoveredSnapshot(snapshot);
|
|
63
66
|
hostedSession = await this.createLocalSessionHandle(executionEnvironment, recovered.snapshot, undefined, recovered.changed);
|
|
64
|
-
hostedSession.
|
|
65
|
-
|
|
67
|
+
const agentRecovery = hostedSession.runtime.restoreState({
|
|
68
|
+
agentId: recovered.snapshot.sessionId,
|
|
69
|
+
revision: recovered.snapshot.agentState.revision,
|
|
70
|
+
contextEpoch: recovered.snapshot.agentState.contextEpoch,
|
|
66
71
|
historyEntries: recovered.snapshot.messages.flatMap((entry) => entry.modelVisible && isCoreMessage(entry.message)
|
|
67
72
|
? [{ id: entry.id, message: entry.message }]
|
|
68
73
|
: []),
|
|
74
|
+
...(recovered.snapshot.agentState.usageCheckpoint
|
|
75
|
+
? { usageCheckpoint: { ...recovered.snapshot.agentState.usageCheckpoint } }
|
|
76
|
+
: {}),
|
|
69
77
|
});
|
|
78
|
+
if (recovered.changed || agentRecovery.recoveredToolResults.length > 0) {
|
|
79
|
+
await hostedSession.persistRecoveredAgentState(agentRecovery);
|
|
80
|
+
}
|
|
70
81
|
return hostedSession;
|
|
71
82
|
}
|
|
72
83
|
catch (error) {
|
|
@@ -98,10 +109,11 @@ export class LocalSessionHost {
|
|
|
98
109
|
return this.createLocalSessionHandleFromRuntimeContext(executionEnvironment, runtimeContext, bootstrap, catalog, committedSnapshot, forceNextSnapshotRevision);
|
|
99
110
|
}
|
|
100
111
|
createLocalSessionHandleFromRuntimeContext(executionEnvironment, runtimeContext, bootstrap, catalog, committedSnapshot, forceNextSnapshotRevision = false) {
|
|
112
|
+
let hostedSession;
|
|
101
113
|
const runtime = ChatRuntime.create({
|
|
102
114
|
persona: bootstrap.persona,
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
backend: executionEnvironment.getToolExecutionBackend(),
|
|
116
|
+
clientTools: (sessionId) => this.clientToolBroker.getToolDefinitions(sessionId),
|
|
105
117
|
modelResolver: bootstrap.modelResolver,
|
|
106
118
|
resolveSubagentRuntime: createExecutionEnvironmentSubagentRuntimeResolver({
|
|
107
119
|
executionEnvironment,
|
|
@@ -110,13 +122,16 @@ export class LocalSessionHost {
|
|
|
110
122
|
}),
|
|
111
123
|
promptContext: runtimeContext.promptBootstrap.promptContext,
|
|
112
124
|
environment: this.sessionOptions.environment,
|
|
125
|
+
eventSink: async (event) => await hostedSession.enqueueRuntimeEvent(event),
|
|
126
|
+
subagentEventSink: async (event) => await hostedSession.recordSubagentEvent(event),
|
|
113
127
|
initialPromptComposition: committedSnapshot
|
|
114
128
|
? promptCompositionFromSnapshot(committedSnapshot)
|
|
115
129
|
: undefined,
|
|
116
|
-
config: bootstrap.config,
|
|
130
|
+
config: bootstrap.config ?? {},
|
|
131
|
+
recordUsage: this.sessionOptions.recordUsage,
|
|
117
132
|
deps: this.sessionOptions.deps,
|
|
118
133
|
});
|
|
119
|
-
|
|
134
|
+
hostedSession = new LocalHostedSessionHandle(runtime, runtimeContext.promptBootstrap, catalog, bootstrap, this.sessionOptions.includeAgentContext, executionEnvironment, this.store, committedSnapshot, forceNextSnapshotRevision, this.sessionOptions.recordUsage ?? appendUsageLogEntry, (session) => this.sessions.delete(session));
|
|
120
135
|
this.sessions.add(hostedSession);
|
|
121
136
|
return hostedSession;
|
|
122
137
|
}
|
|
@@ -304,6 +319,7 @@ class LocalHostedSessionHandle {
|
|
|
304
319
|
includeAgentContext;
|
|
305
320
|
executionEnvironment;
|
|
306
321
|
store;
|
|
322
|
+
recordUsage;
|
|
307
323
|
removeFromHost;
|
|
308
324
|
session;
|
|
309
325
|
committedSessionId;
|
|
@@ -324,7 +340,6 @@ class LocalHostedSessionHandle {
|
|
|
324
340
|
ephemeralAgentSessions = new Map();
|
|
325
341
|
pathAutocompleteCache;
|
|
326
342
|
pathAutocompleteLoad;
|
|
327
|
-
unsubscribeSubagentEvent;
|
|
328
343
|
runtimeEventQueue = Promise.resolve();
|
|
329
344
|
snapshotQueue = Promise.resolve();
|
|
330
345
|
snapshotGeneration = 0;
|
|
@@ -337,7 +352,7 @@ class LocalHostedSessionHandle {
|
|
|
337
352
|
costTotal = 0;
|
|
338
353
|
forceNextSnapshotRevision;
|
|
339
354
|
disposed = false;
|
|
340
|
-
constructor(runtime, promptBootstrap, catalog, bootstrap, includeAgentContext, executionEnvironment, store, committedSnapshot, forceNextSnapshotRevision
|
|
355
|
+
constructor(runtime, promptBootstrap, catalog, bootstrap, includeAgentContext, executionEnvironment, store, committedSnapshot, forceNextSnapshotRevision, recordUsage, removeFromHost = () => { }) {
|
|
341
356
|
this.runtime = runtime;
|
|
342
357
|
this.promptBootstrap = promptBootstrap;
|
|
343
358
|
this.catalog = catalog;
|
|
@@ -345,8 +360,9 @@ class LocalHostedSessionHandle {
|
|
|
345
360
|
this.includeAgentContext = includeAgentContext;
|
|
346
361
|
this.executionEnvironment = executionEnvironment;
|
|
347
362
|
this.store = store;
|
|
363
|
+
this.recordUsage = recordUsage;
|
|
348
364
|
this.removeFromHost = removeFromHost;
|
|
349
|
-
this.session = runtime
|
|
365
|
+
this.session = runtime;
|
|
350
366
|
this.committedSessionId = committedSnapshot?.sessionId ?? this.session.sessionId;
|
|
351
367
|
this.committedSnapshot = committedSnapshot
|
|
352
368
|
? cloneSessionProtocolSnapshot(committedSnapshot)
|
|
@@ -356,9 +372,6 @@ class LocalHostedSessionHandle {
|
|
|
356
372
|
: undefined;
|
|
357
373
|
this.forceNextSnapshotRevision = forceNextSnapshotRevision;
|
|
358
374
|
this.restoreProtocolState(committedSnapshot);
|
|
359
|
-
this.unsubscribeSubagentEvent = this.session.onSubagentEvent((event) => {
|
|
360
|
-
void this.enqueueRuntimeEvent(event).catch(() => undefined);
|
|
361
|
-
});
|
|
362
375
|
}
|
|
363
376
|
get isTurnRunning() {
|
|
364
377
|
return this.runtime.isTurnRunning;
|
|
@@ -386,11 +399,9 @@ class LocalHostedSessionHandle {
|
|
|
386
399
|
}
|
|
387
400
|
async record(options) {
|
|
388
401
|
this.assertActive();
|
|
389
|
-
const userHistoryEntryId = this.session.
|
|
390
|
-
const snapshot = await this.commitSnapshot();
|
|
391
|
-
this.emitSnapshotReset("user-message", snapshot);
|
|
402
|
+
const userHistoryEntryId = await this.session.commitUserText(options.text, options.historyEntryId ? { historyEntryId: options.historyEntryId } : undefined);
|
|
392
403
|
return {
|
|
393
|
-
snapshot,
|
|
404
|
+
snapshot: await this.snapshot(),
|
|
394
405
|
userHistoryEntryId,
|
|
395
406
|
};
|
|
396
407
|
}
|
|
@@ -414,14 +425,8 @@ class LocalHostedSessionHandle {
|
|
|
414
425
|
}
|
|
415
426
|
let lastAssistantMessage;
|
|
416
427
|
try {
|
|
417
|
-
const result = await this.runtime.runTurn(
|
|
418
|
-
|
|
419
|
-
if (event.type === "assistant_final") {
|
|
420
|
-
lastAssistantMessage = event.message;
|
|
421
|
-
}
|
|
422
|
-
await this.enqueueRuntimeEvent(event);
|
|
423
|
-
},
|
|
424
|
-
});
|
|
428
|
+
const result = await this.runtime.runTurn();
|
|
429
|
+
lastAssistantMessage = result.finalMessage;
|
|
425
430
|
if (result.aborted && this.draftAssistantMessage) {
|
|
426
431
|
await this.interruptDraftAssistantMessage();
|
|
427
432
|
}
|
|
@@ -469,6 +474,33 @@ class LocalHostedSessionHandle {
|
|
|
469
474
|
this.assertActive();
|
|
470
475
|
return this.runtime.cancelTurnBoundaryStop();
|
|
471
476
|
}
|
|
477
|
+
steer(text) {
|
|
478
|
+
this.assertActive();
|
|
479
|
+
if (!this.activeTurnPromise) {
|
|
480
|
+
throw new Error("cannot steer without an active turn");
|
|
481
|
+
}
|
|
482
|
+
const submission = this.runtime.steer(text);
|
|
483
|
+
return {
|
|
484
|
+
id: submission.id,
|
|
485
|
+
applied: submission.applied.then(async (association) => {
|
|
486
|
+
await this.commitSnapshot();
|
|
487
|
+
return { userHistoryEntryId: association.historyEntryId };
|
|
488
|
+
}),
|
|
489
|
+
result: submission.result.then(async (association) => {
|
|
490
|
+
const turn = turnOutcomeFromResult(association.result, association.result.finalMessage);
|
|
491
|
+
this.turnOutcomes.set(association.historyEntryId, turn);
|
|
492
|
+
await this.emitSnapshotResetIfChanged("assistant-message");
|
|
493
|
+
return {
|
|
494
|
+
userHistoryEntryId: association.historyEntryId,
|
|
495
|
+
turn,
|
|
496
|
+
};
|
|
497
|
+
}),
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
cancelSteering() {
|
|
501
|
+
this.assertActive();
|
|
502
|
+
return this.runtime.cancelSteering();
|
|
503
|
+
}
|
|
472
504
|
async exec(options) {
|
|
473
505
|
return await this.runExec(options.execId, options.signal, async (signal) => {
|
|
474
506
|
const backend = this.executionEnvironment.getToolExecutionBackend();
|
|
@@ -505,26 +537,32 @@ class LocalHostedSessionHandle {
|
|
|
505
537
|
}
|
|
506
538
|
async setReasoning(reasoning) {
|
|
507
539
|
this.assertActive();
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
this.
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
540
|
+
const write = this.runtimeEventQueue
|
|
541
|
+
.catch(() => undefined)
|
|
542
|
+
.then(async () => {
|
|
543
|
+
const fromRevision = this.committedSnapshot?.revision;
|
|
544
|
+
this.runtime.setReasoning(reasoning);
|
|
545
|
+
this.bootstrap.persona.settings.reasoning = reasoning;
|
|
546
|
+
const snapshot = await this.commitSnapshot();
|
|
547
|
+
if (fromRevision === undefined) {
|
|
548
|
+
this.emitSnapshotReset("configuration", snapshot);
|
|
549
|
+
}
|
|
550
|
+
else if (snapshot.revision !== fromRevision) {
|
|
551
|
+
this.emitDelta(createSessionProtocolDeltaMessage({
|
|
552
|
+
sessionId: snapshot.sessionId,
|
|
553
|
+
fromRevision,
|
|
554
|
+
toRevision: snapshot.revision,
|
|
555
|
+
reason: "configuration",
|
|
556
|
+
delta: {
|
|
557
|
+
type: "snapshot.patch",
|
|
558
|
+
changes: [{ type: "settings.set", settings: snapshot.settings }],
|
|
559
|
+
},
|
|
560
|
+
}));
|
|
561
|
+
}
|
|
562
|
+
return { revision: snapshot.revision, settings: snapshot.settings };
|
|
563
|
+
});
|
|
564
|
+
this.runtimeEventQueue = write.then(() => undefined, () => undefined);
|
|
565
|
+
return await write;
|
|
528
566
|
}
|
|
529
567
|
async setPersona(personaId) {
|
|
530
568
|
this.assertActive();
|
|
@@ -665,29 +703,6 @@ class LocalHostedSessionHandle {
|
|
|
665
703
|
};
|
|
666
704
|
});
|
|
667
705
|
}
|
|
668
|
-
async pruneToolResults(options) {
|
|
669
|
-
return await this.runMaintenance(async (signal) => {
|
|
670
|
-
const result = await this.session.pruneToolResults({
|
|
671
|
-
strategy: options.strategy,
|
|
672
|
-
fraction: options.fraction,
|
|
673
|
-
...(options.guidance !== undefined ? { guidance: options.guidance } : {}),
|
|
674
|
-
signal,
|
|
675
|
-
});
|
|
676
|
-
signal.throwIfAborted();
|
|
677
|
-
this.reconcileProjections({ prunedToolResults: result.prunedToolResults });
|
|
678
|
-
const snapshot = await this.commitSnapshot();
|
|
679
|
-
this.emitSnapshotReset("maintenance", snapshot);
|
|
680
|
-
return {
|
|
681
|
-
snapshot,
|
|
682
|
-
message: result.message,
|
|
683
|
-
noop: result.noop,
|
|
684
|
-
bashResultsPruned: result.bashResultsPruned,
|
|
685
|
-
editCallsPruned: result.editCallsPruned,
|
|
686
|
-
editResultsPruned: result.editResultsPruned,
|
|
687
|
-
bytesPruned: result.bytesPruned,
|
|
688
|
-
};
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
706
|
async runMaintenance(operation) {
|
|
692
707
|
this.assertActive();
|
|
693
708
|
return await this.runActiveWork(operation);
|
|
@@ -729,22 +744,18 @@ class LocalHostedSessionHandle {
|
|
|
729
744
|
}
|
|
730
745
|
async rewindToHistoryEntryId(historyEntryId) {
|
|
731
746
|
this.assertActive();
|
|
732
|
-
const result = this.session.rewindToHistoryEntryId(historyEntryId);
|
|
747
|
+
const result = await this.session.rewindToHistoryEntryId(historyEntryId);
|
|
733
748
|
if (!result) {
|
|
734
749
|
throw new Error("rewind failed");
|
|
735
750
|
}
|
|
736
|
-
await this.runtimeEventQueue;
|
|
737
|
-
this.reconcileProjections({ removeMissingAgents: true });
|
|
738
|
-
const snapshot = await this.commitSnapshot();
|
|
739
|
-
this.emitSnapshotReset("maintenance", snapshot);
|
|
740
751
|
return {
|
|
741
|
-
snapshot,
|
|
752
|
+
snapshot: await this.snapshot(),
|
|
742
753
|
...result,
|
|
743
754
|
};
|
|
744
755
|
}
|
|
745
|
-
async
|
|
756
|
+
async interruptSubagent(subagentId) {
|
|
746
757
|
this.assertActive();
|
|
747
|
-
return { found: await this.session.
|
|
758
|
+
return { found: await this.session.interruptSubagent(subagentId) };
|
|
748
759
|
}
|
|
749
760
|
async createEphemeralContext(options) {
|
|
750
761
|
this.assertActive();
|
|
@@ -753,12 +764,12 @@ class LocalHostedSessionHandle {
|
|
|
753
764
|
contextId,
|
|
754
765
|
persona: this.runtime.persona,
|
|
755
766
|
config: this.bootstrap.config ?? {},
|
|
756
|
-
modelResolver: this.bootstrap.modelResolver,
|
|
757
767
|
discoveredSkills: this.bootstrap.discoveredSkills,
|
|
758
768
|
includeAgentContext: this.includeAgentContext,
|
|
759
769
|
executionEnvironment: this.executionEnvironment,
|
|
760
770
|
instructions: options.instructions,
|
|
761
771
|
tools: options.tools,
|
|
772
|
+
recordUsage: this.recordUsage,
|
|
762
773
|
emitUpdate: (threadId, update) => {
|
|
763
774
|
this.emitEphemeral(createSessionProtocolEphemeralMessage({
|
|
764
775
|
sessionId: this.session.sessionId,
|
|
@@ -793,7 +804,28 @@ class LocalHostedSessionHandle {
|
|
|
793
804
|
}
|
|
794
805
|
async snapshot() {
|
|
795
806
|
this.assertActive();
|
|
796
|
-
return
|
|
807
|
+
return this.runtime.isTurnRunning && this.committedSnapshot
|
|
808
|
+
? await this.commitProjectedSnapshot()
|
|
809
|
+
: await this.commitSnapshot();
|
|
810
|
+
}
|
|
811
|
+
async persistRecoveredAgentState(recovery) {
|
|
812
|
+
this.assertActive();
|
|
813
|
+
for (const recovered of recovery.recoveredToolResults) {
|
|
814
|
+
const tool = this.tools.get(recovered.message.toolCallId);
|
|
815
|
+
if (!tool || tool.status === "streaming") {
|
|
816
|
+
continue;
|
|
817
|
+
}
|
|
818
|
+
this.tools.set(tool.id, tool.status === "queued" || tool.status === "running"
|
|
819
|
+
? {
|
|
820
|
+
...tool,
|
|
821
|
+
status: "cancelled",
|
|
822
|
+
finishedAt: recovered.message.timestamp,
|
|
823
|
+
resultMessageId: recovered.historyEntryId,
|
|
824
|
+
error: "Tool completion status is unknown after session recovery.",
|
|
825
|
+
}
|
|
826
|
+
: { ...tool, resultMessageId: recovered.historyEntryId });
|
|
827
|
+
}
|
|
828
|
+
await this.commitSnapshot();
|
|
797
829
|
}
|
|
798
830
|
async dispose() {
|
|
799
831
|
if (!this.disposePromise) {
|
|
@@ -815,12 +847,6 @@ class LocalHostedSessionHandle {
|
|
|
815
847
|
errors.push(error);
|
|
816
848
|
}
|
|
817
849
|
this.disposed = true;
|
|
818
|
-
try {
|
|
819
|
-
this.unsubscribeSubagentEvent();
|
|
820
|
-
}
|
|
821
|
-
catch (error) {
|
|
822
|
-
errors.push(error);
|
|
823
|
-
}
|
|
824
850
|
for (const session of this.ephemeralAgentSessions.values()) {
|
|
825
851
|
try {
|
|
826
852
|
session.dispose();
|
|
@@ -854,10 +880,17 @@ class LocalHostedSessionHandle {
|
|
|
854
880
|
this.snapshotQueue = write.catch(() => undefined);
|
|
855
881
|
return await write;
|
|
856
882
|
}
|
|
857
|
-
async
|
|
883
|
+
async commitProjectedSnapshot() {
|
|
858
884
|
const write = this.snapshotQueue
|
|
859
885
|
.catch(() => undefined)
|
|
860
|
-
.then(() => this.
|
|
886
|
+
.then(() => this.writeProjectedSnapshot());
|
|
887
|
+
this.snapshotQueue = write.catch(() => undefined);
|
|
888
|
+
return await write;
|
|
889
|
+
}
|
|
890
|
+
async commitSnapshotPatch(reason, changes) {
|
|
891
|
+
const write = this.snapshotQueue
|
|
892
|
+
.catch(() => undefined)
|
|
893
|
+
.then(() => this.writeSnapshotPatch(reason, changes));
|
|
861
894
|
this.snapshotQueue = write.catch(() => undefined);
|
|
862
895
|
return await write;
|
|
863
896
|
}
|
|
@@ -882,23 +915,47 @@ class LocalHostedSessionHandle {
|
|
|
882
915
|
}
|
|
883
916
|
return cloneSessionProtocolSnapshot(this.updateCommittedSnapshotAfterWrite(snapshot));
|
|
884
917
|
}
|
|
885
|
-
async
|
|
918
|
+
async writeProjectedSnapshot() {
|
|
886
919
|
this.assertNotDisposed();
|
|
887
920
|
const generation = this.snapshotGeneration;
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
921
|
+
const current = this.committedSnapshot;
|
|
922
|
+
if (!current) {
|
|
923
|
+
return await this.writeSnapshot();
|
|
924
|
+
}
|
|
925
|
+
const snapshot = cloneSessionProtocolSnapshot(current);
|
|
926
|
+
if (this.persistedSnapshot && isDeepStrictEqual(this.persistedSnapshot, snapshot)) {
|
|
927
|
+
return snapshot;
|
|
928
|
+
}
|
|
894
929
|
await this.store.commitSessionSnapshot(snapshot, {
|
|
895
930
|
expectedRevision: this.persistedSnapshot?.revision ?? 0,
|
|
896
931
|
});
|
|
897
932
|
this.persistedSnapshot = cloneSessionProtocolSnapshot(snapshot);
|
|
898
933
|
if (generation !== this.snapshotGeneration) {
|
|
899
|
-
return await this.
|
|
934
|
+
return await this.writeProjectedSnapshot();
|
|
900
935
|
}
|
|
901
|
-
return cloneSessionProtocolSnapshot(this.
|
|
936
|
+
return cloneSessionProtocolSnapshot(this.committedSnapshot ?? snapshot);
|
|
937
|
+
}
|
|
938
|
+
async writeSnapshotPatch(reason, changes) {
|
|
939
|
+
this.assertNotDisposed();
|
|
940
|
+
const current = this.committedSnapshot;
|
|
941
|
+
if (!current) {
|
|
942
|
+
throw new Error("cannot persist a session patch without a committed snapshot");
|
|
943
|
+
}
|
|
944
|
+
const delta = createSessionProtocolDeltaMessage({
|
|
945
|
+
sessionId: current.sessionId,
|
|
946
|
+
fromRevision: current.revision,
|
|
947
|
+
toRevision: current.revision + 1,
|
|
948
|
+
reason,
|
|
949
|
+
delta: { type: "snapshot.patch", changes },
|
|
950
|
+
});
|
|
951
|
+
const snapshot = applySessionProtocolDelta(current, delta);
|
|
952
|
+
await this.store.commitSessionSnapshot(snapshot, {
|
|
953
|
+
expectedRevision: this.persistedSnapshot?.revision ?? 0,
|
|
954
|
+
});
|
|
955
|
+
this.persistedSnapshot = cloneSessionProtocolSnapshot(snapshot);
|
|
956
|
+
this.committedSnapshot = cloneSessionProtocolSnapshot(snapshot);
|
|
957
|
+
this.snapshotGeneration += 1;
|
|
958
|
+
return delta;
|
|
902
959
|
}
|
|
903
960
|
async switchSnapshotSession(sessionId) {
|
|
904
961
|
if (this.committedSessionId === sessionId) {
|
|
@@ -944,7 +1001,6 @@ class LocalHostedSessionHandle {
|
|
|
944
1001
|
}
|
|
945
1002
|
}
|
|
946
1003
|
const operationIds = new Set(this.timelineExtras.filter((item) => item.type === "operation").map((item) => item.id));
|
|
947
|
-
const prunedByToolId = new Map((options.prunedToolResults ?? []).map((result) => [result.toolCallId, result.content]));
|
|
948
1004
|
for (const [id, facet] of this.facets) {
|
|
949
1005
|
const subjectExists = facet.subject.type === "session" ||
|
|
950
1006
|
(facet.subject.type === "message" && messageIds.has(facet.subject.id)) ||
|
|
@@ -953,26 +1009,21 @@ class LocalHostedSessionHandle {
|
|
|
953
1009
|
(facet.subject.type === "operation" && operationIds.has(facet.subject.id));
|
|
954
1010
|
if (!subjectExists) {
|
|
955
1011
|
this.facets.delete(id);
|
|
956
|
-
continue;
|
|
957
|
-
}
|
|
958
|
-
if (facet.subject.type === "tool") {
|
|
959
|
-
const toolCallId = facet.subject.id;
|
|
960
|
-
const content = prunedByToolId.get(toolCallId);
|
|
961
|
-
if (content !== undefined && facet.kind === "tau.tool-ui-events") {
|
|
962
|
-
this.facets.set(id, {
|
|
963
|
-
...facet,
|
|
964
|
-
data: {
|
|
965
|
-
events: [{ type: "tool_pruned", toolCallId, content }],
|
|
966
|
-
},
|
|
967
|
-
});
|
|
968
|
-
}
|
|
969
1012
|
}
|
|
970
1013
|
}
|
|
971
1014
|
}
|
|
972
1015
|
buildSnapshotDraft() {
|
|
973
1016
|
const messages = this.buildProtocolMessages();
|
|
1017
|
+
const agentState = this.session.snapshot();
|
|
974
1018
|
return {
|
|
975
1019
|
sessionId: this.session.sessionId,
|
|
1020
|
+
agentState: {
|
|
1021
|
+
revision: agentState.revision,
|
|
1022
|
+
contextEpoch: agentState.contextEpoch,
|
|
1023
|
+
...(agentState.usageCheckpoint
|
|
1024
|
+
? { usageCheckpoint: { ...agentState.usageCheckpoint } }
|
|
1025
|
+
: {}),
|
|
1026
|
+
},
|
|
976
1027
|
lifecycle: this.runtime.isTurnRunning ? "running" : "idle",
|
|
977
1028
|
costTotal: this.costTotal,
|
|
978
1029
|
settings: {
|
|
@@ -1113,7 +1164,14 @@ class LocalHostedSessionHandle {
|
|
|
1113
1164
|
const { revision, ...current } = this.committedSnapshot;
|
|
1114
1165
|
return JSON.stringify(current) === JSON.stringify(next) ? revision : revision + 1;
|
|
1115
1166
|
}
|
|
1116
|
-
|
|
1167
|
+
async recordSubagentEvent(event) {
|
|
1168
|
+
const write = this.runtimeEventQueue
|
|
1169
|
+
.catch(() => undefined)
|
|
1170
|
+
.then(() => this.recordSubagentUiEvent(event));
|
|
1171
|
+
this.runtimeEventQueue = write.catch(() => undefined);
|
|
1172
|
+
return await write;
|
|
1173
|
+
}
|
|
1174
|
+
async enqueueRuntimeEvent(event) {
|
|
1117
1175
|
const write = this.runtimeEventQueue
|
|
1118
1176
|
.catch(() => undefined)
|
|
1119
1177
|
.then(() => this.recordRuntimeEvent(event));
|
|
@@ -1128,6 +1186,17 @@ class LocalHostedSessionHandle {
|
|
|
1128
1186
|
}
|
|
1129
1187
|
changes.push({ type: "tool.remove", id: tool.id });
|
|
1130
1188
|
}
|
|
1189
|
+
agentStateChange() {
|
|
1190
|
+
const state = this.session.snapshot();
|
|
1191
|
+
return {
|
|
1192
|
+
type: "agent-state.set",
|
|
1193
|
+
agentState: {
|
|
1194
|
+
revision: state.revision,
|
|
1195
|
+
contextEpoch: state.contextEpoch,
|
|
1196
|
+
...(state.usageCheckpoint ? { usageCheckpoint: { ...state.usageCheckpoint } } : {}),
|
|
1197
|
+
},
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1131
1200
|
async recordRuntimeEvent(event) {
|
|
1132
1201
|
switch (event.type) {
|
|
1133
1202
|
case "assistant_start": {
|
|
@@ -1241,44 +1310,116 @@ class LocalHostedSessionHandle {
|
|
|
1241
1310
|
});
|
|
1242
1311
|
return;
|
|
1243
1312
|
}
|
|
1313
|
+
case "user_message":
|
|
1314
|
+
await this.emitPatch("user-message", [
|
|
1315
|
+
this.agentStateChange(),
|
|
1316
|
+
{
|
|
1317
|
+
type: "message.append",
|
|
1318
|
+
message: {
|
|
1319
|
+
id: event.historyEntryId,
|
|
1320
|
+
state: "committed",
|
|
1321
|
+
modelVisible: true,
|
|
1322
|
+
message: event.message,
|
|
1323
|
+
},
|
|
1324
|
+
timelineItem: timelineItemForMessage(event.historyEntryId),
|
|
1325
|
+
},
|
|
1326
|
+
], { persist: true });
|
|
1327
|
+
return;
|
|
1328
|
+
case "history_rewound":
|
|
1329
|
+
this.reconcileProjections({ removeMissingAgents: true });
|
|
1330
|
+
await this.emitSnapshotResetIfChanged("maintenance");
|
|
1331
|
+
return;
|
|
1244
1332
|
case "assistant_final": {
|
|
1245
1333
|
this.draftAssistantMessage = undefined;
|
|
1246
|
-
|
|
1334
|
+
const messageState = event.message.stopReason === "aborted" ? "interrupted" : "committed";
|
|
1335
|
+
if (messageState === "committed") {
|
|
1336
|
+
this.messageStates.delete(event.historyEntryId);
|
|
1337
|
+
}
|
|
1338
|
+
else {
|
|
1339
|
+
this.messageStates.set(event.historyEntryId, messageState);
|
|
1340
|
+
}
|
|
1341
|
+
const lifecycle = this.runtime.isTurnRunning
|
|
1342
|
+
? "running"
|
|
1343
|
+
: "idle";
|
|
1247
1344
|
const toolChanges = this.syncToolRunsFromAssistantMessage(event.historyEntryId, event.message);
|
|
1248
|
-
|
|
1345
|
+
const usage = getUsageTotals(event.message.usage);
|
|
1346
|
+
const cost = getUsageCostTotal(event.message.usage);
|
|
1347
|
+
this.costTotal += cost;
|
|
1348
|
+
this.recordUsage({
|
|
1349
|
+
timestamp: event.message.timestamp,
|
|
1350
|
+
sessionId: this.sessionId,
|
|
1351
|
+
personaId: event.personaId,
|
|
1352
|
+
provider: event.message.provider,
|
|
1353
|
+
model: event.message.model,
|
|
1354
|
+
api: event.message.api,
|
|
1355
|
+
reasoningEffort: event.reasoningEffort,
|
|
1356
|
+
usage,
|
|
1357
|
+
cost: { total: cost },
|
|
1358
|
+
agent: { type: "main" },
|
|
1359
|
+
});
|
|
1249
1360
|
await this.emitPatch("assistant-message", [
|
|
1361
|
+
this.agentStateChange(),
|
|
1250
1362
|
{ type: "cost.set", costTotal: this.costTotal },
|
|
1251
1363
|
{
|
|
1252
1364
|
type: "message.replace",
|
|
1253
1365
|
message: {
|
|
1254
1366
|
id: event.historyEntryId,
|
|
1255
|
-
state:
|
|
1367
|
+
state: messageState,
|
|
1256
1368
|
modelVisible: true,
|
|
1257
1369
|
message: event.message,
|
|
1258
1370
|
},
|
|
1259
1371
|
},
|
|
1372
|
+
...(this.committedSnapshot?.lifecycle !== lifecycle
|
|
1373
|
+
? [{ type: "lifecycle.set", lifecycle }]
|
|
1374
|
+
: []),
|
|
1260
1375
|
...toolChanges,
|
|
1261
1376
|
]);
|
|
1262
1377
|
return;
|
|
1263
1378
|
}
|
|
1379
|
+
case "tool_run_queued":
|
|
1380
|
+
case "tool_run_blocked":
|
|
1381
|
+
case "tool_run_started":
|
|
1382
|
+
case "tool_run_finished": {
|
|
1383
|
+
const existing = this.tools.get(event.toolCallId);
|
|
1384
|
+
if (!existing || existing.status === "streaming") {
|
|
1385
|
+
throw new Error(`missing completed protocol tool run for '${event.toolCallId}'`);
|
|
1386
|
+
}
|
|
1387
|
+
const nextTool = {
|
|
1388
|
+
...existing,
|
|
1389
|
+
status: event.type === "tool_run_queued"
|
|
1390
|
+
? "queued"
|
|
1391
|
+
: event.type === "tool_run_blocked"
|
|
1392
|
+
? "blocked"
|
|
1393
|
+
: event.type === "tool_run_started"
|
|
1394
|
+
? "running"
|
|
1395
|
+
: event.outcome,
|
|
1396
|
+
...(event.type === "tool_run_started" || event.type === "tool_run_finished"
|
|
1397
|
+
? { startedAt: existing.startedAt ?? event.timestamp }
|
|
1398
|
+
: {}),
|
|
1399
|
+
...(event.type === "tool_run_blocked" || event.type === "tool_run_finished"
|
|
1400
|
+
? { finishedAt: event.timestamp }
|
|
1401
|
+
: {}),
|
|
1402
|
+
};
|
|
1403
|
+
this.tools.set(nextTool.id, nextTool);
|
|
1404
|
+
await this.emitPatch("tool-run", [{ type: "tool.set", tool: structuredClone(nextTool) }]);
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1264
1407
|
case "tool_result": {
|
|
1265
1408
|
const existing = this.tools.get(event.message.toolCallId);
|
|
1266
1409
|
if (existing?.status === "streaming") {
|
|
1267
1410
|
throw new Error(`tool result arrived before '${event.message.toolCallId}' completed`);
|
|
1268
1411
|
}
|
|
1269
1412
|
if (existing) {
|
|
1413
|
+
if (existing.status === "queued" || existing.status === "running") {
|
|
1414
|
+
throw new Error(`tool result arrived before '${event.message.toolCallId}' finished`);
|
|
1415
|
+
}
|
|
1270
1416
|
const nextTool = {
|
|
1271
1417
|
...existing,
|
|
1272
|
-
status: existing.status === "blocked"
|
|
1273
|
-
? "blocked"
|
|
1274
|
-
: event.message.isError
|
|
1275
|
-
? "failed"
|
|
1276
|
-
: "succeeded",
|
|
1277
|
-
finishedAt: event.message.timestamp,
|
|
1278
1418
|
resultMessageId: event.historyEntryId,
|
|
1279
1419
|
};
|
|
1280
1420
|
this.tools.set(nextTool.id, nextTool);
|
|
1281
1421
|
await this.emitPatch("tool-result", [
|
|
1422
|
+
this.agentStateChange(),
|
|
1282
1423
|
{
|
|
1283
1424
|
type: "message.append",
|
|
1284
1425
|
message: {
|
|
@@ -1294,6 +1435,7 @@ class LocalHostedSessionHandle {
|
|
|
1294
1435
|
return;
|
|
1295
1436
|
}
|
|
1296
1437
|
await this.emitPatch("tool-result", [
|
|
1438
|
+
this.agentStateChange(),
|
|
1297
1439
|
{
|
|
1298
1440
|
type: "message.append",
|
|
1299
1441
|
message: {
|
|
@@ -1309,6 +1451,7 @@ class LocalHostedSessionHandle {
|
|
|
1309
1451
|
}
|
|
1310
1452
|
case "tool_recovery": {
|
|
1311
1453
|
const changes = [
|
|
1454
|
+
this.agentStateChange(),
|
|
1312
1455
|
{
|
|
1313
1456
|
type: "message.append",
|
|
1314
1457
|
message: {
|
|
@@ -1324,14 +1467,11 @@ class LocalHostedSessionHandle {
|
|
|
1324
1467
|
if (!existing || existing.status === "streaming") {
|
|
1325
1468
|
throw new Error(`missing completed protocol tool run for '${toolResult.toolCallId}'`);
|
|
1326
1469
|
}
|
|
1470
|
+
if (existing.status === "queued" || existing.status === "running") {
|
|
1471
|
+
throw new Error(`tool recovery arrived before '${toolResult.toolCallId}' finished`);
|
|
1472
|
+
}
|
|
1327
1473
|
const nextTool = {
|
|
1328
1474
|
...existing,
|
|
1329
|
-
status: existing.status === "blocked"
|
|
1330
|
-
? "blocked"
|
|
1331
|
-
: toolResult.isError
|
|
1332
|
-
? "failed"
|
|
1333
|
-
: "succeeded",
|
|
1334
|
-
finishedAt: toolResult.timestamp,
|
|
1335
1475
|
};
|
|
1336
1476
|
this.tools.set(nextTool.id, nextTool);
|
|
1337
1477
|
changes.push({ type: "tool.set", tool: structuredClone(nextTool) });
|
|
@@ -1374,11 +1514,15 @@ class LocalHostedSessionHandle {
|
|
|
1374
1514
|
this.reconcileProjections();
|
|
1375
1515
|
await this.emitSnapshotReset("maintenance", await this.commitSnapshot());
|
|
1376
1516
|
return;
|
|
1377
|
-
case "
|
|
1378
|
-
await this.recordToolUiEvent(event.
|
|
1517
|
+
case "tool_activity":
|
|
1518
|
+
await this.recordToolUiEvent(event.activity);
|
|
1379
1519
|
return;
|
|
1380
|
-
case "
|
|
1381
|
-
|
|
1520
|
+
case "turn_started":
|
|
1521
|
+
case "turn_finished":
|
|
1522
|
+
case "tool_call_admitted":
|
|
1523
|
+
case "model_retry_scheduled":
|
|
1524
|
+
case "model_retry_started":
|
|
1525
|
+
case "usage_checkpoint":
|
|
1382
1526
|
return;
|
|
1383
1527
|
}
|
|
1384
1528
|
}
|
|
@@ -1399,47 +1543,20 @@ class LocalHostedSessionHandle {
|
|
|
1399
1543
|
data: { events: [...events, structuredClone(event)] },
|
|
1400
1544
|
};
|
|
1401
1545
|
this.facets.set(facet.id, facet);
|
|
1402
|
-
const tool =
|
|
1546
|
+
const tool = {
|
|
1547
|
+
...existingTool,
|
|
1548
|
+
facetIds: existingTool.facetIds.includes(facetId)
|
|
1549
|
+
? existingTool.facetIds
|
|
1550
|
+
: [...existingTool.facetIds, facetId],
|
|
1551
|
+
};
|
|
1403
1552
|
this.tools.set(tool.id, tool);
|
|
1404
1553
|
await this.emitPatch("tool-run", [
|
|
1405
1554
|
{ type: "tool.set", tool },
|
|
1406
1555
|
{ type: "facet.set", facet: structuredClone(facet) },
|
|
1407
|
-
]);
|
|
1408
|
-
}
|
|
1409
|
-
updateToolRunFromUiEvent(tool, event) {
|
|
1410
|
-
if (tool.status === "streaming") {
|
|
1411
|
-
throw new Error(`tool UI event '${event.type}' arrived before tool call completion`);
|
|
1412
|
-
}
|
|
1413
|
-
const next = {
|
|
1414
|
-
...tool,
|
|
1415
|
-
facetIds: tool.facetIds.includes(`tool-ui-${tool.toolCallId}`)
|
|
1416
|
-
? tool.facetIds
|
|
1417
|
-
: [...tool.facetIds, `tool-ui-${tool.toolCallId}`],
|
|
1418
|
-
};
|
|
1419
|
-
if (event.type.endsWith("_started") || event.type === "tool_call_queued") {
|
|
1420
|
-
next.status = event.type === "tool_call_queued" ? "queued" : "running";
|
|
1421
|
-
next.startedAt ??= Date.now();
|
|
1422
|
-
}
|
|
1423
|
-
else if (event.type.endsWith("_blocked")) {
|
|
1424
|
-
next.status = "blocked";
|
|
1425
|
-
next.finishedAt = Date.now();
|
|
1426
|
-
}
|
|
1427
|
-
else if (event.type.endsWith("_finished")) {
|
|
1428
|
-
next.status = "status" in event && event.status === "error" ? "failed" : "succeeded";
|
|
1429
|
-
next.finishedAt = Date.now();
|
|
1430
|
-
}
|
|
1431
|
-
else if (event.type === "bash_aborted") {
|
|
1432
|
-
next.status = "cancelled";
|
|
1433
|
-
next.finishedAt = Date.now();
|
|
1434
|
-
}
|
|
1435
|
-
return next;
|
|
1556
|
+
], { persist: false });
|
|
1436
1557
|
}
|
|
1437
1558
|
async recordSubagentUiEvent(event) {
|
|
1438
|
-
const
|
|
1439
|
-
const agent = agentRunFromSubagentEvent(event, existing);
|
|
1440
|
-
if (!agent) {
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1559
|
+
const agent = agentRunFromSubagentEvent(event);
|
|
1443
1560
|
const previousCost = this.agentCostTotals.get(agent.id) ?? 0;
|
|
1444
1561
|
this.costTotal += Math.max(0, agent.costTotal - previousCost);
|
|
1445
1562
|
this.agentCostTotals.set(agent.id, agent.costTotal);
|
|
@@ -1447,10 +1564,27 @@ class LocalHostedSessionHandle {
|
|
|
1447
1564
|
return;
|
|
1448
1565
|
}
|
|
1449
1566
|
this.agents.set(agent.id, agent);
|
|
1450
|
-
|
|
1567
|
+
const changes = [
|
|
1451
1568
|
{ type: "cost.set", costTotal: this.costTotal },
|
|
1452
1569
|
{ type: "agent.set", agent: structuredClone(agent) },
|
|
1453
|
-
]
|
|
1570
|
+
];
|
|
1571
|
+
const facetId = `subagent-activity-${agent.id}`;
|
|
1572
|
+
if (event.type === "subagent_activity") {
|
|
1573
|
+
const facet = {
|
|
1574
|
+
id: facetId,
|
|
1575
|
+
subject: { type: "agent", id: agent.id },
|
|
1576
|
+
kind: SUBAGENT_ACTIVITY_FACET_KIND,
|
|
1577
|
+
version: 1,
|
|
1578
|
+
data: { text: event.text },
|
|
1579
|
+
};
|
|
1580
|
+
this.facets.set(facet.id, facet);
|
|
1581
|
+
changes.push({ type: "facet.set", facet: structuredClone(facet) });
|
|
1582
|
+
}
|
|
1583
|
+
else if ((event.type === "subagent_run_started" || event.type === "subagent_finished") &&
|
|
1584
|
+
this.facets.delete(facetId)) {
|
|
1585
|
+
changes.push({ type: "facet.remove", id: facetId });
|
|
1586
|
+
}
|
|
1587
|
+
await this.emitPatch("agent-run", changes, event.type === "subagent_activity" ? { persist: false } : {});
|
|
1454
1588
|
}
|
|
1455
1589
|
buildAssistantPartialChanges(previousDraft, nextDraft) {
|
|
1456
1590
|
if (!previousDraft) {
|
|
@@ -1476,33 +1610,31 @@ class LocalHostedSessionHandle {
|
|
|
1476
1610
|
return;
|
|
1477
1611
|
}
|
|
1478
1612
|
if (!this.committedSnapshot) {
|
|
1613
|
+
if (options.persist === false) {
|
|
1614
|
+
const snapshot = { ...this.buildSnapshotDraft(), revision: 1 };
|
|
1615
|
+
this.committedSnapshot = snapshot;
|
|
1616
|
+
this.snapshotGeneration += 1;
|
|
1617
|
+
this.emitSnapshotReset(reason, snapshot);
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1479
1620
|
const snapshot = await this.commitSnapshot();
|
|
1480
1621
|
this.emitSnapshotReset(reason, snapshot);
|
|
1481
1622
|
return;
|
|
1482
1623
|
}
|
|
1483
|
-
|
|
1484
|
-
|
|
1624
|
+
if (options.persist !== false) {
|
|
1625
|
+
this.emitDelta(await this.commitSnapshotPatch(reason, changes));
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1485
1628
|
const delta = createSessionProtocolDeltaMessage({
|
|
1486
1629
|
sessionId: this.committedSnapshot.sessionId,
|
|
1487
|
-
fromRevision,
|
|
1488
|
-
toRevision,
|
|
1630
|
+
fromRevision: this.committedSnapshot.revision,
|
|
1631
|
+
toRevision: this.committedSnapshot.revision + 1,
|
|
1489
1632
|
reason,
|
|
1490
1633
|
delta: { type: "snapshot.patch", changes },
|
|
1491
1634
|
});
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
this.emitDelta(delta);
|
|
1496
|
-
return;
|
|
1497
|
-
}
|
|
1498
|
-
const snapshot = await this.commitSnapshotWithRevision(toRevision);
|
|
1499
|
-
this.emitDelta(createSessionProtocolDeltaMessage({
|
|
1500
|
-
sessionId: delta.sessionId,
|
|
1501
|
-
fromRevision,
|
|
1502
|
-
toRevision: snapshot.revision,
|
|
1503
|
-
reason,
|
|
1504
|
-
delta: { type: "snapshot.patch", changes },
|
|
1505
|
-
}));
|
|
1635
|
+
this.committedSnapshot = applySessionProtocolDelta(this.committedSnapshot, delta);
|
|
1636
|
+
this.snapshotGeneration += 1;
|
|
1637
|
+
this.emitDelta(delta);
|
|
1506
1638
|
}
|
|
1507
1639
|
emitSnapshotReset(reason, snapshot) {
|
|
1508
1640
|
this.emitDelta(createSessionProtocolDeltaMessage({
|
|
@@ -1576,27 +1708,7 @@ class LocalHostedSessionHandle {
|
|
|
1576
1708
|
return;
|
|
1577
1709
|
}
|
|
1578
1710
|
const interruptedMessage = createInterruptedAssistantMessage(draft, this.runtime.persona.model);
|
|
1579
|
-
this.session.
|
|
1580
|
-
this.messageStates.set(draft.id, "interrupted");
|
|
1581
|
-
this.draftAssistantMessage = undefined;
|
|
1582
|
-
const changes = [
|
|
1583
|
-
{
|
|
1584
|
-
type: "message.replace",
|
|
1585
|
-
message: {
|
|
1586
|
-
id: draft.id,
|
|
1587
|
-
state: "interrupted",
|
|
1588
|
-
modelVisible: true,
|
|
1589
|
-
message: interruptedMessage,
|
|
1590
|
-
},
|
|
1591
|
-
},
|
|
1592
|
-
{ type: "lifecycle.set", lifecycle: "idle" },
|
|
1593
|
-
];
|
|
1594
|
-
for (const tool of this.tools.values()) {
|
|
1595
|
-
if (tool.status === "streaming" && tool.origin.messageId === draft.id) {
|
|
1596
|
-
this.removeToolRun(tool, changes);
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
await this.emitPatch("assistant-stream", changes);
|
|
1711
|
+
await this.session.commitInterruptedAssistant(interruptedMessage, draft.id);
|
|
1600
1712
|
}
|
|
1601
1713
|
async cleanupFailedTurn() {
|
|
1602
1714
|
if (this.draftAssistantMessage) {
|
|
@@ -1610,6 +1722,9 @@ function turnOutcomeFromResult(result, assistantMessage) {
|
|
|
1610
1722
|
if (result.blocked) {
|
|
1611
1723
|
return { status: "blocked", ...result.blocked };
|
|
1612
1724
|
}
|
|
1725
|
+
if (result.limitReached) {
|
|
1726
|
+
return { status: "failed", stopReason: "error", errorMessage: result.limitReached.message };
|
|
1727
|
+
}
|
|
1613
1728
|
if (result.aborted || assistantMessage?.stopReason === "aborted") {
|
|
1614
1729
|
return { status: "aborted", stopReason: "aborted" };
|
|
1615
1730
|
}
|
|
@@ -1688,8 +1803,14 @@ function getAssistantDraftBlockText(message, type) {
|
|
|
1688
1803
|
}
|
|
1689
1804
|
function normalizeRecoveredSnapshot(snapshot) {
|
|
1690
1805
|
const recovered = cloneSessionProtocolSnapshot(snapshot);
|
|
1691
|
-
|
|
1806
|
+
const legacyAgentState = recovered.agentState.contextEpoch === LEGACY_SESSION_CONTEXT_EPOCH;
|
|
1807
|
+
let changed = recovered.lifecycle !== "idle" || legacyAgentState;
|
|
1692
1808
|
recovered.lifecycle = "idle";
|
|
1809
|
+
if (Object.keys(recovered.agents).length > 0) {
|
|
1810
|
+
changed = true;
|
|
1811
|
+
recovered.agents = {};
|
|
1812
|
+
recovered.facets = Object.fromEntries(Object.entries(recovered.facets).filter(([, facet]) => facet.subject.type !== "agent"));
|
|
1813
|
+
}
|
|
1693
1814
|
const streamingToolIds = new Set(Object.values(recovered.tools)
|
|
1694
1815
|
.filter((tool) => tool.status === "streaming")
|
|
1695
1816
|
.map((tool) => tool.id));
|
|
@@ -1698,11 +1819,13 @@ function normalizeRecoveredSnapshot(snapshot) {
|
|
|
1698
1819
|
recovered.tools = Object.fromEntries(Object.entries(recovered.tools).filter(([id]) => !streamingToolIds.has(id)));
|
|
1699
1820
|
recovered.facets = Object.fromEntries(Object.entries(recovered.facets).filter(([, facet]) => facet.subject.type !== "tool" || !streamingToolIds.has(facet.subject.id)));
|
|
1700
1821
|
}
|
|
1822
|
+
let recoveredAgentHistory = false;
|
|
1701
1823
|
recovered.messages = recovered.messages.map((message) => {
|
|
1702
1824
|
if (message.state !== "draft" || message.message.role !== "assistant") {
|
|
1703
1825
|
return message;
|
|
1704
1826
|
}
|
|
1705
1827
|
changed = true;
|
|
1828
|
+
recoveredAgentHistory = true;
|
|
1706
1829
|
return {
|
|
1707
1830
|
id: message.id,
|
|
1708
1831
|
state: "interrupted",
|
|
@@ -1710,7 +1833,16 @@ function normalizeRecoveredSnapshot(snapshot) {
|
|
|
1710
1833
|
message: createInterruptedAssistantMessageFromModelSnapshot(message, recovered.bootstrap.model),
|
|
1711
1834
|
};
|
|
1712
1835
|
});
|
|
1713
|
-
|
|
1836
|
+
if (recoveredAgentHistory) {
|
|
1837
|
+
recovered.agentState = {
|
|
1838
|
+
revision: recovered.agentState.revision + 1,
|
|
1839
|
+
contextEpoch: recovered.agentState.contextEpoch,
|
|
1840
|
+
...(recovered.agentState.usageCheckpoint
|
|
1841
|
+
? { usageCheckpoint: { ...recovered.agentState.usageCheckpoint } }
|
|
1842
|
+
: {}),
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
return { snapshot: recovered, changed, legacyAgentState };
|
|
1714
1846
|
}
|
|
1715
1847
|
function promptCompositionFromSnapshot(snapshot) {
|
|
1716
1848
|
const systemMessage = snapshot.messages[0];
|
|
@@ -1798,48 +1930,8 @@ function createInterruptedAssistantMessageFromModelSnapshot(draft, model) {
|
|
|
1798
1930
|
timestamp: draft.message.timestamp,
|
|
1799
1931
|
};
|
|
1800
1932
|
}
|
|
1801
|
-
function agentRunFromSubagentEvent(event
|
|
1802
|
-
|
|
1803
|
-
? event.state
|
|
1804
|
-
: undefined;
|
|
1805
|
-
if (event.type === "subagent_progress" && existing) {
|
|
1806
|
-
return {
|
|
1807
|
-
...existing,
|
|
1808
|
-
costTotal: event.costTotal,
|
|
1809
|
-
turns: event.turns,
|
|
1810
|
-
toolCalls: event.toolCalls,
|
|
1811
|
-
usage: { ...event.usage },
|
|
1812
|
-
progress: event.text,
|
|
1813
|
-
};
|
|
1814
|
-
}
|
|
1815
|
-
if (event.type === "subagent_abort_requested" && existing) {
|
|
1816
|
-
return { ...existing, abortRequested: true };
|
|
1817
|
-
}
|
|
1818
|
-
if (!state) {
|
|
1819
|
-
return undefined;
|
|
1820
|
-
}
|
|
1821
|
-
return {
|
|
1822
|
-
id: state.id,
|
|
1823
|
-
name: state.name,
|
|
1824
|
-
title: state.title,
|
|
1825
|
-
status: state.status === "success"
|
|
1826
|
-
? "succeeded"
|
|
1827
|
-
: state.status === "error"
|
|
1828
|
-
? "failed"
|
|
1829
|
-
: state.status === "aborted"
|
|
1830
|
-
? "cancelled"
|
|
1831
|
-
: "running",
|
|
1832
|
-
...(state.modelLabel !== undefined ? { modelLabel: state.modelLabel } : {}),
|
|
1833
|
-
costTotal: state.costTotal,
|
|
1834
|
-
turns: state.turns,
|
|
1835
|
-
toolCalls: state.toolCalls,
|
|
1836
|
-
usage: { ...state.usage },
|
|
1837
|
-
startedAt: state.startedAt,
|
|
1838
|
-
...(state.finishedAt !== undefined ? { finishedAt: state.finishedAt } : {}),
|
|
1839
|
-
abortRequested: state.abortRequested,
|
|
1840
|
-
...(state.finalText !== undefined ? { finalText: state.finalText } : {}),
|
|
1841
|
-
...(state.error !== undefined ? { error: state.error } : {}),
|
|
1842
|
-
};
|
|
1933
|
+
function agentRunFromSubagentEvent(event) {
|
|
1934
|
+
return structuredClone(event.state);
|
|
1843
1935
|
}
|
|
1844
1936
|
function cloneResolvedBootstrap(bootstrap) {
|
|
1845
1937
|
return {
|